diff --git a/assets/AGENTS.md b/assets/AGENTS.md index 55b3dc33..a85cf862 100644 --- a/assets/AGENTS.md +++ b/assets/AGENTS.md @@ -182,7 +182,8 @@ Remove the `quest` label from issues no other quest tracks. ## Workspace -Work in your own worktree. +Work in your own worktree, reusing a suitable one you already own. +Read-only discovery needs no new checkout when your context or a checkout you own already answers it. Put PR bodies, review drafts, logs, patches, helper scripts, and temporary clones in its `.tmp/`, so they disappear with the worktree. If the repository doesn't ignore `.tmp/`, add it to the file `git rev-parse --git-path info/exclude` names. Never write them to `/tmp`, beside the checkout, elsewhere in it, or in a directory other agents share, such as a session scratchpad. @@ -191,6 +192,9 @@ Pass PR bodies to `gh` on stdin (`--body-file -`). Before ending a task, pausing for a decision, or handing off, commit a checkpoint of the source changes, and report what remains and which checks passed or did not run. Finish with a clean checkout: intended changes committed and pushed, incidental generated changes restored, and pre-existing or unrelated changes preserved. +Run expensive builds and test suites through `quest gate `, which waits until the host has room for them; never poll the load average or cap agents by core count yourself. +Run no more sub-agents at once than the harness allows; queue the rest and start one as each reports. + Wait on a PR's CI or reviews with `quest wait`, and on other background work with a blocking command that ends on its terminal state, not timed polls. Bound each wait under an hour so the prompt cache stays warm, and re-run it on timeout. A sub-agent ends its turn only with a final result or a question, never with background work still running. diff --git a/assets/skills/complete.md b/assets/skills/complete.md index c80aee91..81cb439c 100644 --- a/assets/skills/complete.md +++ b/assets/skills/complete.md @@ -32,7 +32,6 @@ Run each `/quest-ready`, `/quest-merge`, or `/quest-iterate` in its own sub-agen Each sub-agent blocks on its own waits and reports back only when done or blocked. For GitHub CI, review, or merge activity, it uses one `quest wait` and resumes with the returned cursor as described by `quest skill merge`, rather than polling GitHub. -Limit the number of active agents to the CPU core count. Merge sub-agents report once their PR is landing; do not watch the queue or wait for merges. An open PR that left the queue unmerged shows why under `landing-stopped` in `quest status `. diff --git a/assets/skills/spawn.md b/assets/skills/spawn.md index b0284061..98bb15bc 100644 --- a/assets/skills/spawn.md +++ b/assets/skills/spawn.md @@ -28,7 +28,6 @@ Present those one at a time: a short paragraph explaining the problem, the quest Start each quest in a background sub-agent with its own isolated worktree, since agents cannot write to a worktree their parent created. Each agent reports back only when done or blocked. -Limit the number of active agents to the physical CPU core count, or the harness's concurrent sub-agent limit if lower; queue the rest and start one as each reports. When done, each agent's claim PR holds its work, still a draft if decisions or unfinished work remain. Its report lists every open decision with a recommendation. diff --git a/quest/m0/README.md b/quest/m0/README.md index 3f8be31e..d6093cbc 100644 --- a/quest/m0/README.md +++ b/quest/m0/README.md @@ -21,9 +21,13 @@ product without changing the core's independence. Decided while planning m0 (2026-09-26), replacing the earlier copied-files and ownership-manifest design: -- Nothing is vendored. The binary carries the skills and the quest contract; - a repository gets static one-line skill stubs and one reference line in its - root instructions. Upgrading never rewrites repository files. +- The binary carries the skills, the quest contract, and all hook logic. + `quest init` installs only static stubs into a repository: one-line skill + stubs, one reference line in its root instructions, one `.gitattributes` + line, and Claude hook entries in `.claude/settings.json` that only call a + `quest` subcommand. Upgrading never rewrites repository files. (Amended + 2026-10-26 (user), replacing "Nothing is vendored", so `quest init` can + install the agent lifecycle hooks.) - The repository's own tool manager pins the version: mise (release binaries) or a nix flake input (any rev, built from source). Quest ships no launcher and no pin file; an install outside either is simply unpinned. diff --git a/quest/m0/helpers/README.md b/quest/m0/helpers/README.md index 5e26f6d5..88b38642 100644 --- a/quest/m0/helpers/README.md +++ b/quest/m0/helpers/README.md @@ -73,4 +73,4 @@ commands from Sep-Oct. Session counts in each child come from that window. ## Related -- [Agent lifecycle integration](/quest/m0/worktree-agents.md) - removes the agent-level load-average rules +- [Agent lifecycle integration](/quest/m0/worktree-agents.md) - reclaims finished and suspended agent checkouts through their harness diff --git a/quest/m0/helpers/headless-agents.md b/quest/m0/helpers/headless-agents.md index b2d44a46..e6d3d12b 100644 --- a/quest/m0/helpers/headless-agents.md +++ b/quest/m0/helpers/headless-agents.md @@ -40,10 +40,9 @@ every user would have to add it. supply its own `claude.exe` and receive the key), and launch npm `.cmd` shims, which `spawn` cannot run without a shell. Then run the fake-CLI tests on the native Windows jobs. -- The command does no load or CPU admission. The skill keeps holding launches - as it does for sub-agents, until agent lifecycle integration removes those - rules. +- The command does no load or CPU admission, and the skill no longer caps + agents: the guide routes their expensive commands through `quest gate`. ## Related -- [Agent lifecycle integration](/quest/m0/worktree-agents.md) - removes the skill's load-average launch rules, so neither the skill nor the command polls load +- [Agent lifecycle integration](/quest/m0/worktree-agents.md) - reclaims the checkouts of finished and suspended agents, including headless ones diff --git a/quest/m0/worktree-agents.md b/quest/m0/worktree-agents.md index a568f8ff..023c18d2 100644 --- a/quest/m0/worktree-agents.md +++ b/quest/m0/worktree-agents.md @@ -1,4 +1,4 @@ -# [M] Release agent checkouts at handoffs and completion +# [L] Release agent checkouts at handoffs and completion ## Goal @@ -9,34 +9,92 @@ merge. ## Plan +Remaining work: + +- Claude hooks: a `quest` subcommand (for example `quest worktree hook + `) handles `WorktreeCreate` and `WorktreeRemove` through `quest + worktree create` and `remove`, releases the stopped subagent's checkout on + `SubagentStop`, and restores it on `SubagentStart`. `/quest-spawn` cleanup + calls `quest worktree remove`, since Claude never removes a hook-created + subagent worktree. +- `quest init` adds the static hook entries to `.claude/settings.json`, + merging into an existing file, and `quest uninstall` removes exactly those + entries. +- Derived defaults for a checkout the hook creates, which gets only a `name`. +- Codex through `quest agent` running the harness inside `quest worktree run`. +- Exercise both harnesses with a finished worker under a still-live parent, + a suspended decision, a crash, and a restored session. Confirm live that + `SubagentStop`'s `cwd` is the subagent's worktree, and that a hook-created + worktree passes Claude's isolation identity check. Reconcile existing + cleanup mechanisms instead of adding an unrelated competing sweeper. Run + these from a session that is not itself worktree-isolated: Claude's + isolation checks refuse git in any other repository, including a scratch + test repository. + +Decisions: + - Decided 2026-10-15: use `quest worktree` for checkout lifetime and `quest gate` - for expensive phases. Remove the skill's physical-core agent-count and load - average admission rules once command admission is integrated. Disk capacity - gates checkout allocation, not the number of reasoning agents. + for expensive phases. Disk capacity gates checkout allocation, not the number + of reasoning agents. +- Decided 2026-10-26 (user): Claude integrates through a + `WorktreeCreate`/`WorktreeRemove` hook pair backed by `quest worktree`, with + `SubagentStop` releasing and `SubagentStart` restoring. It matches the + ownership model, and native cleanup does not reclaim finished workers. The + accepted cost: the hook replaces every Claude worktree in the repository. + Rejected: pruning build output in place on `SubagentStop`, and prose alone. +- Decided 2026-10-26 (user): the hooks live in the repository's + `.claude/settings.json`, written by `quest init`, not in user settings. The + entries are static stubs that only call a `quest` subcommand, with all logic + in the binary like the skill stubs, so upgrades never rewrite them. The m0 + Plan's vendoring bullet was amended to allow this. +- Decided 2026-10-26 (user): a hook-created checkout derives its defaults. + Scratch is the main checkout's top-level ignored entries, excluding + `.worktrees/`, `.claude/worktrees/`, and nested repositories. The reserve is + the main checkout's disk usage. An unset `capacity` admits whatever the + free-space check admits, instead of refusing everything. +- Decided 2026-10-26 (user): Codex, which documents no worktree hooks, is + covered by `quest agent` running it inside `quest worktree run`, which + releases on exit and restores on resume. Codex app threads stay on Codex's + native archive. +- Decided 2026-10-26 (user): agents are capped only at the harness's + concurrent sub-agent limit, stated once in the guide; the core-count cap is + gone, since `quest gate` holds expensive commands. The 2026-10-15 decision + stands over [kixelated/quest#227](https://github.com/kixelated/quest/pull/227)'s + wording, which kept the core count only incidentally. + +Context: + - Landed: `quest worktree run` supervises a job and releases its scratch, `remove` deletes a finished checkout without losing work (a squash-merged head counts only with exact PR-head evidence), and `stop` ends a crashed - supervisor's leftover processes. -- A 2026-10-19 transcript audit counted 1,731 load-average polling commands - in moq-dev/moq and moq-dev/moq.pro sessions since Oct 14, so the remaining - agent-level load rules still cost tokens until this lands. + supervisor's leftover processes. The guide's Workspace section asks for a + checkpoint before a decision or handoff and a clean checkout at the end + ([kixelated/quest#223](https://github.com/kixelated/quest/pull/223)), routes + expensive commands through `quest gate`, keeps read-only discovery out of + new checkouts, and caps sub-agents only at the harness's own limit. +- Measured: this repository's main checkout held 65 Claude subagent worktrees + under `.claude/worktrees/` (8.2 GB) on 2026-10-23, and still 20 (6.5 GB) on + 2026-10-26 after manual cleanup, the oldest from 2026-10-07. Finished workers + are not reclaimed today. - A foreground CLI wrapper only owns its child commands. Native agent tools need explicit ownership and suspend/resume integration; a helper that exits after creating a directory cannot infer when such an agent has finished. - Reuse native worktree/archive APIs where they preserve the required state. Test actual completion, not merely an accepted or queued archive request. Recover failed archives and stale ownership without bypassing active locks. -- Do read-only discovery without allocating a new checkout when existing - context suffices. Reuse suitable owned checkouts for active work. -- Update shared workflow guidance to checkpoint meaningful source before a - blocking decision or completed handoff, recording unresolved work and check - results. Exclude disposable scratch and preserve source on cancellation. -- Exercise both harnesses with a finished worker under a still-live parent, - a suspended decision, a crash, and a restored session. Reconcile existing - cleanup mechanisms instead of adding an unrelated competing sweeper. -- Current Claude docs exclude hook-created subagent worktrees from automatic - removal and its retention sweep. Codex can archive recoverably but refuses - unsupported nested repositories. Integrate their actual supported lifecycle. +- Claude: a `WorktreeCreate` hook replaces every worktree Claude creates in the + repository (`--worktree`, `EnterWorktree`, subagent isolation, background and + remote-control sessions) and prints the path; `.worktreeinclude` is then not + processed. Claude never removes a hook-created subagent or workflow worktree + and never runs `WorktreeRemove` for one; it runs `WorktreeRemove` only for + session exits, `ExitWorktree`, background-session deletes, and remote-control + cleanup. `SubagentStop` fires when a subagent finishes responding, which + covers both completion and a suspended decision, and `SubagentStart` fires on + resume; their `cwd` follows the agent. Without a hook, Claude removes a clean + subagent worktree only when it finishes with no changes and otherwise leaves + it to the `cleanupPeriodDays` sweep. +- Codex can archive recoverably but refuses unsupported nested repositories, + and keeps its 15 most recent managed worktrees by default. Sources: [Claude worktrees](https://code.claude.com/docs/en/worktrees), [Claude removal hooks](https://code.claude.com/docs/en/hooks#worktreeremove), [Codex worktrees](https://learn.chatgpt.com/docs/environments/git-worktrees).