Repository navigation
Conversation
A session whose final save failed was held for 24 hours so its workspace could be recovered from the Pod. The workspace is an emptyDir on a spot node, so a spot interruption or a cluster-autoscaler scale-down (which ignores terminated Pods) deleted it within minutes. On 2026-11-09 two staging sessions lost their work this way. After a failed final save, buzz-acp now runs `buzz-agent-checkpoint quarantine`, which stores the workspace without the secret scan under `<prefix><generation>/quarantine/`. Excluded credential paths stay out, and no repository is dropped: one without a commit is kept as base `unborn`. The quarantine gets at most 90s and ends within 290s of the stop's start, inside the Pod's 300s grace period. The reaper records that archive (checkpoint-source `quarantine`) ahead of a listed turn checkpoint and tombstones the session at once instead of holding it. Recover from checkpoint restores it, skipping the restore-time scan only for quarantine keys. Signed-off-by: Tee8z <tee8z@protonmail.com>
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Takeover runtime recheck of the existing checkpoint implementation: the packaged Reran This adds runtime evidence to the prior reviews. It does not claim a staging rollout or human acceptance. The security dependency update and accepted temporary SQLite policy exception are prepared in #155. |
Problem
When the final checkpoint of a remote-agent Sandbox fails, the reaper holds the session for 24 hours so the workspace can be recovered from the Pod. The workspace is an
emptyDiron a spot node, so the hold protects nothing:brandonc55728…-a76cb9c93e11replaced, older turn checkpointtee8z1c425d…-510f13618843replaced, the checkpoint it was restored from; all session work lostBehavior
After a failed final save, the harness now stores the workspace without the secret scan. The reaper records that archive and ends the session at once.
flowchart LR stop[Harness stops] --> save[buzz-agent-checkpoint save] save -->|ok| receipt[termination receipt: source receipt] save -->|failed| quarantine["buzz-agent-checkpoint quarantine (at most 90s, ends by stop start + 290s)"] quarantine -->|ok| q["S3 prefix/generation/quarantine/uuid.tar.gz"] quarantine -->|failed| hold[no archive: 24h hold, as before] q --> reaper[reaper tombstones at once: source quarantine] reaper --> recover[Recover from checkpoint restores it]checkpoint.pyquarantineaction. It packs likesavebut runs no secret scan and no bundle validation. It keeps every excluded path out (private runtime files,.env*,PRIVATE_NAMES). A repository without a usable origin is bundled whole. One whose HEAD has no commit (newgit init, orphan checkout) is kept as baseunborn: its other branches and every file. No repository is dropped.checkpoint.pyrestorequarantine/skips the restore-time scan. The key decides this, not the archive's manifest. A repository without a usable origin keeps its remote-tracking refs; only the temporary URL is cleared. A verified restore still refuses an empty origin or anunbornrecord.buzz-acpfinal_saveruns the quarantine only after a failed final save, never after a turn save. It reportscheckpoint_quarantinedorcheckpoint_quarantine_failedand still exits non-zero. The quarantine gets at most 90s and must end withinSTOP_BUDGET(290s) of the stop's start, inside the Pod's 300s grace period. With under 10s left it is skipped and reported (reasondeadline). The drains before it have no shared bound (Known Defect 7), so it takes the remaining time instead of adding a fixed term.Evidence::Quarantined. Precedence is receipt, quarantine, listed, inherited. A Completed session with a quarantine archive is tombstoned at once; one without an archive still holds. An S3 outage on the quarantine listing defers; it never recordsmissing.lifecycle.rsCHECKPOINT_SOURCE_QUARANTINE,QUARANTINE_DIR, andis_restorable_key, so a session recovered from a quarantine inherits that key.Quarantine keys have one more
/than session keys, sois_session_keykeeps them out of the session listing. Clients need no change: no client readscheckpoint-source, and Recover from checkpoint restores the tombstone key. No infrastructure change: in voltage-terraformv2/environments/staging-agent, the Sandbox role may put and get<developer>/*, the reaper may list the bucket, and the unfiltered 30-day expiration rule covers quarantine archives.Tradeoff: a quarantine archive can contain a credential that the agent wrote into a repository file; the secret scan exists to refuse exactly that. The archive stays in the developer's own prefix, expires in 30 days, and restores only through explicit recovery.
voltage/remote-agents.mdnow says so.Validation
cargo test -p buzz-acp -p buzz-sandbox-reaper -p buzz-backend-kubernetes: 1126, 143, and 225 passed.cargo clippy --all-targets -D warningsandcargo fmtare clean.a_failed_final_save_ends_at_once_on_its_quarantine_archivereplays the staging incident.quarantine_archives_are_listed_apart_from_session_checkpointscovers listing, nested keys, foreign generations, and an outage.a_failed_final_save_quarantines_the_workspacecovers save ok, quarantine ok, quarantine failure, and a spent stop deadline.checkpoint_stop.rsruns the harness binary: a failed save is followed by exactly one quarantine on the post-ready and startup-cancel stop paths, and a successful save by none.test-checkpoint-storage.py(image, moto S3) now covers: SIGTERM, then a final save that the secret scan refuses, then a quarantine, then recovery that restores the leaked file, a repository without an origin, and a repository without a commit, but never.env. The same archive stored under an ordinary key is refused, because only aquarantine/key skips the verified restore.test-checkpoint.py,test-checkpoint-shallow.py,test-checkpoint-storage.py, andtest-restore.pypass against a local build of this commit's agent image. CI runs them again on publish.Limits
deadline). A spot interruption gives about 2 minutes, which a slow save can use up.listedsource.unbornrepository has its files unstaged.CheckpointMissing. The failed save shows as(source: quarantine)inSessionEndedand ascheckpoint_failedin activity. There is no separate metric.Agent review
Two independent agent reviews ran.
unbornbase keeps them, and the image test covers it.Human test
Prerequisite: staging runs this branch's agent and reaper images. Pins live in voltagecloud/cd (manager, gate) and voltage-terraform (worker).
github_token = "ghp_aB3dE6gH9jK2mN5pQ8sT1vW4yZ7cF0iL3oR6"intoleak.txtin a cloned repository and change another file.SessionEndedEvent to show(source: quarantine)within one pass, and noCheckpointMissingEvent:Summary by CodeRabbit