diff --git a/AGENTS.md b/AGENTS.md index 6c467df..da41e5a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,6 +13,24 @@ at the same time a Claude Code plugin, an Agent Plugins 1.0 plugin and a Codex plugin; all three launch the same server with `uv run`. Both its users and its maintainers are LLM agents inside harnesses; design for them first. +## Execution model + +Work here is run by a lead that delegates first. The lead holds the architecture, +the specs and the merges; implementers take bounded, file-disjoint leaves in their +own worktrees, on the cheapest tier that finishes a leaf with the gates green. +Two currencies decide who does what. **Tokens**: the lead runs on the most capable +tier and everything it reads or edits itself stays in its context, re-sent on every +later turn of the cycle; an implementer's tokens are spent once, on a cheaper tier, +in a context discarded after its report. **Latency**: parallel leaves cost the +slowest leaf rather than the sum, but each dispatch carries a fixed overhead (the +brief, then the implementer's cold read of this file, its leaf and the cited +reports) that measured leaves place at 4–15 minutes (`KT-C`, `KT-D`). So delegation +is the default, and not stubborn: a leaf the lead finishes faster than it can brief +(scaffold, shared helpers, CI, this file, changelog) stays with the lead. Whatever +the harness offers for parallel workers instantiates this; with nothing, the lead +runs the same roadmap sequentially under the same discipline. Load the +`campaign-lead` dev skill before deciding a task is too small for it. + ## Load the dev plugin ```bash @@ -26,7 +44,7 @@ claude plugin install colgrep-mcp-dev@colgrep-mcp # from the repo's marketpla | Skill | Load it when | |:--|:--| | `maintainer-policy` | you are about to add scaffold, CI, hooks, docs or a "best practice"; review or refactor server code; choose between `perf` and `refactor`; write a docstring | -| `campaign-lead` | you lead, plan or dispatch multi-agent work here: architecture report, roadmap, worktrees, reviewer pass, closing a cycle | +| `campaign-lead` | a task has, or might have, more than one lead-sized leaf — decide that inside the skill, not before it: architecture report, roadmap, worktrees, dispatch, reviewer pass, closing a cycle | | `landing-and-release` | you commit, rebase, merge, open or land a PR, resolve a conflict, cut a release, or `cz check` rejects you | | `stack-traps` | you run `colgrep` by hand, touch a handler or a manifest, debug a plugin that does not connect, read a Windows CI failure, or `claude -p` fails | diff --git a/dev/evals/campaign-lead-triggers/case.yaml b/dev/evals/campaign-lead-triggers/case.yaml index 38ff4cf..edc6e23 100644 --- a/dev/evals/campaign-lead-triggers/case.yaml +++ b/dev/evals/campaign-lead-triggers/case.yaml @@ -9,7 +9,7 @@ execution: allowed_tools: [Read, Glob, Skill] prompt: | We just merged the knowledge-transfer report for the consistency campaign. Time to run - the next cycle on this repo with three Sonnet implementers working in parallel worktrees; + the next cycle on this repo with three implementers working in parallel worktrees; here are the follow-ups from that retrospective to turn into roadmap leaves. Set it up and get them dispatched. graders: diff --git a/dev/skills/campaign-lead/SKILL.md b/dev/skills/campaign-lead/SKILL.md index e379937..3bd1710 100644 --- a/dev/skills/campaign-lead/SKILL.md +++ b/dev/skills/campaign-lead/SKILL.md @@ -1,6 +1,6 @@ --- name: campaign-lead -description: "Guides a lead through running a multi-agent campaign on this repository: writing the architecture report, building the roadmap, creating worktrees by hand, dispatching implementers, merging per level, running a read-only reviewer, and closing with a knowledge-transfer report. Load this whenever asked to lead, coordinate, plan, or dispatch work on this repo, to create a roadmap or worktrees for subagents, to review a merged roadmap level, or to close out a campaign cycle — even if the request never says 'skill'." +description: "Guides a lead through running a multi-agent campaign on this repository: deciding what to delegate and what to keep, writing the architecture report, building the roadmap, creating worktrees by hand, dispatching implementers, merging per level, running a read-only reviewer, and closing with a knowledge-transfer report. Load this whenever asked to lead, coordinate, plan, or dispatch work on this repo, before deciding a task is too small to delegate, to create a roadmap or worktrees for implementers, to review a merged roadmap level, or to close out a campaign cycle — even if the request never says 'skill'." --- # Campaign Lead @@ -9,6 +9,21 @@ Composes with the machine-level `writing-reports`, `managing-roadmaps` and `writ skills for mechanics; this skill is the order of operations and the rules this repository's campaigns established, each cited to the retrospective that records it (`AGENTS.md` legend). +## The Default: Delegate First + +`AGENTS.md` §Execution model states the contract; this section is how the lead applies it. +Every task that touches more than one file-disjoint leaf is a campaign, and every leaf goes to +an implementer unless the exception below applies. The lead's own context is the expensive +currency — it runs on the most capable tier and re-reads everything it touched on every later +turn — and wall-clock is the other: implementers run in parallel, so a level costs its slowest +leaf, while a dispatch carries a fixed overhead of the brief plus the implementer's cold read +of `AGENTS.md`, its leaf and the cited reports. Measured leaves ran 4–15 minutes each on the +cheaper tier (KT-C §Wins, KT-D §Wins); below that floor the lead is faster than its own brief. +Run implementers on the cheapest tier that clears the gates for leaves of that size; when one +leaf fails there, escalate that leaf, not the round. The harness instantiates the mechanism — +whatever it offers for parallel workers, in worktrees the lead created; with none, run the same +roadmap sequentially under the same discipline, and say so in the retrospective. + ## Order of Operations 1. **Architecture report first** — contracts, file ownership per leaf, risks — under @@ -20,9 +35,10 @@ campaigns established, each cited to the retrospective that records it (`AGENTS. not-yet-shared helper duplicates it, and two duplicates collide at merge (KT-B §Wins, KT-C §Wins: helpers before dispatch → zero conflicts). 4. **One worktree per leaf, created by hand**: `git worktree add -b task/ - `. Never rely on the Agent tool's `isolation: worktree` for this — it - branches from the primary checkout's `main`, not the campaign branch, and a whole dispatch - round lands on the wrong base (KT-H §Pain Points, KT-B §Root Causes). + `. Never let the harness create it — a harness convenience branches from + whatever it considers the default base, not the campaign branch, and a whole dispatch round + lands on the wrong base (KT-H §Pain Points, KT-B §Root Causes; the Claude Code instance of + this trap is `stack-traps` `references/claude-code.md#agent-worktree`). 5. **Dispatch** with `references/dispatch-prompt.md`. Every prompt states "stop if the leaf file is missing from your worktree" — it turns a wrong-base worktree into a ~15-second no-op with zero stray commits instead of wasted work (KT-H §Wins). @@ -43,9 +59,11 @@ campaigns established, each cited to the retrospective that records it (`AGENTS. is what closes a campaign with zero merge conflicts (KT-H, KT-C §Wins). - **Hard stop time**, stated in both the leaf and the dispatch prompt: the lead merges whatever is green at the stop (`consistency` roadmap README §Gotchas). -- **Do lead-sized leaves yourself.** Scaffolding, shared helpers, CI wiring, `AGENTS.md`, - changelog fixes: delegating them costs a dispatch round-trip for work the lead finishes in - minutes (KT-C, KT-H §Wins). +- **The exception to the default: do lead-sized leaves yourself.** Scaffolding, shared + helpers, CI wiring, `AGENTS.md`, changelog fixes: delegating them costs a dispatch round-trip + for work the lead finishes in minutes (`adapter_hygiene` took 4; KT-C, KT-H §Wins). The + exception is per leaf, never per cycle — a cycle with no dispatch at all needs the + retrospective to say why. - **Refactor leaves need an explicit dump-and-diff oracle**, not "tests still pass": dump `Client.list_tools()`/`list_resources()`/`list_resource_templates()`/`list_prompts()` JSON on the base and the branch, diff empty. The MCP SDK ships docstrings verbatim, so even @@ -55,8 +73,9 @@ campaigns established, each cited to the retrospective that records it (`AGENTS. - **Windows CI is the only portability oracle here** — read its verdict, don't skim it, whenever a leaf is the first to exercise a previously-untested path, and name that path in the PR body (KT-C §Pain Points, CI). -- **A subagent that says it is "watching CI in the background" has already ended its turn.** - Make it block on `gh run watch --exit-status`, or read the run yourself. +- **An implementer's turn ends with its report.** Anything it says it will do "in the + background" after that never happens; make it block on the run (`gh run watch + --exit-status`) or read the run yourself (`stack-traps` `references/claude-code.md#worker-turn`). - **A drift test that relates two artefacts owned by different leaves is red until both land.** Order the roadmap so the *naming* side lands first (e.g. the `AGENTS.md` skill table before the skill leaves it names), even ahead of BFS order, or every merge in between is red on a diff --git a/dev/skills/campaign-lead/references/dispatch-prompt.md b/dev/skills/campaign-lead/references/dispatch-prompt.md index 7cbf4c7..298daf1 100644 --- a/dev/skills/campaign-lead/references/dispatch-prompt.md +++ b/dev/skills/campaign-lead/references/dispatch-prompt.md @@ -23,6 +23,10 @@ shape to look complete: the lead re-runs and compares rather than trusting a summary. - **Commit rules and hard-stop time** keep the history and the time-box legible across many parallel branches the lead did not watch being written in real time. +- **Tier is the lead's choice, not a template field.** Dispatch on the cheapest tier that has + cleared the gates for leaves of this size (`campaign-lead` §The Default); the final report's + gate-attempt count is the signal to escalate *that leaf* to a stronger tier on the next + round, not to stop delegating. --- @@ -52,6 +56,7 @@ never edit versions by hand; never author a `release(...)` commit. how each fact is cited, size caps, prohibited real-world side effects such as running a real external tool or a live eval>. **Final report** (your last message, plain text): the commits (hash + subject); the exact -output line of each gate; files touched outside your ownership (should be none) or changes you -recommend elsewhere; anything unfinished at the hard stop. +output line of each gate and how many attempts each took to go green; files touched outside +your ownership (should be none) or changes you recommend elsewhere; anything unfinished at the +hard stop. ``` diff --git a/dev/skills/stack-traps/SKILL.md b/dev/skills/stack-traps/SKILL.md index f8dca52..b28f7dc 100644 --- a/dev/skills/stack-traps/SKILL.md +++ b/dev/skills/stack-traps/SKILL.md @@ -28,6 +28,8 @@ linked section, don't re-derive the trap from scratch. | `claude -p` or `claude plugin eval` fails with an OAuth error | claude-code | `references/claude-code.md#oauth` | | `claude --plugin-dir . mcp list` says Connected but your edit is not in the server, or the plugin fails right after a bump | claude-code | `references/claude-code.md#uvx-pin` | | the plugin's hooks don't fire, or still run the old text, after an edit or an update; Codex lists them but never runs them | claude-code | `references/claude-code.md#plugin-hooks` | +| an implementer reports "leaf file missing", or its branch is based on `main` instead of the campaign branch | claude-code | `references/claude-code.md#agent-worktree` | +| a subagent said it was watching CI or would follow up, and nothing happened | claude-code | `references/claude-code.md#worker-turn` | | a Bash command is blocked, including inside a heredoc that only mentions the search pattern | machine | `references/machine.md#shell-hook` | | CI is red only on windows-latest, or only a `setup-uv` step fails | machine | `references/machine.md#windows-ci` | | `git worktree add` on `main` fails because it's checked out elsewhere | machine | `references/machine.md#worktree-main` | @@ -59,7 +61,8 @@ linked section, don't re-derive the trap from scratch. - `references/claude-code.md` — root `.mcp.json` vs plugin-scope `.claude-plugin/mcp.json`, marketplace vs plugin namespaces, `claude -p` on an expired OAuth session, the `uvx colgrep-mcp==` pin, plugin - hooks loading (reload, Codex trust, the portable/Claude-only split). + hooks loading (reload, Codex trust, the portable/Claude-only split), the + Agent tool's worktree base and the end of a subagent's turn. - `references/machine.md` — the plugin's shell-search hook and `COLGREP_BYPASS=1`, Windows CI's two known causes, the detached-worktree trick for `main`, the permission classifier, a venv whose shebangs point at a moved checkout. diff --git a/dev/skills/stack-traps/references/claude-code.md b/dev/skills/stack-traps/references/claude-code.md index 08cf135..3f721b7 100644 --- a/dev/skills/stack-traps/references/claude-code.md +++ b/dev/skills/stack-traps/references/claude-code.md @@ -128,3 +128,37 @@ so `uv run pytest tests/test_hooks.py` is the fastest check. Keep Claude-only events (`WorktreeRemove`) in `hooks/claude-code.json`, never in the portable `hooks/hooks.json` a Codex parser also reads; `test_hooks.py` pins the split. + +## An implementer's worktree is based on `main`, not the campaign branch {#agent-worktree} + +**Symptom**: an implementer dispatched with the Agent tool reports "leaf file +missing" in its first minute, or its commits turn out to sit on a branch cut +from `main` while the roadmap, specs and helpers live on the campaign branch. + +**Cause**: the Agent tool's `isolation: "worktree"` option creates the +worktree from the primary checkout's HEAD — `main` — never from the branch +the lead's session is on. One whole dispatch round landed on the wrong base +this way (`KT-H` §Pain Points, `KT-B` §Root Causes). This is the Claude Code +instance of the harness-neutral rule in `campaign-lead` step 4. + +**What to do**: create every implementer worktree yourself, `git worktree +add -b task/ `, and pass the path in the +dispatch prompt; never set `isolation: "worktree"` from a campaign branch. +Keep the "stop if the leaf file is missing" line in every prompt — it is what +turned the wrong-base round into a 15-second no-op. + +## A subagent said it was watching CI, and nothing happened {#worker-turn} + +**Symptom**: an implementer's final message says it is "watching CI in the +background" or "will follow up when the run finishes"; the run finishes red +or green and nothing follows. + +**Cause**: an Agent-tool subagent's turn ends with its final message; there +is no later execution, so any promise about the future in that message is +never kept. The same holds for any harness whose workers return a single +report (`campaign-lead` §Rules). + +**What to do**: make the implementer block inside its turn — `gh run watch +--exit-status ` — and paste the verdict line into its report, or read +the run yourself after the report. Never treat a worker's "watching" as a +gate result.