Repository navigation
fix(agents): finished workers, transcript reads and worktree guard - #3306
Conversation
…ries Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An unarchived session alone no longer keeps a worktree live past seven idle days; the hook still refuses to move one holding unsaved work. The transcript guard treats the session's own job directory as its own, and the worker rules send files to publish to the scratchpad. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ipts lost agents wake and agents resume reach a worker off the roster by its exact name, with its last task. An agy start keeps its conversation id, so its transcript keeps its roster name after the link files go. A read says what the store does not hold, agy tool results are stored, and a grant says what it covers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Desk review of exact head Verdict: changes needed. Two closing issues are not complete; the worktree change has a data-loss risk.
Closing-issue assessment:
The explicitly non-closing #3283 correctly remains open: ended non-Claude harnesses are refused rather than continued; no live continuation proof is supplied. Validation: exact-head static review, linked issues and comments read. The original focused tests passed:
Temporary test overlays (no reviewed source changes) reproduced findings 1–2:
|
…indexed The hook's unsaved-work check resolves the worktree a session's folder lies in, so a session in a subdirectory keeps its protection, and an unreadable lookup keeps it too. An agy transcript indexed before results were stored is read again once. A read tells what is gone for good from what only the index misses, and an empty result from a missing one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Verification of exact head Verdict: the three previous findings are fixed.
The PR still has all six Closes lines. Against their stated acceptance criteria:
#3283 remains explicitly open, as before. Validation: focused guard, transcript, archive and root/subdirectory worktree tests, plus my original unchanged-cache reproduction in a scratch-only test overlay. All pass at the head above. Read only: no source edits, pushes or merges. This is verification of the earlier review, not a fresh review of unrelated changes. |
* origin/main: feat(guard): send harness memory to the desk, let the guide write there (#3304) ci: stage batch gate and catch package lint before push (#3314) fix(agents): finished workers, transcript reads and worktree guard (#3306) feat(execution): sync policy per start, account for host leftovers (#3311)
…0a00f80-86c3-479f-b27a-7f2192f5fb1b/1 * origin/main: feat(update): roll back unhealthy releases during probation (#3316) feat(disk): show what holds the disk; serialize Teleport renewals (#3312) chore(deps): update dependency ubuntu to v26 (#3321) chore(deps): update actions/github-script action to v9 (#3320) feat(guard): send harness memory to the desk, let the guide write there (#3304) ci: stage batch gate and catch package lint before push (#3314) fix(agents): finished workers, transcript reads and worktree guard (#3306) feat(execution): sync policy per start, account for host leftovers (#3311) fix(supervisor): skip closed, absorbed and never-owned work in dispatch (#3315) feat(hook): carry an answered note for a production deletion (#2492) ci: vendor the Kubernetes schema the chart schema check reads (#3310) test: wait for pass actions before a loop rig's state goes (#3313)
Written by an agent.
One batch for the agents lifecycle, transcript reads and worktree guard issues.
Closes #633
Closes #2064
Closes #3219
Closes #3235
Closes #3282
Closes #3284
Refs #3283: this PR does the part that needs no live proof. It stays open, see below.
Folds in #2325 and #2616, which both merged cleanly with main and are closed in favour of this PR.
What changes
Guard (2064, 3219). From 2325: an embedded slash in a relative path no longer reads as an absolute path, and unshadowed
duanddfpass as metadata. New: the session's own$CLAUDE_JOB_DIRcounts as its own. The refusal reproduced only with a literal path into a job directory inside a transcript store, where the session-id ownership check does not match. The exemption checks the resolved path too, so a link out of the job directory stays refused, and it is ignored for a directory holding a whole store.$CLAUDE_JOB_DIRis now also expanded, so$CLAUDE_JOB_DIR/../../other.jsonlis refused where it used to pass unresolved.Worker rules (3235). The
Filesrule names<scratchpad>for artifacts. The rules have a 2500-byte budget, so the line was reworded rather than extended, and the test pinning the old phrase moved with it.Worktree liveness (3282). An unarchived desktop session keeps its worktree live for seven days after its last activity, read from its record and its transcript, not forever. A record with no activity at all stays live. Processes, running sessions and unfinished roster agents keep a worktree live as before. The trim and the disk step judge a tree's work themselves. The hook's
mv/rmrefusal has no such check, so past the bound it still refuses a worktree with uncommitted or unpushed work, and one it could not read within ten seconds.Archive agreement (633). From 2616:
agents.archiveAgreementgoes from the schema, the doctor and the wording; the steward route archives without it. This loosens a confirmation step: sessions a person started stay excluded, and archiving stays reversible.Transcripts (3284). Beekeeper never writes
<truncated N bytes>, so those markers are the harness's own and that text cannot be recovered.transcripts readnow opens with a# lost for good:line counting harness cuts, clipped tool results and tool calls with no stored result, and--jsoncarries the same asloss. Agy tool results are now stored: they were dropped by the parser. The store's own 4 KiB clip stays, but each clipped result now says how many bytes are missing. A grant says it covers the stored transcript and not the files that session wrote, and says when no stored transcript matches it yet.Finished workers (part of 3283).
agents wakeandagents resumereach a worker off the roster by its exact name. It comes back on the roster with its last task, in its own conversation, under the same stop, starts-hold and usage checks. Only these two commands look there: a timer or a settled wait naming a finished worker still wakes nobody. An agy start now records its conversation id in state, because the link files go with the inbox; that is why a stored agy transcript lost its roster name, and whytranscripts read <name>and a grant by name found nothing.Stays open: 3283
Claude Code workers continue. An agy, codex or omp worker whose process ended is refused with a line saying beekeeper cannot continue it and naming its stored transcript, which is the issue's fallback. Those three harnesses do have resume options, so "every harness that can continue one" is not met yet: relaunching them needs a live proof that the harness really rejoins the same conversation. A wrong guess there would quietly start a new one.
An agy worker started before this change has no recorded conversation id, so its transcript keeps no roster name.
Not in this PR
#1193 stays open. #2426 replaces the steward with a configured command, but no such adapter exists, so it does not close the issue, and it conflicts with the agreement removal here.
Overlap
Shared files, no shared logic found:
cmd/agentpark.goandcmd/agents.gowith #3303 and #3305,internal/state/state.gowith 3305, #2492 and #2340. The real conflict is 2426, above.Validation
go build ./...go test ./internal/guard ./internal/transcripts ./internal/worktrees ./internal/config ./plugin: pass.go test ./cmd ./internal/tui -run 'TestRestarted|Ended|Transcript|Archiv|Steward|PickSteward|OwedArchive|PlanArchives|SeedArchives|SayChores|PeerSendDelivers|TestDoctor|Idle|Worktree|TestGone|Skill': pass.go test ./cmd -run 'Prompt|Places|Scratch|Rules|Brief': one failure,TestScratchSecretBrokerLifecycle/vault-socket,bind: invalid argumenton a Unix socket under a long temporary path on the development host. This PR touches no sandbox or secret file; CI runs it on a short path.TestTranscriptOwnJobDir,TestIdleDesktopSessionKeepsNoWorktreeLive,TestAgyResultsAndLoss, andTestEnded*for both harness outcomes, the starts hold, the name-only lookup and the roster name.Nothing here was proven against a live desktop or a live agy session. The agy result shape is the one the existing activity reader already relies on.
🤖 Generated with Claude Code