🤖 Align Igor with the lean build cycle

Adds the attack-the-plan step and per-phase review to the development
cycle, the fix-pass stop rule, Athanor resume between phases, and the
alias-over-pin model rule. Drops the stale 4.6-for-implementation
guidance and per-task review convention. Harness notes now point to the
implementation skill's spawning reference.
This commit is contained in:
2026-10-05 22:12:31 +02:00
parent e51520723c
commit 146a48c343
4 changed files with 26 additions and 27 deletions
+2 -2
View File
@@ -17,7 +17,7 @@ Replaces `g4b_ai`.
| `workpad` | Document placement — reports, plans, goals, brainstorms, designs, journals, research, specs. | | `workpad` | Document placement — reports, plans, goals, brainstorms, designs, journals, research, specs. |
| `research-tree` | Multi-topic research as a dependency tree of parallel phases. | | `research-tree` | Multi-topic research as a dependency tree of parallel phases. |
| `research` | Research governance — bounded agent spawning, web fetch budgets. | | `research` | Research governance — bounded agent spawning, web fetch budgets. |
| `implementation` | Implementation orchestration — sequencing, delegation, verification. | | `implementation` | Lean implementation — attack the plan against the code, build in phases, one review per phase. |
| `svg` | SVG diagram placement and referencing in markdown. | | `svg` | SVG diagram placement and referencing in markdown. |
### Agents ### Agents
@@ -26,7 +26,7 @@ Replaces `g4b_ai`.
|-------|------| |-------|------|
| `igor` | Session coordinator (loaded by the igor skill). | | `igor` | Session coordinator (loaded by the igor skill). |
| `adept` | Domain-scoped knowledge agent. Long-lived within a session, accumulates journals. | | `adept` | Domain-scoped knowledge agent. Long-lived within a session, accumulates journals. |
| `athanor` | Dispatching orchestrator — the slow furnace. "Put it in the oven." | | `athanor` | Build furnace (Opus 5.5) — builds a reshaped plan one phase per turn. "Put it in the oven." |
| `researcher` | Deep research. Reads, synthesizes, writes reports. No sub-agents. | | `researcher` | Deep research. Reads, synthesizes, writes reports. No sub-agents. |
| `search` | Read-only code/file lookup. | | `search` | Read-only code/file lookup. |
| `scout` | Lightweight fact extraction. Fast and cheap. | | `scout` | Lightweight fact extraction. Fast and cheap. |
+11 -11
View File
@@ -82,30 +82,30 @@ Pick the tier by task type (details in `references/model-tiers.md`). Prefer proj
| Complex summaries, git fixes, small code changes | Sonnet subagent | `model: "sonnet"` (needs write access) | | Complex summaries, git fixes, small code changes | Sonnet subagent | `model: "sonnet"` (needs write access) |
| Test runs, compiles, commits, linear-data summaries | Haiku subagent | `model: "haiku"` (needs Bash access) | | Test runs, compiles, commits, linear-data summaries | Haiku subagent | `model: "haiku"` (needs Bash access) |
| Domain knowledge, repeated consultation on a subsystem | `adept` agent (long-lived, domain-scoped) | `subagent_type: "adept"`, `model: "opus"` | | Domain knowledge, repeated consultation on a subsystem | `adept` agent (long-lived, domain-scoped) | `subagent_type: "adept"`, `model: "opus"` |
| Large multi-part jobs needing their own subagent fan-out | `athanor` | `subagent_type: "athanor"` | | Building a reshaped plan; large multi-part jobs needing their own subagent fan-out | `athanor` | `subagent_type: "athanor"`, `model` omitted (pinned to Opus 5.5) |
The `athanor` is the forge — your heavy lifter. An Opus-tier agent that may use the Agent (Task) tool itself and runs its own subagents. Load it with a brief (scope, output paths, completion criteria), close the door, and let it cook. Don't hand it step-by-step instructions; it decomposes the work itself. The `athanor` is the forge — your heavy lifter. A build furnace pinned to Opus 5.5 that may use the Agent (Task) tool itself and runs its own subagents. Load it with the reshaped build plan (for non-build jobs: a brief with scope, output paths, completion criteria), close the door, and let it cook. It builds one phase per turn and hands back.
**Model must be explicit.** Always pass `model` on `Agent` calls (`"opus"`, `"sonnet"`, `"haiku"`) — omitting it inherits the coordinator's model, which may be Fable. Subagents are Opus or lower; never dispatch a Fable-tier subagent unless the user explicitly asks. **Model must be explicit — and deliberate.** The per-call `model` is an alias and it overrides an agent's pinned model: `model: "opus"` gives the agent the Opus that alias resolves to, not its pin (a 4.6 Igor passing `opus` got a 4.6 Athanor). So: for agents pinned in their frontmatter (e.g. athanor) omit `model` unless you deliberately override the pin; for unpinned agents (general-purpose) always pass `model` (`"opus"`, `"sonnet"`, `"haiku"`), since omitting it inherits your model, which may be Fable. Note the choice in the journal, and have the agent stamp the model id it ran on. Subagents are Opus or lower; never dispatch a Fable-tier subagent unless the user explicitly asks. Model traits: the implementation skill's `references/models.md`.
## Development Cycle ## Development Cycle
Igor routes work through six stages. Not every task enters the cycle — one-off fixes, ad-hoc questions, and maintenance stay outside it. The line: if writing the plan would take longer than doing the work, it is not in the cycle. Igor routes work through six stages. Not every task enters the cycle — one-off fixes, ad-hoc questions, and maintenance stay outside it. The line: if writing the plan would take longer than doing the work, it is not in the cycle.
**Stages:** (1) Brainstorm — Igor with user or Pinky; skip when direction is clear. (2) Research — researcher/adept answers open questions. (3) Design — independent Opus agent produces one buildable approach. (4) Plan — independent Opus agent (never the designer) produces steps with completion criteria. (5) Implement — the Athanor receives the plan; code comes out. (6) Review — fresh Opus reviewer measures output against plan and design. **Stages:** (1) Brainstorm — Igor with user or Pinky; skip when direction is clear. (2) Research — researcher/adept answers open questions. (3) Design — independent Opus agent produces one buildable approach. (4) Plan — independent Opus 5.5 agent (never the designer) produces steps with completion criteria. (4b) Attack the plan — Igor dispatches a fresh Opus 5.5 agent (never the planner) that tests the plan adversarially against the code (blockers, design errors, missed consumers of changed semantics), then reshapes it into a build plan: phases that end testable, blocks one owner can finish. One step. It is what pays for dropping per-task review. Show the user the build plan and its open decisions before the door closes. (5) Build — the Athanor builds one phase per turn: blocks, a cheap gate between them, tests once, a run log. (6) Phase review — Igor dispatches a fresh Opus 5.5 reviewer per phase, without the attack's risk list as its scope; it answers every handoff flag, hunts weakened checks and tests that cannot fail, and stamps its model id. Details in `spire:implementation`.
**Separation rule:** Plans and designs are always written by independent agents. The author of a plan never implements it; the author of a design never plans from it. Separation keeps review honest. **Separation rule:** Plans and designs are always written by independent agents. The author of a plan never implements it or attacks it; the author of a design never plans from it; the builder never reviews its own phase. Separation keeps review honest.
**Review decision tree:** Igor routes the outcome: **Review decision tree:** Igor routes the outcome:
1. None or low findings only — done. Lows stay in the report; never loop for lows. 1. No Critical or Important findings — the phase is done. Minors are fixed in a fix pass if one runs, otherwise logged; never loop for minors.
2. Any medium or high — collect findings into a new plan (stage 4). The normal short loop. 2. Critical or Important — one fix pass (resume the Athanor), then a fresh reviewer re-checks only those findings. Then stop and go to the next phase. Findings too large for a fix pass go into a new plan (stage 4).
3. Approach is wrong, not the code — back to design (stage 3). Append a dated amendment. 3. Approach is wrong, not the code — back to design (stage 3). Append a dated amendment.
4. Unresearched unknown surfaced — back to research (stage 2). Only for a genuinely new problem space. 4. Unresearched unknown surfaced — back to research (stage 2). Only for a genuinely new problem space.
5. Goal is wrong — stop. User's call. 5. Goal is wrong — stop. User's call.
Default to the shortest loop that fits; long loops need a stated reason. Default to the shortest loop that fits; long loops and extra reviews (e.g. a mid-phase hotspot review) need a stated reason.
**Athanor queuing:** Plans enter sequentially; Igor holds the queue. A new plan arriving mid-run waits — the door is closed. If a new plan invalidates the one cooking, Igor stops the run (`TaskStop`), shelves partial output, and dispatches the replacement. Parallel Athanors only for disjoint code in separate worktrees; default is one. **Athanor queuing:** Plans enter sequentially; Igor holds the queue. A new plan arriving mid-run waits — the door is closed. If a new plan invalidates the one cooking, Igor stops the run (`TaskStop`), shelves partial output, and dispatches the replacement. Parallel Athanors only for disjoint code in separate worktrees; default is one. Between phases, and for the fix pass, Igor resumes the same Athanor with `SendMessage` (safe from the root). When its context looks spent, Igor starts a fresh Athanor from the run log and trunk notes instead.
**Cycle and workpad:** Each stage writes to its folder; moving forward creates a new file, never mutates the previous one. The folder trail is the record. **Cycle and workpad:** Each stage writes to its folder; moving forward creates a new file, never mutates the previous one. The folder trail is the record.
@@ -170,10 +170,10 @@ Roster matching uses the gravity-well rule: pick the slug that fits most strictl
- **Journal.** Keep the session journal append-only and current: what was dispatched, what came back, decisions, course corrections. - **Journal.** Keep the session journal append-only and current: what was dispatched, what came back, decisions, course corrections.
- **A "no" is a lull, not a stop.** When you offer a follow-up and the user declines ("no," "nah," "I'm good"), that pause is the cheapest moment to bring the journal current — do it then. Then close the beat with one line: a short acknowledgment, or the next natural thread if one exists. Don't stop dead; silence reads as a crash. - **A "no" is a lull, not a stop.** When you offer a follow-up and the user declines ("no," "nah," "I'm good"), that pause is the cheapest moment to bring the journal current — do it then. Then close the beat with one line: a short acknowledgment, or the next natural thread if one exists. Don't stop dead; silence reads as a crash.
- **Talk to the user directly, keep details in files.** Questions and decisions go to the user conversationally and concisely; long-form material lives in the workpad. - **Talk to the user directly, keep details in files.** Questions and decisions go to the user conversationally and concisely; long-form material lives in the workpad.
- **User conventions.** Subagent-driven execution with review between tasks. Push branches, never open pull requests. - **User conventions.** Lean build: attack the plan before building, review once per phase, one fix pass, then stop (see `spire:implementation`). Push branches, never open pull requests.
- **Goals.** As Igor you may write files in the workpad `goals/` folder on the user's behalf — capture their objective in agent-interpretable form. Goals are otherwise user-owned: only the user deletes them, and dispatched agents (including athanor) treat `goals/` as read-only. - **Goals.** As Igor you may write files in the workpad `goals/` folder on the user's behalf — capture their objective in agent-interpretable form. Goals are otherwise user-owned: only the user deletes them, and dispatched agents (including athanor) treat `goals/` as read-only.
- **Prefer working on main.** Most sessions only touch markdown (workpad files, docs) — do that directly on `main`, no worktree. Create a worktree branch only when the work really requires isolation (a code implementation run, especially alongside another one in flight) or the user asks for one. - **Prefer working on main.** Most sessions only touch markdown (workpad files, docs) — do that directly on `main`, no worktree. Create a worktree branch only when the work really requires isolation (a code implementation run, especially alongside another one in flight) or the user asks for one.
- **Notifications report a turn ending, not a job finishing.** Read the `<result>` before concluding anything; check `ListAgents` before resuming. Full mechanics in `references/harness-notes.md`. - **Notifications report a turn ending, not a job finishing.** Read the `<result>` before concluding anything; check `ListAgents` before resuming. Full mechanics in the implementation skill's `references/spawning-claude-code.md`.
- **Leaf tasks must say "do this yourself; do not dispatch further agents."** Only `athanor` is meant to fan out. - **Leaf tasks must say "do this yourself; do not dispatch further agents."** Only `athanor` is meant to fan out.
## Session lifecycle ## Session lifecycle
@@ -1,15 +1,12 @@
# Task Notification Mechanics # Harness notes (moved)
A `<task-notification>` with `status: completed` fires whenever a dispatched agent yields with no live background children *of its own*. An agent that sub-delegates to a background child and then yields will notify `completed` immediately — before any deliverable exists. The harness mechanics that lived here (task notifications, background grandchildren, `ListAgents`, `TaskStop`, `TaskOutput`, leaf briefs) moved on 2026-10-05 to the implementation skill's reference, together with resume, fork and model-pin behaviour:
## Rules `plugins/spire/skills/implementation/references/spawning-claude-code.md`
- Before concluding "the agent stopped/failed," **read the `<result>` text**. A result that announces a hand-off ("I've dispatched...", "running in the background") + a missing artifact = a background child is still working. **Wait for its notification; do not resume-and-redo.** The short version for Igor:
- Background children flatten to the session root: each grandchild sends its *own* later notification with a *different* `task-id`. Expect N+1 notifications when sub-delegation happened.
- The same `task-id` may notify more than once (each is one turn). Key your bookkeeping on the deliverable, not the notification count.
- When unsure whether work is still in flight, call `ListAgents` before acting. Background grandchildren appear there as flat, top-level subagents of your session with status `running`. If a child is alive and writing your output path, **do not** `SendMessage`-resume the parent — that starts a second writer racing the first. `TaskStop` the child first only if you mean to abandon it.
- `TaskList` is the todo-list tool, unrelated to agents. `TaskOutput` on an agent dumps its whole transcript into your context — never use it for agents. `ListAgents` is the only agent-liveness check.
## Leaf tasks - A notification reports a turn ending, not a job finishing. Read the `<result>` text; check `ListAgents` before resuming.
- Background grandchildren notify you, the root. If a child is still writing an output path, do not resume its parent.
When you dispatch a single self-contained task (read these files, write this one report), the prompt MUST say "do this work yourself; do not dispatch further agents." A `general-purpose` agent has the Agent tool and will hand off if the prompt reads like an orchestration brief. Only `athanor` is *meant* to fan out — route multi-part jobs there instead of hoping a leaf agent stays a leaf. - Resuming via `SendMessage` is safe from you (the root), not from inside a subagent.
- Leaf briefs say "do this yourself; do not dispatch further agents."
@@ -9,7 +9,7 @@ Prefer a project-pinned agent from `.claude/agents/` when one matches the task;
| Quick fact extraction, version/config lookup | Haiku lookup | `"scout"` | Fast, cheap, read-only; at most 2 web pages | | Quick fact extraction, version/config lookup | Haiku lookup | `"scout"` | Fast, cheap, read-only; at most 2 web pages |
| Code/file lookups, symbol tracing | Sonnet search | `"search"` | Read-only; targeted "where is X" lookups | | Code/file lookups, symbol tracing | Sonnet search | `"search"` | Read-only; targeted "where is X" lookups |
| Planned implementation | implementer agent | project-pinned or omit (defaults to general-purpose) | Executes plans, verifies with the project's check/test commands | | Planned implementation | implementer agent | project-pinned or omit (defaults to general-purpose) | Executes plans, verifies with the project's check/test commands |
| Multi-part jobs needing their own subagent fan-out | `athanor` (Opus-tier, may use Agent/Task tool) | `"athanor"` | Decomposes a brief and runs its own subagents | | Building a reshaped plan; multi-part jobs needing their own subagent fan-out | `athanor` (pinned to Opus 5.5, may use Agent/Task tool) | `"athanor"`, omit `model` | Builds one phase per turn; also takes non-build fan-out briefs |
| Complex summaries, git fixes, small code changes | Sonnet subagent | omit (defaults to general-purpose) | Capability/speed balance; needs write access | | Complex summaries, git fixes, small code changes | Sonnet subagent | omit (defaults to general-purpose) | Capability/speed balance; needs write access |
| Test runs, compiles, commits, linear-data summaries | Haiku subagent | omit (defaults to general-purpose) | Fast, cheap, mechanical; needs Bash and possibly write access | | Test runs, compiles, commits, linear-data summaries | Haiku subagent | omit (defaults to general-purpose) | Fast, cheap, mechanical; needs Bash and possibly write access |
@@ -31,7 +31,9 @@ Sub-delegation guard:
Model selection rules: Model selection rules:
- **Never dispatch a Fable-tier subagent unless the user explicitly asks.** Always pass `model` explicitly on `Agent` calls (`"opus"`, `"sonnet"`, `"haiku"`) — omitting it inherits the coordinator's model, which may be Fable. Subagents are Opus or lower. - **Never dispatch a Fable-tier subagent unless the user explicitly asks.** Subagents are Opus or lower.
- **Prefer Opus 4.6 for implementation and detail-precise lookups; Opus 5 only for reviews.** Pinned implementer/researcher agents should be Opus 4.6. `subagent_type: "general-purpose"` + `model: "opus"` resolves to Opus 5, which tends to hallucinate — use it for review/critique-style tasks only. - **Unpinned agents get an explicit `model`** (`"opus"`, `"sonnet"`, `"haiku"`) — omitting it inherits the coordinator's model, which may be Fable.
- **Pinned agents get no `model`** unless you deliberately override the pin. The per-call alias overrides the frontmatter pin. Note the choice and have the agent stamp the model id it ran on.
- **Model traits** (which model is good at what, context guesstimates) live in the implementation skill's `references/models.md`, as dated observations. Defaults as of 2026-10-05: Opus 5.5 for the Athanor, planning, attacking plans and review.
This table can grow — add new agents and heuristics here as they prove out. This table can grow — add new agents and heuristics here as they prove out.