Repository navigation
A sandbox's CLI reaches its owner, and its record carries its truth - #246
Open
geekgonecrazy wants to merge 4 commits into
Open
geekgonecrazy wants to merge 4 commits into
geekgonecrazy wants to merge 4 commits into
Conversation
The token-granted remote-sandbox stack, the CLI that runs inside one, and the record contract that keeps a write honest. - **Sandbox grants, with a host-store seam**: libatomic's DaemonState holds them in memory by default; a host that persists them installs its own store before serving. The ingress serves sandbox tokens only. - **The CLI inside a remote sandbox**: a pointer is a working root, the view materializes into the sandbox's cache, and its writes submit to the owner over the socket — nothing opens a repository the sandbox does not have, and a lost socket fails instead of starting a daemon on the cache (`ATOMIC_DAEMON_BIN=/usr/bin/false`). - **The remote sandbox's cache**, without the owner protocol: view skeletons and graph slices imported from submitted bytes, a sandbox that fell behind materializes again before it records. - **`triage review` serves the report**: the full bundle (verdict, findings, intents and criteria, changes with real diffs, the walkthrough) rides GenerateTriageReview as versioned `atomic.triage.report.v1`, so the CLI renders over the service what the local builder produced. - **The write carries its truth**: a record carries its AI authorship (vendor, model, tool, suggestion, tokens, session) into provenance, and fences on the view's state — the response's `view_merkle` chains the next write; a stale expectation refuses VIEW_STALE instead of landing over someone else's change. Insert fences on the target view the same way. - **A turn's cost and conversation ride its record**: the sherpa turn-end hook reports the turn's tokens and step count, and the change's unhashed agent_turn carries them with the condensed transcript — the prompt, the tool calls, and the closing reply (a bare-string assistant turn included) — attached before serialization, so the local store and a sandbox's submitted bytes are the same document. Verified: `cargo test --workspace` — 9208 passed, 0 failed — including the remote-sandbox CLI e2e (token scoping, intent writes landing with their record, provenance publishing, the transcript's cost landing on the change) and the sandbox and triage service suites.
… private doc links - record/mod.rs: the Base32 import and the mut on the record outcome were left over from removing the attach-then-resave path — both gone. - diff_engine.rs: two doc blocks orphaned by the triage move (the stat graph and the word-diff renderer live in the CLI now) were interleaved before change_file_diffs's own docs, tripping empty_line_after_doc_comments — removed. - intra-doc links to private or moved items (export_crdt, layer_key, effective_state, super::output) unlinked — the doc job runs rustdoc with -D warnings. - the remote-sandbox e2e binds a Unix socket; the file is now cfg(not(windows)), the same gate the other socket-based integration tests carry. - a needless borrow in the triage service test.
geekgonecrazy
force-pushed
the
atomic/sandbox-stack
branch
from
October 9, 2026 21:35
a928c5b to
792ec10
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The token-granted remote-sandbox stack, the CLI that runs inside one, and the record contract that keeps a write honest — rebased onto dev as one squashed delta (dev's #239 libatomic and #243–#249 are preserved; the CLI service area, diff/log rendering and build identity come from dev, everything below is added).
Sandbox grants, with a host-store seam
libatomic's
DaemonStateholds grants in memory by default; a host that persists them installs its own store before serving (DaemonState::with_sandbox_grants). Tokens are minted blake3-hashed, carry a view, a capability subset and a server-clock expiry (TTL bounded, default 7200s);renew_sandboxextends the expiry andclose_sandboxrevokes. Every request bearing a sandbox token is resolved against the store — a token that does not resolve is refused, per request.The CLI inside a remote sandbox
A pointer is a working root (
.atomic-sandbox, mode 0600 — it carries a credential);atomic sandbox materializereconstructs the view into the sandbox's cache; its writes submit to the serving repository over the daemon socket, carried there by whatever the host serves (a forwarded socket, a direct connection). Nothing opens a repository the sandbox does not have, and a CLI that loses its socket fails (ATOMIC_DAEMON_BIN=/usr/bin/false) instead of starting a daemon on the cache. Only the commands that work off the cache run there; the rest refuse, naming the sandbox and why.The remote sandbox's cache, without the owner protocol
View skeletons and graph slices import from submitted bytes; a sandbox that fell behind materializes again before it records. The cache's perspective mirrors the ancestor walk exactly — pinned by a parity test against the repository's own perspective.
triage reviewserves the reportThe full bundle — the verdict, the findings with their remedies, the intents and their criteria, the candidate changes with their diffs, the guided walkthrough — rides
GenerateTriageReviewas versionedatomic.triage.report.v1, so the CLI (and any web UI over the service) renders the same document the local builder produced. The CLI-entangled triage builder moved into the repository (triage/{mod,model,report}), served instead of shelled.The write carries its truth
A record carries its AI authorship (vendor, model, tool, suggestion type, tokens, session) into the change's provenance —
Provenance::from_authorship_parts. And it fences on the view's state: the caller passes the state it last saw (expected), the response'sview_merklechains the next write, and a stale expectation refusesVIEW_STALEinstead of landing over someone else's change. Insert fences on the target view's snapshot the same way; dry runs read only and don't fence. (Dev's #248 working-copy protection sits beside the fence in the same handler — different hazard: it guards a dirty working copy, the fence guards a moved view.)A turn's cost and conversation ride its record
The sherpa turn-end hook reports the turn's tokens and step count; the change's unhashed
agent_turncarries them with the condensed transcript — the prompt, the tool calls, the closing reply — attached before serialization so the local store and a sandbox's submitted bytes are the same document. A bare-string assistant reply (how a text-only turn serializes) is a turn of the conversation; dropping it left provenance ending at the last tool call.Related
ATOMIC_SERVICE), diff/log rendering and build identity come from dev (feat: add libatomic #239/fix(cli): map syntext IndexNotFound and auto-build content index in query code #243/fix(cli): render view list hierarchy over RPC #244/feat(cli): include commit identity in development builds #245); this adds the sandbox-aware routing (open_root→ no service session inside a remote sandbox; commands run their local bodies over the cache), the remote-sandbox client, and everything above.{canonical, view}, written byatomic sandbox create) parses as no remote sandbox — those sandboxes keep opening the canonical graph exactly as before; a remote pointer (which requiresrepository+token) can never parse as an old one.Verified
cargo test --workspace: 9222 passed, 0 failed — including the remote-sandbox CLI e2e (atomic-cli/tests/remote_sandbox_client_test.rs: the real binary inside a pointer-only tree over a Unix socket — token scoping, intent writes landing with their record, provenance publishing, the transcript's cost landing on the change; the same binary host-side through the same server), the sandbox service suite (open/renew/close, materialize, submit — the token gate, the fences), the triage service suite, the record service suite (authorship, fence, view_merkle chaining), and the repository parity tests for the sandbox cache.