Spawned analysis: have an agent review a session's work - #6
Merged
Merged
Conversation
gitx, coord, ui and the smoke test had all written their own "make a repository with one commit", and they had already drifted: one resolved symlinks and the others did not. That is the difference that registers a single directory as two projects, because t.TempDir hands back a symlinked path on macOS and git reports the resolved one. internal/gittest holds it once. No test builds or queries git by hand any more; the only remaining callers are gitx.run, the demo seeder, and the helper itself. The resolution is now a rule rather than a comment. Removing it used to break nothing at all, which is how four copies managed to disagree about it; TestRepoReturnsAResolvedPath fails on both its assertions without it.
analyse starts a separate agent to review what another session changed and reports what the review cost. analysis collects it. The caller does not wait: a real review outlasts the tool timeout of whatever asked for it, and that timeout belongs to the calling agent rather than to Deck, so a synchronous answer would be money nobody receives. The reviewer is handed the diff and given nothing else. It has no coordination tools because it has nothing to ask anyone, and it runs in a mode that answers a question but refuses to act, so a review cannot become an edit. Everything it needs is in the prompt, which is what makes that prompt worth testing. A turn that ran and refused is a result, not an error. agent.ClaudeRun carries Failure as a field, because Go's convention tells a caller to discard the value alongside an error and that would put the bill out of reach in the one case where it is surprising. An error means the opposite: no envelope came back, so there is no accounting to add and inventing a figure would be worse than the gap. Cost is per session and never written to disk. A per-run figure alone is hard to read — the same one-word turn measured at $0.012 and $0.237 depending on whether its context was read from cache or written to it — so the running total is what makes a pattern visible. The sidebar carries it as a third badge beside claims and mail, accented while a review is in flight and faint once settled, following the rule already stated there. Close cancels every run the coordinator started. Without it, quitting Deck mid-review left an agent running and billing with no surface left to show it on. The spawn is a field rather than a direct call, so the suite neither spends money nor needs the CLI: a probe measured one unstubbed test run at $0.106, and CI, where claude is not installed, reported green on a spawn that had failed. WithReviewer is the seam, and it replaced a method that existed only for tests. Verified live once: a real reviewer answered ZEPHYR_RETRY_BUDGET in 3.4s for $0.1069, with the token split and the session total agreeing.
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.
Stage 3 of the connected-sessions plan.
analysestarts a separate agent to review what another session changed;analysiscollects the answer and what it cost.Two commits: the
gittestextraction stands alone and is reviewable on its own, then the feature.Four decisions, each measured rather than argued
Asynchronous, because the timeout is not ours. A synchronous call blocks the caller's tool timeout, which belongs to the calling agent. A review that outruns it returns nothing and has already spent the money.
The reviewer is handed its evidence and given nothing else. No coordination tools — it has nothing to ask anyone. It runs under a permission mode that answers but cannot act, tested rather than assumed. Everything it needs is in the prompt, so the prompt is what the tests assert on.
A failed turn is a result, not an error.
agent.ClaudeRuncarriesFailureas a field. Returning a Go error would tell every caller to discard the value — putting the bill out of reach in the one case where it is surprising. Anerrormeans no envelope came back, so there is no accounting to add.Cost is per session, never written to disk. The same one-word turn measured at $0.012 and $0.237 depending on whether its context was read from cache or written to it, so a per-run figure alone is unreadable. The sidebar carries the total as a third badge beside claims and mail, accented while running and faint once settled.
Tests
The suite neither spends money nor needs the CLI. It used to do both: a probe measured one unstubbed run at $0.106, and CI — where
claudeis not installed — reported green on a spawn that had failed.coord.WithRevieweris the seam, and it replaced a method that existed only for tests.Every wiring point fails when broken, verified by breaking it:
case "analyse"/case "analysis"TestAnalyseIsCallableOverMCPjson:"question"/json:"id"TestTheQuestionReachesTheReviewerTestFailedTurnKeepsItsCostTestAFailedRunStillCountsAgainstSpendTestJobsAreBounded—kept 55, want 50TestCloseStopsARunningAnalysisTestSidebarShowsWhatAnalysesCostVerified live once, opt-in behind
DECK_LIVE: a real reviewer answeredZEPHYR_RETRY_BUDGETin 3.4s for $0.1069, with the token split and the session total agreeing.Documented in
README.md(both tools, the new badge) anddocs/architecture.md(the four decisions, including an explicit warning not to "tidy" theFailurefield into an error return).