Repository navigation
feat(machine): force-stop machines and native Sandboxes; keep parallel Store writes safe - #656
Conversation
…writes Port the verified force-stop and native concurrency changes onto current layerfs_v2_0_0. Stop providers without a live worker, retain saved data and runtime registration custody, and advertise machine.stop force. Restore macOS writer and Store lifecycle admission, and treat disappearing stale leases as already released. Preserve upstream Sandbox recovery slots, pool/capacity fixes and API retirements; omit obsolete image override handling. Ported-from: 7b5f5a56305f6aeb10fb8d96cf15d7ee71c6c316 Validation: PG CLI build and warning-denying all-targets Clippy; API dead-worker force; live mounted/running native machine and Sandbox force using a matching private daemon; upstream bridge admission/setup and pool/capacity tests. Before the unrelated upstream recovery-slot merge, the unchanged persistence, lease, provider and CLI scopes passed 20 native, one lease, 24 provider and seven CLI discovery/framing tests; boundary and 182 tooling tests also passed. The old test daemon's private-config refusal was diagnosed as upstream's LFSD08-to-LFSD09 startup protocol change; its matching-daemon rerun passed. No mutation retries were added. Production LOC: 158658 -> 159105 (delta +447) Scope: all first-party core, engine, control and API product sources including runtime SQL, Python and JavaScript; excludes tests, docs, tooling and generated artifacts. Method: tools/production_loc.py --root <git-archive snapshot> --json on parent dbd633f and staged tree 9b47c8d. Counter SHA256: d3148db88f91b09eb74eb659b2f700209776a24d022f09774dc7bb38ea1eecf6 Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Assisted-by: Cindy (https://cindy.app)
Bring the force-stop port (1b22005, ported from 7b5f5a5630) up to the current layerfs_v2_0_0 tip 03883a6: #649 carries a full-pool capacity notice into sandbox.get. Merged without conflicts; the tree is identical to the resolution staged in layerfs-force-stop-v2-push. Production LOC: 159105 -> 159152 (delta +47) Scope: first-parent comparison (1b22005 -> merge); all first-party core, engine, control and API product sources; tests, docs, tooling and generated artifacts excluded. Method: pinned tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on both snapshots. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A forced sandbox.close on native now stops the Sandbox from its own records: no Store open, daemon control call, active-Workspace refusal or retry. The backend Stop checks the runtime identity and ends its mounts and processes; Delete checks the physical detach before the runtime goes. Each recorded or held Workspace is answered as unknown. This is the remaining part of c1cf6fd169 that the 7b5f5a5630 port did not carry. The forced machine.stop on native shares the same host builder (layerfs_sandbox::force::native_host). Also unroll two single-element loops in the machine_force test, which warning-denying Clippy refused. Validation (registered private worktree, macOS): - warning-denying all-targets Clippy: layerfs-sandbox, -control, -api, -machine, -platform, -store (postgresql,machine); layerfs-cli (postgresql); layerfs-daemon. - layerfs-api machine_force and live machine_force_native with a matching private daemon (native machine.stop and sandbox.close force end the exact daemon, command and mount without opening the Store): passed. - layerfs-api sandbox_* and machine_* suites: 34 passed. Platform machine_force/machine_lima 17, sandbox-backend local_stop_mount 1, store lease_race 1, persistence writer_admission/sqlite_lock_custody 12, CLI capabilities/stream_framed 7, sandbox capacity_read/pool_admission 8, api sandbox_capacity 8: all passed. - The debug CLI's help --json advertises machine.stop and sandbox.close force. Production LOC: 159152 -> 159204 (delta +52) Scope: all first-party core, engine, control and API product sources; tests, docs, tooling and generated artifacts excluded. Method: pinned tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on the parent and the staged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings #656 up to the v2 tip (64 commits). Conflicts and how they were resolved: - writer_admission.rs, lane.rs: both sides enabled the macOS directory lane identically; took base (#647). - lease.rs: base #666 already treats a stale lease its holder dropped as released (remove_stale); took base. The PR's lease_race test still passes and is kept. - connection.rs: took base's open rule (#647): a writable open takes the lane and releases it after the profile check; a read-only open takes none. Kept the PR's ConnectionSlot and State.path so the last-close custody in session/lifecycle.rs still applies. - seal.rs: kept the PR's checked close through ConnectionSlot (a failed close restores the connection) and base's order: the lane is held through the sidecar check and released after it. - glossary.md: took base (already says Linux and macOS). - docs: #671 deleted api/sdk/machine/{README,stop}.md and engine/store/backends.md. Their PR content moved to api/sdk/machine.md (machine.stop force), api/sdk/sandbox.md (native forced close) and engine/store/sqlite.md (last-close lane row). Deleted test (it asserts the PR's read-only-open admission, which base's #647 rule does not have): writer_admission.rs another_process_admission_precedes_read_only_connection_open. The last-close admission test is kept and passes. Checks (macOS, toolchain 1.85.1, registered worktree via tools/worktree.py): - Clippy --all-targets -D warnings: layerfs-persistence; layerfs-api (machine, postgresql), -sandbox, -machine, -control, -platform, -store; layerfs-cli (postgresql), layerfs-daemon: clean. - Tests: persistence writer_admission 13, sqlite_lock_custody 2; store lease_race 1, lease_stale 1; platform machine_force 9, machine_lima 8; cli capabilities 4, stream_framed 3; api (machine, postgresql) machine_* and sandbox_* 30 across 17 suites, sandbox_capacity 8: all passed. - rustfmt clean on the resolved files. cargo fmt --check still flags api/crates/layerfs-cli/tests/concurrent_reads.rs, which comes from base unchanged. - Not run: machine_force_native (needs a matching private daemon), Linux and Docker E2E. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Production LOC: 159204 -> 161104 (delta +1900), first parent eda9c04 against the merged tree; core 39787 -> 39787, engine 74384 -> 74810, control 39465 -> 40527, api 5568 -> 5980. The delta is the base's 64 commits; against layerfs_v2_0_0 (160621) the PR now adds +483. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on both trees. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… refusals before a signal stay certain Fixes the two blocking findings of the independent review of #656 at 18b4df7. 1. A read-only or diagnostic SQLite session's close no longer takes the Store directory's writer lane. The last-close lane added for #656 made every session wait for it, so after one uncertain write (a quarantined writer keeps the lane) a daemon's reader close blocked forever under the reader-set mutex, and with it mount, unmount and session lookup; the diagnostic open and control's idle-Store reaper hung the same way. A read-only connection cannot checkpoint or remove -wal/-shm, so the lane bought no custody there. State now keeps the Store path only for writable sessions (close_lane); writable closes are unchanged. 2. A forced machine.stop on native records a Sandbox as uncertain only once its stop has been sent. Recorded::for_stop reopens the recorded runtime without signalling (identity and boot checks, missing runtime); a refusal there now clears the op instead of leaving an uncertain machine.stop on native, which the new machine gates turned into a home-wide lockout with no call to clear it. Partial progress no longer makes a native refusal uncertain either: each native Sandbox is recorded as it stops. Recorded::stop_now is for_stop followed by the stop, as before. Tests added: writer_admission read_only_close_does_not_wait_for_a_held_writer_lane; api machine_force native_force_stop_refused_before_any_signal_leaves_no_uncertain_op. Both fail on 18b4df7's product code and pass here. No test deleted. Docs: engine/store/sqlite.md (Last close row, including the existing checkpoint-thread start exception the review noted), api/sdk/machine.md (machine.stop force on native). Checks (toolchain 1.85.1, registered worktree via tools/worktree.py): - Clippy --all-targets -D warnings, macOS and Linux: layerfs-persistence, -sandbox, -control, -api (machine, postgresql), -store, -cli (postgresql), -daemon: clean. rustfmt clean on changed files. - macOS: persistence writer_admission 14, sqlite_lock_custody 2, idle_checkpoint 4; api machine_force 2, sandbox_records 2, sandbox_lost 1, sandbox_family 1; platform machine_force 9: passed. - Linux: persistence writer_admission 15, sqlite_lock_custody 2, idle_checkpoint 4; store lease_race 1, lease_stale 1; platform machine_force 9; api machine_force 2, sandbox_lost 1: passed. - Linux mount lane (tools/ci_tests.py mount-targets, 45 binaries from layerfs-daemon and layerfs-control, each in a fresh container with /dev/fuse, SYS_ADMIN, apparmor=unconfined and a fresh ext4 /tmp, each under timeout 120 with --test-threads=1): 45/45 passed, 116 tests passed, 3 ignored by their own attributes. - Not run: machine_force_native (needs a matching private daemon); Docker/Lima providers live. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Production LOC: 161104 -> 161117 (delta +13); core 39787 -> 39787, engine 74810 -> 74811, control 40527 -> 40539, api 5980 -> 5980. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on the parent and the staged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dy and continuation Fixes the non-blocking findings of the independent reviews of #656 at 18b4df7 and d4d9df9. Store (persistence): - A writable session's last close makes one non-blocking lane attempt. With the lane it closes as before (checkpoint, WAL/SHM removal under the lane). Without it (held elsewhere, or the attempt failed) it sets SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE and closes: SQLite then takes no exclusive lock, runs no checkpoint and unlinks nothing, so the close neither waits behind a writer kept after an uncertain write nor tears the WAL down unadmitted, and the connection is no longer leaked. Only if that setting fails is the connection kept until process exit. (Review findings A and 3.) Force stop (control): - native: a refusal before the signal no longer ends the stop; the other Sandboxes are still stopped, and the call answers the first refusal with detail.refused_sandboxes beside stopped_sandboxes and unknown. (C) - native uncertainty is phase-based only: a Sandbox is uncertain once its stop was sent; a code alone no longer makes it so. (B) - Recording the outcome no longer replaces the stop's own refusal: a failure while writing records is reported in detail.custody_errors. (6) - A forced stop may settle an uncertain machine.stop this process left, or one whose owner has ended; one a live process still holds is Busy, as the op standing table says. (7) Forced native sandbox.close (control): - Refused Busy while a live process holds native (e.g. a forced machine.stop in progress); an intent an ended process left does not stop it. (10) - Once the runtime stopped, a later failure (delete, registry, folder removal) carries detail.runtime_stopped and the record is marked stopped instead of left as it was. (5) Docs: engine/store/sqlite.md (Last close), api/sdk/machine.md (force on native, refused_sandboxes, custody_errors, settling an uncertain stop; docker InvalidInput for a container that is not a LayerFS worker, which the ordinary stop now also checks: finding 9), api/sdk/sandbox.md (forced native close: no per-command settle or mount check, Busy rule, runtime_stopped), control/sandboxes/README.md (record format: the machine_stopped and machine_stop_unknown fields, "v" unchanged, older builds: finding 8). Tests: - Replaced writer_admission another_process_admission_precedes_last_connection_close (added by this PR; it asserted the waiting close this commit removes) with writable_last_close_without_the_lane_neither_waits_nor_tears_down_the_wal (no wait and the WAL kept while the lane is held; an admitted close removes it). - api machine_force native_force_stop_refused_before_any_signal_leaves_no_uncertain_op now has two Sandboxes and checks the stop continues past the refused one. - api machine_force_native gains an identity case: a recorded pid naming an unrelated live process is refused before any signal, neither process is signalled, and no op is left on native. - The two changed unit tests fail on d4d9df9's product code and pass here. Checks (toolchain 1.85.1, registered worktree via tools/worktree.py): - Clippy --all-targets -D warnings, macOS and Linux, on persistence, sandbox, sandbox-backend (Linux), control, platform, machine (Linux), api (machine, postgresql), store, cli (postgresql), daemon: clean. - macOS: persistence writer_admission 14, sqlite_lock_custody 2, idle_checkpoint 4; store lease_race 1, lease_stale 1; platform machine_force 9, machine_lima 8; cli capabilities 4, stream_framed 3; api machine_force 2, sandbox_records 2, sandbox_lost 1, sandbox_family 1, sandbox_capacity_worker 3: passed. machine_force_native run live with LAYERFS_DAEMON (debug macOS daemon of this tree): 2 passed in 2.0 s, no daemon or helper left. - Linux: persistence writer_admission 15, sqlite_lock_custody 2, idle_checkpoint 4; store lease_race 1, lease_stale 1; platform machine_force 9; api machine_force 2, sandbox_lost 1, sandbox_capacity_worker 3: passed. - Linux mount lane (45 binaries, each in a fresh container with /dev/fuse, SYS_ADMIN, fresh ext4 /tmp, timeout 120, --test-threads=1): 44 binaries passed; kernel_coherence failed once in size_never_shrinks_under_concurrent_append_and_refusals_stay_refused ("read length: 0 after 1000", a FUSE read racing appends; overlay and fuse do not depend on layerfs-persistence, and the test closes no Store during the race). One diagnostic rerun of that binary passed 6/6. The same binary passed at d4d9df9. Reported as an intermittent failure, not counted as a pass. Totals of the first run: 110 passed, 1 failed, 3 ignored. - Not run: live Docker/Lima providers. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Production LOC: 161117 -> 161173 (delta +56); core 39787 -> 39787, engine 74811 -> 74818, control 40539 -> 40588, api 5980 -> 5980. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on the parent and the staged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed Sandboxes are not stopped Follows the independent review of #656 at b4a0283. - N2 (regression in b4a0283): a writable session's last close waits for the lane again, so it checkpoints and removes -wal/-shm under the lane. Closing without it whenever the lane was briefly held left the WAL behind, which bucket pull's verify close reports as a failure and backup restore's in-use check as InUse. Finding A (a writable close waits behind a writer kept after an uncertain write) is therefore kept by design: every write behind that writer already waits; read-only and diagnostic closes still take no lane. Only a failed wait (interrupted, or the directory cannot be opened) closes with SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE (no exclusive lock, no checkpoint, no unlink; no second attempt), replacing the connection leak (finding 3). - N3: the transfer leftover-WAL comment names the failed-wait close too; control open.rs's comment holds again as written. - N5: a native Sandbox that never started (no id, no runtime record) is neither marked stopped nor listed in stopped_sandboxes. - N6: a forced native sandbox.close is not refused for an unresolved machine.stop intent this process left (it already was not for one an ended process left). - D: the live identity case asserts refused_sandboxes exactly. Tests: - Replaced writer_admission writable_last_close_without_the_lane_neither_waits_nor_tears_down_the_wal (added by this PR in b4a0283; it asserted the behaviour reverted here) with writable_last_close_waits_for_the_lane_then_removes_the_wal. - api machine_force native_force_stop_refused_before_any_signal_leaves_no_uncertain_op now uses a refused, an already stopped and a never-started Sandbox. Docs: engine/store/sqlite.md (Last close), api/sdk/machine.md, api/sdk/sandbox.md. Checks (toolchain 1.85.1, registered worktree via tools/worktree.py): - Clippy --all-targets -D warnings, macOS and Linux, on persistence, sandbox, sandbox-backend (Linux), control, platform, machine (Linux), api (machine, postgresql), store, cli (postgresql), daemon: clean. - macOS: persistence writer_admission, sqlite_lock_custody, idle_checkpoint; store lease_race, lease_stale; platform machine_force, machine_lima; cli capabilities, stream_framed; api machine_force, sandbox_records, sandbox_lost, sandbox_family, sandbox_capacity_worker: 57 passed, 0 failed. machine_force_native live with LAYERFS_DAEMON (debug macOS daemon of this tree): 2 passed in 1.9 s, no daemon left. - Linux: persistence, store, platform machine_force, api machine_force, sandbox_lost, sandbox_capacity_worker: 38 passed, 0 failed. - Linux mount lane (45 binaries, each in a fresh container with /dev/fuse, SYS_ADMIN, fresh ext4 /tmp, timeout 120, --test-threads=1): 45/45, 116 passed, 0 failed, 3 ignored by their own attributes. - Not run: live Docker/Lima providers. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Production LOC: 161173 -> 161187 (delta +14); core 39787 -> 39787, engine 74818 -> 74818, control 40588 -> 40602, api 5980 -> 5980. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on the parent and the staged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review finding M1 at 0fd2a99: the comment written for native_runtime sat on the Native enum and still described an Option. Comment text only. Checks: Clippy --all-targets -D warnings on layerfs-control (macOS) clean; rustfmt clean. Production LOC: 161187 -> 161187 (delta 0); comment-only change. Method: tools/production_loc.py (blob 35e4a6d) --root <git archive snapshot> --json on the parent and the staged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review record Reviewed head: 18b4df7 (integrate/v2-force-stop-latest), merge base 27920d3 with layerfs_v2_0_0. Blocking
Non-blocking Risky-lines scan: no Durable, unsafe, DELETE FROM, rmtree, #[ignore], dependency hunk, busy handler or retry loop in production code; one production remove_dir_all (force.rs:68, mirrors the ordinary close); two asserts re-added unchanged with longer messages; one fixture value changed (stream_worker.rs image). Not checked by the reviewer: builds and tests; PostgreSQL; Windows/WSL, apple-container and lima at runtime; groups::end, mounts::detach and namespaces reopen internals; the three new test files beyond a risky-lines scan; JS/Python binding signatures against docs. Author evidence at this head (macOS and Linux, toolchain 1.85.1, registered worktree): Clippy -D warnings clean on all changed crates on both; boundary guard PASS; macOS 79 tests passed; Linux persistence writer_admission 14, sqlite_lock_custody 2, idle_checkpoint 4, store lease_race 1 and lease_stale 1, platform machine_force 9, api machine_force 1 and sandbox_lost 1 passed; api sandbox_family and sandbox_records each fail in the build container because base's kernel guard refuses a Store on its overlayfs /tmp (environment, unchanged tests). Linux mount lane (45 binaries) built, not run. machine_force_native not run. Verdict: blocked by findings 1 and 2. Owner approval is required in any case (risk:store, risk:format). |
|
Review record Reviewed head: d4d9df9 (integrate/v2-force-stop-latest). Covers the change since 18b4df7 (8 files, +133/-22) and updates the verdict for the whole PR; the 18b4df7 record stands for everything this push did not touch. Earlier blocking findings
New, non-blocking Author evidence at this head (toolchain 1.85.1, registered worktree): Clippy -D warnings clean on all changed crates, macOS and Linux; both new tests fail on 18b4df7's product code and pass at d4d9df9; macOS and Linux covering tests passed; Linux mount lane (tools/ci_tests.py mount-targets, 45 binaries, each in a fresh container with /dev/fuse, SYS_ADMIN, fresh ext4 /tmp, timeout 120, --test-threads=1): 45/45, 116 tests passed, 3 ignored by their own attributes; boundary guard PASS at 18b4df7 (the push changes no guarded path). Not run: machine_force_native, live Docker/Lima. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Verdict: mergeable after owner approval (gate: risk:store, risk:format, hand-added Store-access gate). |
|
Review record Reviewed head: d303c7b (integrate/v2-force-stop-latest). Resolved across the review: blocking 1 (read-only/diagnostic closes take no lane) and 2 (native force-stop pre-signal refusal leaves no op); B, C, 3, 5, 6, 7, 8, 9, N2, N3, N5, N6, M1.
Author evidence at d303c7b's code (0fd2a99; d303c7b changes comments only), toolchain 1.85.1, registered worktree via tools/worktree.py:
Verdict: mergeable after owner approval and explicit acceptance of A, N1 and 10. |
|
Owner approval and acceptance Head: d303c7b The owner answered "Accept and merge" in the session after being shown the three remaining trade-offs from the review records above:
Gate: risk:store, risk:format and the hand-added Store-access gate are approved with this acceptance. Per the review policy, a contributor reads the risk:store and risk:format hunks within a week after merge and files an issue for each finding. |
…l-AI-Lab#682/Ephemeral-AI-Lab#656) Upstream Ephemeral-AI-Lab#682 (Sandboxes from any local Docker image with a bundled runtime layer) and Ephemeral-AI-Lab#656 (force-stop machines and native Sandboxes) bring four unix-bound modules into layerfs-sandbox (docker, images, image_load, image_artifact) plus machine_force in control. The modules gate unix; route's create-with-image branch and its two image helpers sit behind a small facade (neutral answers on Windows); machine.images/load/prune/stop_force answer Unsupported with the Ephemeral-AI-Lab#454 pointer; the worker server's image arms are unix-only arms (no worker runs on Windows). Four conflicts resolved keeping our Windows admission lane and the fused doctor symlink check. Production LOC: 161378 -> 161947 (delta +569; upstream features with the Windows refusals; tools/production_loc.py --json).
Brings the Ephemeral-AI-Lab#136 helper reaping work onto upstream after the reviewer's first pass: Ephemeral-AI-Lab#656 force-stop of machines and native Sandboxes, Ephemeral-AI-Lab#647 macOS export-volume flush and exact Busy, Ephemeral-AI-Lab#682 image-loaded Sandboxes, Ephemeral-AI-Lab#681 GC design, Ephemeral-AI-Lab#642 one-read NFS records. Conflicts were documentation only, and are resolved into upstream's structure: - engine/daemon/control-calls.md: upstream's macOS `sync_volume_np` flush row kept; this branch's Attach (mount table read once, `tracked`), Unmount (mount-table settlement), ForceUnmount (finishing an export kept at Detach) and Helper run (retained queue) rows merged into upstream's table. - engine/kernel-routes/nfs.md: upstream's Commit line kept inside this branch's Attach/Unmount/ForceUnmount diagram. Code merged without conflicts; Ephemeral-AI-Lab#656 touches Sandbox/machine force-stop and the Store lane, not the NFS export teardown, so the two do not overlap in the data path. `cargo +1.85.1 check --locked --all-targets` on the changed crates passes at this tree. Durable: NOT_RUN - disabled by owner until explicit reauthorization. Production LOC: 160218 -> 163746 (delta +3528); first parent b49690d. core 39787 -> 39787, engine 74627 -> 75078, control 39828 -> 42804, api 5976 -> 6077. Reference absent (retired R9c; last counted 65,417 at tree 498dd19). Method: python3 tools/production_loc.py --root <git archive of b49690d> and --root <the merged working tree>.
Tier: P1; gate: yes (risk:store, risk:format, Store-access gate by hand); owner approved with acceptance of A, N1 and 10 (see comments).
Docs: api/sdk/machine.md (machine.stop force), api/sdk/sandbox.md (forced native close), engine/store/sqlite.md (Last close), control/sandboxes/README.md (record fields), glossary.md.
Durable: NOT_RUN — disabled by owner until explicit reauthorization.
Update (head d303c7b)
Brought up to
layerfs_v2_0_0(27920d3) and reworked after an independent review (records in the comments): read-only Store closes take no lane; native force-stop refusals before a signal stay certain and the stop continues past them; forced native close is gated on a livenativeholder and records a stopped runtime; record format, Docker refusal and close rules documented.Evidence at this code: Clippy -D warnings clean on all changed crates (macOS and Linux); macOS 57 tests and live
machine_force_nativepassed; Linux 38 tests passed; Linux mount lane 45/45 binaries, 116 tests passed. Not run: live Docker/Lima providers.Production LOC against
layerfs_v2_0_0at merge: 160621 -> 161187 (delta +566); core 39787 -> 39787, engine 74765 -> 74818, control 40093 -> 40602, api 5976 -> 5980 (tools/production_loc.py, blob 35e4a6d601fa).Summary
Adds an explicit
forceoption tomachine.stopand makessandbox.close --forcework onnativewithout a Store or daemon. Both stop the runtime through its provider or its own records, never through the machine's worker, and keep disks, Stores, saved history and runtime records.The branch is three commits on the current
layerfs_v2_0_0tip (03883a63cf, #655):1b22005b40: port of the force-stop and native concurrency work (7b5f5a5630) onto v2.machine.stop --forcestops providers without a live worker. Sandboxes on the machine are recordedgone, orunresolvedwhen the stop could not be confirmed, with their Workspace frontiers reportedunknown.9d30a87ad2: merges fix(sandbox): carry a full-pool capacity notice into sandbox.get (#649) #655 (no conflicts).eda9c04f12: forcedsandbox.closeonnativefrom the Sandbox's own records: no Store open, daemon control call, active-Workspace refusal or retry. The forced nativemachine.stopuses the same host builder. This is the remaining part ofc1cf6fd169.Validation
macOS, registered private worktree (
tools/worktree.py):layerfs-sandbox,layerfs-control,layerfs-api,layerfs-machine,layerfs-platform,layerfs-store, withpostgresql,machine;layerfs-cliwithpostgresql;layerfs-daemon.machine_force_nativewith a matching private daemon: the forced nativemachine.stopandsandbox.closeend the exact daemon, command and mount without opening the Store. Saved data stays readable.layerfs-apimachine_*/sandbox_*: 34layerfs-platformmachine_force/machine_lima: 17layerfs-persistencewriter_admission/sqlite_lock_custody: 12layerfs-sandboxcapacity_read/pool_admission: 8layerfs-apisandbox_capacity: 8layerfs-clicapabilities/stream_framed: 7layerfs-sandbox-backendlocal_stop_mount: 1layerfs-storelease_race: 1layerfs help --jsonadvertisesforceonmachine.stopandsandbox.close.Not run here: Linux/Docker E2E bundles.
Production LOC
1b22005b40: 158658 -> 159105 (delta +447)9d30a87ad2(first parent): 159105 -> 159152 (delta +47)eda9c04f12: 159152 -> 159204 (delta +52)Scope: first-party core, engine, control and API product sources. Method: pinned
tools/production_loc.py --root <git archive snapshot> --json.🤖 Generated with Claude Code