Repository navigation
feat: keep an autonomous session working while the person is away - #1101
Merged
Merged
Conversation
…estions The critical overnight stall is fixed first rather than deferred, on the product thinker's standing rulings; its smallest slice is its own intent. The slice's design questions and the checklist draft's obvious ones are answered from the record and the host's documented hook behaviour. Refs: iss-2610170619247185 Refs: itd-2610170638184486 Assisted-by: Claude:claude-opus-5-5
The away mode held by abcd and repeated at every start, compaction and prompt, a Stop hook that refuses to end a turn with owed work while the person is away, and the question reroute become their own planned intent with a seven-step spec ending in a live session capture. The ready gate passes. Refs: iss-2610170619247185 Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
…ng walk Fourteen Given-When-Then criteria derived from the press release and the product thinker's decisions, marked as a draft to walk on Thursday, and the scope split names the first slice that builds on the draft. Refs: itd-2610170638184486 Assisted-by: Claude:claude-opus-5-5
Refs: itd-2610170638184486 Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
The plan review of 2026-10-18 (an Opus and Sonnet pair) returned fix the plan first. Every blocker, major and moderate is applied as a plan edit: "own" work without a window, read from the reflog, a run's lanes and this copy's reservations; a clearing rule for stacked branches; a stop allowed while away only with a wake whose next fire time precedes the earliest renewal due; questions routed by the act, with the acts only the person may approve queued; the away record changed under a lock and capped at seven days; present mode reading disk only; a StopFailure entry. The return report, the status line and the bare mode print move back to the checklist draft, and the slice is re-estimated at five days. Eight new decisions record the refinements; the spec carries a review round note listing each finding's disposition. Refs: iss-2610170619247185 Refs: itd-2610180912189125 Refs: itd-2610170638184486 Assisted-by: Claude:claude-opus-5-5
Only the person sets the away mode now: guard entries refuse an agent's every route to it that the guard reads, and the mode's push rights are narrow, with the default branch, tags, cuts, other people's pull requests and review-only branches excluded. The wake deadline gains a ceiling and the host's lateness, behind comes from the forge's merge state, created branches are recorded as own, stale and review-only branches are not, the person-only acts are completed, and a lapsed window points at the verb that ends it. Nine refining decisions and a proposed ADR for the network read record it; the slice is re-estimated at eight days. Refs: itd-2610180912189125 Refs: iss-2610170619247185 Assisted-by: Claude:claude-opus-5-5
The away mode now grants no push rights: the person's own standing instruction decides what is committed, pushed and opened, as before, and an owed item that needs a push is pushed only if that instruction allows, otherwise queued and handed back for the window. The guard entries that made setting the mode person-only, the guard's reading of go run and built binaries as abcd, the forge listing's reuse cache and the fuller mode back print move to the checklist draft as named remaining work. The created-branch recorder, the ownership, link and stale rules, the wake deadline, the merge-state reading and the person-only acts stay, so round 2's blockers stay fixed. Re-estimated at 5.75 days over seven steps, down from eight. Two decisions record it, the first superseding round 2's choice (a); the invariant 7 ADR drops the cache while proposed. Refs: itd-2610180912189125 Refs: itd-2610170638184486 Refs: iss-2610170619247185 Assisted-by: Claude:claude-opus-5-5
…third review A queued push now hands nothing back unless the person ran abcd mode autonomous --hold-pushes, and then only a verified branch's unpushed item; a qualifying wake releases an unchanged set of work the session can do itself at most twice in a row. The cheap minors are written in, a Review round 3 section lists each finding, and the size is re-estimated at 7.5 days of work. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
…heck # Conflicts: # .abcd/development/research/notes/2026-08-15-decomposition-calibration.md
internal/core/autonomy keeps one away record per repository on the machine, in the away store keyed on the root commit, changed only under fsutil's file lock with a re-read inside it. A record or lock that is not a regular file this account owns that no one else can write, within 64 KiB, reads as not away and refuses a writer, naming the file. A record lapses at its end, seven days at most; repeated identical stops collapse into one entry. Record and Owed are fixed here so the owed-work and stop-verdict lanes can build against them. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
RefuseParkWhileAway refuses product-thinker and facilitator while the away mode holds, naming abcd decide and abcd mode queue; managed is never refused and the three-word vocabulary is unchanged. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
The away verbs reach autonomy from the CLI and the plugin page: autonomous [--until <time>] [--hold-pushes] sets the record, queue keeps a step for the person's return, and back prints one line per queued step, hand-back and stop, records who ended it, and closes it. While the record holds, mode product-thinker and facilitator are refused naming abcd decide. Every refusal exits 2 with nothing written. The verb gains its own brief chapter, as surface_coverage requires once it has sub-verbs, and the derived reference and appendix are regenerated. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
Step 1 of the overnight-stall plan is landed; its Settled here section records the readings the build lane chose where the plan was silent, for review. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
While the away record holds, the session-start hook prints the away block on every source, compaction included, and the prompt hook adds it to every prompt outside the rules loader's dedup ledger. The block says the mode grants no rights, lists the acts only the person may approve, routes every other question to abcd decide, and allows abcd mode back only on the person's word. The person sees one line on every prompt naming who set it, from which copy, the steps queued and items handed back, and abcd mode back; a lapsed, unclosed record holding a queued step or a recorded stop shows one line naming that verb instead. The session-start hook notes each session's start copy in the away store, first note kept, so a hook run from a worktree the session made resolves to the start copy. The prompt hook reads the record through the drain's root-commit lookup, so it still makes one a prompt. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
…branch reading The guard's pre-tool hook reads each shell command for the branches it creates (git worktree add -b|-B, git switch -c|-C, git checkout -b|-B, git branch <b>, a bare git worktree add, git worktree add on an existing branch) and carries a record across git branch -m|-M, before the guard judges it. A created name is kept only when no branch of that name exists; names match whole. The list is per working copy, keyed on the copy key, in the away store, written under the store's lock, capped at the hundred most recent. It records whether or not the person is away and refuses nothing: a store it cannot write leaves one stderr line. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
Judge is the stop verdict, pure over the away record, the owed set, the host's payload and the session's state: a prose question is blocked once; owed work blocks, naming the next item, unless a qualifying wake holds the session waiting, and a wake releases an unchanged set of capped items at most twice in a row; with nothing owed the session takes the next ready item or schedules a look. A wake qualifies when its latest fire time, read by abcd's own five-field cron parser with the host's lateness added, falls before the deadline: the earliest renewal due less the skew, and at most half an hour on while work is owed. stop_hook_active alone drives the count of consecutive blocks, and the block passing the host's cap is recorded as a stop possibly forced by it. A hand-back is accepted only under --hold-pushes and only for an unpushed branch's item. The session's state is kept per session id in the copy's local tier. Owed gains NextRenewal and HandedBack. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
While the away record holds, the guard's question gate refuses every call to the host's question tool before any other check, abcd's or another tool's, chipped or not, with one reason: an act only the person may approve is queued with abcd mode queue, and every other question is decided and recorded with abcd decide. No mode is set from a chip and nothing is marked open. The list and the route live in autonomy.PersonOnlyActs and autonomy.QuestionRoute, so the away block and the stop check can repeat the same text. An away record the store refuses reads as not away, and the hook says so with exit 1. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
The guard chapter, the guard page and the mode page say the gate refuses every question while away with one reason routing it by the act, sets no mode, and that nothing detects the act mechanically. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
…hoices Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
The away block and the stop check's prose-question block now carry autonomy.QuestionRoute, the question reroute's one statement of the acts only the person may approve, instead of a list of their own. A placeholder file stands in for the reroute's question.go until its branch merges, with exactly its text, and is deleted then. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
autonomy.ReadOwed(ctx, ReadOptions) is the stop check's one seam onto owed work. While the person is present it reads disk only: renewals due and unpushed own branches. While away it adds one listing of the open pull requests under a ten-second deadline, for failing, behind (the forge's merge state, DIRTY as behind), stacked and uncarried work, and fails open to the disk kinds, naming the pull requests as not read. A branch is own through this copy's reflog or its created-branch list while it holds a recent commit of this checkout's or a live reservation links it, as a lane of a live run, or as the head of the person's pull request a reservation under this copy's key links by head branch or a closing trailer. A stacked branch is judged by the clearing rule, review and receipts included. With --hold-pushes a queued step hands back a verified branch's unpushed item, recorded once per branch and head. landing.GHContext binds the forge client to a caller's deadline; brief invariant 7 gains the away mode's one listing per check. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
…e's choices Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
abcd hook stop maps the Stop payload onto the verdict: it reads the
session's start copy from the session-start note, the away record, the
owed set through one seam the owed reader fills, and the session's
state, then answers {"decision":"block","reason":...} on a block, a
systemMessage naming owed work while the person is present, and
nothing otherwise. It records accepted hand-backs and the stop passing
the host's cap (CLAUDE_CODE_STOP_HOOK_BLOCK_CAP raises it) under the
store's lock. A malformed payload, an unreadable record or session
state, or a lock not had allows the stop with a stderr line. abcd hook
stop-failure records a turn ended on an API error, with its type, while
the record holds, and writes nothing while the person is present. The
manifest gains Stop (30-second timeout) and StopFailure entries whose
scripts never download the binary, and the brief's hook paragraphs name
them.
Refs: itd-2610180912189125
Assisted-by: Claude:claude-opus-5-5
Steps 2 and 5 of the overnight-stall plan are landed; the plan's Settled here section records the readings build lane 1 chose where the plan was silent, for review, among them the owed reader's seam and the placeholder for the question reroute's text. Refs: itd-2610180912189125 Assisted-by: Claude:claude-opus-5-5
Step 6, the question reroute, lands beside steps 2 and 5. Its question.go carries the text lane 1's question_placeholder.go stood in for, word for word, so the placeholder is removed in this merge to keep the tree building. Assisted-by: Claude:claude-opus-5-5
Steps 3 and 4, the created-branch recorder and the owed-work reader, land beside steps 2, 5 and 6. Three conflicts, each kept both ways: the guard chapter keeps the question gate's away paragraph and adds the recorder's section after it; the autonomy package doc keeps the verdict's section and adds the branch list and the reader after it; the spec keeps every lane's landed line and Settled here entry, lane 2's after step 6's. Assisted-by: Claude:claude-opus-5-5
ReadOwed now returns Owed.NextRenewal, the earliest renewal due among the live reservations under this copy's key, which the wake deadline needs, and moves a queued push's unpushed item into Owed.HandedBack instead of recording it. The verdict accepts a hand-back and the stop hook records what it accepted, so a hand-back has one owner and is never recorded for an item the verdict puts back among the owed. Assisted-by: Claude:claude-opus-5-5
The Stop hook's seam now defaults to autonomy.ReadOwed and is asked with autonomy.ReadOptions, replacing lane 1's local stand-in, which read nothing owed. An end-to-end test runs the hook against a real checkout with an own branch holding unpushed commits and a stub forge client: away, the stop is blocked with the push sentence that defers to the person's standing instruction; present, it is allowed and the forge never asked. Assisted-by: Claude:claude-opus-5-5
The created-branch recorder now resolves its copy through the session-start note (autonomy.ResolveCopy), falling back to the payload cwd's worktree when the session has no note, so a branch a session cuts after changing into a worktree it made is recorded under the copy the stop check reads. Assisted-by: Claude:claude-opus-5-5
…gin is known adr-2610181003541997, still proposed, is amended in place: the stop check's one listing covers every open pull request when the person's forge login is known, since the reader needs other people's pull requests to keep them out of the session's own, and the person's own alone when it is not. Invariant 7's clause and the spec's design text say the same. The spec records the integration's choices: the placeholder removed in the merge, the stop hook as the one owner of the hand-back record, the wired seam and the recorder keyed on the start copy. Assisted-by: Claude:claude-opus-5-5
…hes as not own Two minors of the diff review: - The carried check accepted a fork's or another person's pull request naming the reservation, which findOwn excludes; it now applies the same filter, so such a pull request carries nothing. - Sibling copies on one machine share the author email, so a branch this copy only checked out once to review read as its own. A branch from the reflog that another worktree has checked out now is that worktree's, unless this copy's sessions recorded creating it or a linked pull request names it. Assisted-by: Claude:claude-opus-5-5
The spec gains the "Diff review round 1" table, one row per finding with its fix and tests, the fix round's choices under "Settled here", and the hooks reference read again: the Stop feedback form and StopFailure's input. The mode command page says `back` ends the mode whatever state the record is in, and that a full queue refuses. Assisted-by: Claude:claude-opus-5-5
The away hooks still asked git for the checkout's root before finding no .abcd/ there. They now look for the nearest .git entry first, with no git: a .git folder with no .abcd/ beside it is left untouched, and only a managed-looking checkout, or a linked worktree's .git file, is asked of git. The release orchestrator's rule: abcd changes nothing about how an unmanaged repository behaves. Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-sonnet-5-5
…idual Assisted-by: Claude:claude-sonnet-5-5
A docs-fidelity review of the stall slice found seven sentences the code contradicts. `mode back` never refuses on the record's or lock's state, so its sentence and the mode chapter now say it ends the mode whatever that state, and setting the mode carries a record merely past 64 KiB. The StopFailure shim names the API-error stop it did not record, not the stop check. The branch recorder is gated on abcd managing the checkout, not on the local tier. The guard hook also writes the mode and the open-question marker on an admitted abcd question. The away-record warning status appears only where the question would otherwise pass silently, an undecodable question payload fails open before the away check, and the on-disk behind check covers every pushed branch of the session's own when the pull-request listing fails. Assisted-by: Claude:claude-opus-5-5
While the person is marked away, a session that tries to end its turn with work it owns still owed is sent back to it; a waiting session needs a wake in time to keep its reservations; a question is routed by the act to a recorded decision or the person's return queue; and the away record is repeated at every start, compaction and prompt. Delivers: itd-2610180912189125 Resolves: iss-2610170619247185 Assisted-by: Claude:claude-opus-5-5
Assisted-by: Claude:claude-opus-5-5
TestAwayHooksLeaveUnmanagedRepoAlone joined the home folder's name by hand, which the home-name boundary refuses in a test; the fixture now follows the name when it changes. Assisted-by: Claude:claude-opus-5-5
The away mode added 04-surfaces/26-mode.md without joining briefDocs, so the brief-surface crosscheck would not read it. It is pinned in chapter-slug order, between memory and reading. Assisted-by: Claude:claude-opus-5-5
Eleven exported functions in internal/core/autonomy were reached only from their own package, or from tests in the CLI package: begin, createdFile, latestFire, openStore, owedKinds, parseCron, parseUntil, qualifyingWake, resolveWho, sessionStatePath, and wakeDeadline (renamed from Deadline so it does not collide with the deadline locals it is assigned to). PersonOnlyActs is gone: its own test reads the list directly, and the guard test now holds the refusal to QuestionRoute, which carries every act. The CLI tests that opened the store or built a record by hand now go through Resolve and SetAway, the paths the verbs take. Assisted-by: Claude:claude-opus-5-5
…o baseline Run alone, the test counted the guard's once-per-process git version check as the recorder's work. Assisted-by: Claude:claude-opus-5-5
REPPL
enabled auto-merge
October 18, 2026 17:18
The literal tripped the secret scan's generic-api-key rule on the commit that added it; that commit's line is fingerprinted as history residue. Assisted-by: Claude:claude-opus-5-5
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 18, 2026
github-merge-queue
Bot
removed this pull request from the merge queue due to failed status checks
Oct 22, 2026
Main changed gitutil.RootCommit to return (string, error), so a failed git call is never read as a repository with no root commit. The away store, written against the old signature, no longer built on the merge result, and the merge queue dropped the PR twice for it. openStore now stops with git's failure rather than ErrNoRootCommit, as lab and the implement loop do. ResolveCopy treats a noted copy git cannot answer for as unconfirmed and acts from cwd's worktree, as it already did when Toplevel failed there. Assisted-by: Claude:claude-opus-5-5
The review pair on the RootCommit adaptation found that the Stop hook allows a stop with nothing on stderr when git does not answer for the root commit. The behaviour predates the adaptation; it is filed rather than changed on the release's critical path. Refs: iss-2610222021318139 Assisted-by: Claude:claude-opus-5-5
REPPL
enabled auto-merge
October 22, 2026 22:09
…heck # Conflicts: # .gitleaksignore
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.
Summary
This fixes the critical lapse in which an autonomous session sat idle overnight with work it could do alone. It delivers the first slice of the autonomous-agents bundle.
The person marks themselves away with
abcd mode autonomous [--until <time>]and ends it withabcd mode back. While the mode holds:Stophook reads the work: its live reservations, its own pull requests that are behind or failing, its own unpushed branches, and stacked branches whose base is still open. It sends the session back to the next item. "Own" covers branches the session created, including ones made with a plaingit worktree add, so both instances of the incident are caught. The away mode grants no push rights: where an item needs a push, the session pushes only if the person's own standing instruction allows it, and otherwise queues it.Safety:
mode backsucceeds whatever state the record is in;Evidence
Decisions are recorded on delegation, citing the product thinker's standing rulings, under dcn-26101809* to dcn-261018103*. The ADR for the invariant 7 amendment is adr-2610181003541997 (proposed).
Delivers: itd-2610180912189125
Resolves: iss-2610170619247185
Refs: spc-2610180914469489
Assisted-by: Claude:claude-opus-5-5