keel-execute
Skill0 starsChanged 57 days agoMITView on GitHub
Use when a reviewed plan is ready to implement — orchestrates subagent-driven execution with per-task review and a crash-safe progress ledger, or falls back to inline execution when subagents aren't available. Stage 4 of the keel pipeline; hands off to keel-finish.
In this repository9 other files it gives its agents.
- keel-auditSkill
- security-auditSkill
- keel-debugSkill
- keel-discoverSkill
- keel-finishSkill
- keel-plan-reviewSkill
- keel-planSkill
- keel-wayfindSkill
- keel-workflowSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
23 rules. About 0 are common, 8 are distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈8
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 48
Never start on main/master without explicit user consent — branch first (the rule itself lives in keel-workflow.
- Distinctive: line 58
Continuous execution: do not pause between tasks to ask "should I continue?" — checkpoint questions burn the user's time.
- Very specific: line 61
Glossary: if CONTEXT.md exists at the repo root, include its path in every implementer/reviewer brief — code and test names follow its …
- Very specific: line 64
Code intelligence: if the repo is indexed by CodeGraph (a .codegraph/ directory exists) or the codebase-memory-mcp server is connected, …
- Very specific: line 72
Project rulebook: if the repo has a .learned/ (check once with python3 ~/.claude/skills/learned/scripts/learned.py root), then for every …
- Distinctive: line 95
If the planning-with-files plugin happens to be installed, its hooks add automatic nudges.
- Very specific: line 110
Spec drift check: if the plan header has a Spec Version: field and the spec file it references still exists in the repo, compare the spec …
- Very specific: line 137
Read the dependency graph before dispatching anything: Every task carries a Depends on: line — that is the plan's statement of what must …
- Very specific: line 151
Order: Never dispatch a task whose Depends on: names a task the ledger does not yet record as DONE.
- Very specific: line 184
Staleness rule: before editing, the implementer verifies the task's Files: paths/lines still match reality.
- Very specific: line 257
Not triggered → do not dispatch it.
- Very specific: line 270
Findings go in the ledger, not just the conversation: When the axis runs, its Critical/Important findings and their disposition are written …
- Distinctive: line 298
Evidence gate: every finding quotes the diff/code line that motivates it (file:line + verbatim text).
- Distinctive: line 334
Never loop past round 5 silently hoping the next attempt converges.
- Very specific: line 338
Read the plan's ## Critical flows.
- Very specific: line 340
If yes, run it and compare against Observable result — then record the verdict on the ledger line as flow: <name> — ok or flow: <name> — …
- Very specific: line 374
Do not pass a model override at the call site — each agent file pins its own.
- Distinctive: line 407
Do not override these at the call site.
- Very specific: line 459
After all tasks: dispatch one final whole-branch code-reviewer (no model override — it inherits the strongest available.
- Very specific: line 490
If this plan edited the pipeline's own skill/rule files (this repo, not a consumer repo): run bash eval-fixtures/check-structure.sh and …
- Distinctive: line 533
BEFORE starting, not at task 7.
- Distinctive: line 542
Create a todo per task. Execute in dependency order per step 0, not task-number order: follow each step exactly, run each verification, …
- Distinctive: line 558
Stop and ask rather than guess when: blocked, the plan has a critical gap, an instruction is ambiguous, or a verification keeps failing.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
keel-execute — Plan Execution
INPUT a plan file with a header carrying Spec Version + Global Constraints
+ Success Criteria, and every task carrying Delivers / Files /
Depends on / Interfaces / Skills; if it came from keel-plan-review,
a REVIEW REPORT ending in NO UNRESOLVED DECISIONS
OUTPUT all tasks committed and reviewed on a non-main branch; ledger complete
in .keel/progress.md; final whole-branch review passedMissing INPUT → BLOCKED: 缺 <field> → 退回 keel-plan. A plan without those
fields silently disables brief extraction, the staleness check, and the
spec-compliance axis — three of this stage's four safety mechanisms. An
empty Global Constraints: is the one that hides best: the pre-flight
scan checks tasks against it, so a blank field makes that scan pass on
nothing, and a clean scan reads identically whether the constraints were
satisfied or absent. Blank is a miss, not a permissive default.
Two modes, one decision at the top:
Subagents available AND tasks mostly independent?
├─ yes → ORCHESTRATED mode (default; better context isolation, reviewed per task)
└─ no → INLINE mode (sequential, single context)
Tasks tightly coupled with shared evolving state? → INLINE, or go re-split the planUniversal rules (both modes):
- Never start on main/master without explicit user consent — branch first (the rule itself lives in keel-workflow; this is a reference, not a redefinition).
- Controller context check before ORCHESTRATED mode: past ~100k tokens, write a handoff and fork to a fresh session first. The controller keeps accumulating across the whole stage and will hit mid-stage compaction — the exact failure the ledger exists to survive, not one to walk into.
- Pipeline artifacts are not code. On first creating
.keel/, ensure the repo.gitignorecontains it and commit that separately. Every reviewer diff excludes that path; mixing process artifacts into a task diff makes reviewers grade the wrong thing. - Continuous execution: do not pause between tasks to ask "should I continue?" — checkpoint questions burn the user's time. Stop only at the plan's end or on a genuine blocker.
- Glossary: if
CONTEXT.mdexists at the repo root, include its path in every implementer/reviewer brief — code and test names follow its vocabulary. - Code intelligence: if the repo is indexed by CodeGraph (a
.codegraph/directory exists) or the codebase-memory-mcp server is connected, state that in every implementer/reviewer brief and require its use: implementers query it BEFORE grep/Read to locate symbols, find callers, and see the blast radius of an edit; reviewers use it to check a finding's impact beyond the diff (who else calls the changed code). One query typically replaces a dozen grep/read round-trips. CodeGraph caveat: query in English — Chinese queries silently return empty, not an error. - Project rulebook: if the repo has a
.learned/(check once withpython3 ~/.claude/skills/learned/scripts/learned.py root), then for every task runlearned.py search "<kw>"on the task's Files / Interfaces keywords and append the hits as a Known pitfalls block (<ID>: <title>) to both the implementer brief and every reviewer brief. Implementers treat hits as Global Constraints; reviewers treat each hit as one more checklist line in the form "看到 X → 問 Y". Reviewer findings that match a rule cite its ID. The rulebook is the project's memory of what already went wrong; a brief without it re-discovers the same failures. No.learned/→ note it once in the ledger header and proceed. Use theproject:-labelled hits only.searchalso returns hits from any rulebook the repo mounts, labelled by that rulebook instead; those are cross-project design knowledge, and they are consumed atkeel-discover/keel-plan/keel-plan-review, where the shape is still open. Arriving here they are unusable by construction — the architecture was settled stages ago — so they cost brief length and buy nothing. - Filesystem is memory (absorbed from planning-with-files; the rule is
keel's own and binds with no plugin installed): keep the ledger
.keel/progress.md(what happened) and.keel/findings.md(what was learned) current. After every ~2 exploratory operations, write findings down. Context windows get compacted; files don't. Enforcement is keel's too: the Finish ledger entry carries afindings:line (see Finish), andkeel-finishPart 2e treats its absence as a gap — not a style choice. If the planning-with-files plugin happens to be installed, its hooks add automatic nudges; treat them as a bonus, comply, don't duplicate.
ORCHESTRATED mode
Pre-flight plan review (before Task 1, from superpowers)
One scan of the whole plan before any dispatch, checking for: tasks that contradict each other, tasks that violate the plan's own Global Constraints, and anything the plan mandates that the review rubric (smells.md, repo standards) would flag as a defect. Findings → ONE batched question to the user, each item quoting the plan's text and asking which wins. Clean scan → proceed silently. Cheap once; discovering a plan contradiction at Task 7 is not.
Spec drift check: if the plan header has a Spec Version: field and the
spec file it references still exists in the repo, compare the spec file's
current commit hash/timestamp against the one recorded in the plan header.
Mismatch → the spec body changed after the plan was written; follow
keel-workflow's Backward routes entry for this case (route back to
keel-plan to re-align) instead of starting Task 1. No Spec Version: field,
or the referenced spec file can't be found → skip the check, don't block
(same skip-if-missing spirit as the staleness rule below).
Destructive-operation scan. In the same pass, read every task's
Delivers: and steps for operations that reach outside the repo and cannot
be undone by git: deploys, migrations against a non-ephemeral database,
data deletion, external publication, credential rotation, push or merge to a
protected branch. Each one found is its own G9 question to the user before
Task 1 — naming the exact command and the exact target — even though the
plan already specifies it.
That last clause is the entire point. Every other gate in this stage arbitrates
findings that conflict with the plan; nothing anywhere reviews what the plan
itself instructs. A task reading Delivers: production DB migrated to the new
schema passes G5 (no contradiction), never triggers G6 (no reviewer disagrees
with it), and reaches an implementer whose brief contains no reason to hesitate.
Plan approval is not operation authorization: the user last agreed that the
plan's premises were right, possibly dozens of turns and one context fork ago.
Per task loop
Read the dependency graph before dispatching anything. Every task carries a
Depends on:line — that is the plan's statement of what must finish first — confirmed by the user at G2, or re-examined bykeel-plan-lens-engwhen G2 was skipped because the plan routed throughkeel-plan-review. There is a third provenance and it is weaker than both: akeel-workflowMedium shortcut plan reaches here having had neither, because it never enteredkeel-plan(no Step 6) and never enteredkeel-plan-review(no lens). The edges are present and unconfirmed. Say so once in the ledger header —breakdown: unconfirmed — Medium shortcut, no G2, no eng lens— and hold the graph to a higher bar of suspicion before parallelising on it: an unconfirmed edge that is merely missing costs a serialised run, while an unconfirmed edge that is wrong costs a conflict. It governs three decisions here, and nothing else in this stage can substitute for it:- Order. Never dispatch a task whose
Depends on:names a task the ledger does not yet record as DONE. Task number is not dependency order. - Parallelism. The mode decision above asks whether tasks are "mostly
independent" — read that off the graph, not off intuition. Two tasks may
run concurrently only when neither depends on the other (directly or
transitively) and their
Files:do not overlap. File overlap alone is the weaker of the two tests; a dependency edge is a hard bar even when the files are disjoint. - Which Interfaces to include in step 1's brief — precisely the tasks
named in
Depends on:.
A task with no
Depends on:line at all is a different thing from one readingnone→BLOCKED: 缺 Depends on → 退回 keel-plan. The Medium shortcut can produce plans without it, and those are exactly the plans G2 never confirmed.Depends on: noneon every task is a legitimate graph, not a missing one. A task naming a dependency that does not exist in the plan is a plan bug →BLOCKED: Depends on 指向不存在的 task → 退回 keel-plan.- Order. Never dispatch a task whose
- Extract the task brief — the task's own text plus the plan header
(Goal, Global Constraints, and
Visual source of truth:when the plan has one) plus the Interfaces blocks of the tasks itsDepends on:names. Pass briefs as file paths, never pasted into the prompt — pasted history bloats every downstream dispatch. - Dispatch a fresh
keel-exec-implementerwith the brief. If the task names domain skills (itsSkills:field), the implementer invokes them before writing code. The brief carries the same two standards paths the quality reviewer gets —smells.mdnext to this file anddesign.mdin the siblingkeel-discoverskill, each written into the brief as an absolute path, not a relative link: resolve it to an absolute path from where this skill is actually installed (~/.claude/skills/…for a global install,<repo>/.claude/skills/…for a per-project one) and write that absolute path into the brief — a relative link resolves for you, reading this file, and for nobody in a subagent's cwd — because an author graded against a bar it was never shown turns every avoidable smell into a review round. It implements, tests, commits, and reports status. Staleness rule: before editing, the implementer verifies the task'sFiles:paths/lines still match reality. Mismatch → relocate using the task'sDelivers:behavior, note the drift in the status report; never blind-edit whatever now sits at the stated lines. Drift threshold — when relocation stops being enough. Record every relocate in the ledger. The plan as a whole has stopped matching the code when any of these holds: (a) a task'sDelivers:describes behavior with no corresponding location left in the codebase at all — not moved, gone; (b) a third or more of the completed tasks reported a relocate; (c) a symbol named in some task'sInterfaces: Consumes:doesn't exist and isn't produced by any earlier task. Any one → stop dispatching, emitBLOCKED: 計畫與現況牴觸 → 退回 keel-planwith the accumulated relocate list. This iskeel-workflow's "plan contradicts the code as it now is (beyond one task's fix)" route, and the threshold is what "beyond one task's fix" means operationally. Without a threshold the drift is absorbed silently: each implementer relocates its own task, notes it in its own report, and no one adds the notes up. A plan that stopped being true at Task 2 then runs to Task 9, each task individually reasonable and the whole built on ground that moved. Test-first is enforced, not aspirational (from superpowers TDD): the brief states that production code written before its failing test gets deleted and redone — not kept as "reference", not "adapted". Sunk cost is the wrong frame: untested code is a liability, not progress. Report file: the implementer writes its full report (what it did, test evidence, concerns) to.keel/task-N-report.md; its final message is ≤15 lines — status, commits, one-line test summary, concerns. Full reports flowing back inline is how controller contexts blow up. - Review the diff — spec/quality always, security when triggered — read-only by
declaration (they describe fixes; only the fixer writes):
(a)
keel-exec-reviewer-spec— does it do what the task'sDelivers:says: missing behavior, scope creep, implemented-but-wrong, interface drift; (b)keel-exec-reviewer-quality— repo standards first, plus the smell baseline insmells.mdand the design vocabulary/judgment tools inkeel-discover'sdesign.md— both written into the brief as absolute paths, not relative links: resolve it to an absolute path from where this skill is actually installed (~/.claude/skills/…for a global install,<repo>/.claude/skills/…for a per-project one) and write that absolute path into the brief — a relative link resolves for you, reading this file, and for nobody in a subagent's cwd. Both must pass, on every task, no trigger condition. (c)keel-exec-reviewer-security— dispatched as a third, independent axis only when at least one of these R4 conditions is met (check all five before skipping). Findings taggedplan-globalinkeel-plan-lens-security's output don't belong to any single task — note them once at the start of this step, not as a per-task trigger:- the task's
Files:line touches an authentication/authorization/session, encryption, file-upload, outbound-call, or database-query-construction path. This is judged semantically against the task'sDelivers:content, not a literal filename/keyword match — per keel-plan's existing "Delivers is truth, Files is a hint" rule. A diff that changes an existing data query's ownership filter still counts even ifFiles:only saysservices/order.pywith no "auth" string in it. - the diff adds or modifies an externally-reachable endpoint
keel-planmarked the task high-risk- the plan-stage security lens (
keel-plan-lens-security) previously raised a finding against this task: determined by matching the plan file's## SECURITY FINDINGStable rows by their## Task Ntag against the current task's number — a tag match means condition 4 is met, regardless of whether that finding was later addressed. ("Previously raised," not "still unresolved.") Read the table from the plan file, never from conversation history: this controller may be a fresh one that never saw the review stage. No such section — the plan skippedkeel-plan-review, which most plans do — means this condition is unevaluable, not false: it cannot contribute a trigger, and the other four conditions carry the decision alone. Say so in the ledger line rather than counting it as a clean miss. - the diff matches a sensitive-string pattern:
password,secret,token,api[_-]?key,BEGIN.*PRIVATE KEY, or a connection-string shape New dependencies added to a package list (new package names, not version bumps) do not trigger this axis on their own — that's dependency existence verification and belongs tokeel-finishPart 2c(3b). A pure dependency-list change that matches none of the five conditions above skips this axis and cites that deferral in the ledger line below. Not triggered → do not dispatch it; instead write to the ledgersecurity axis skipped — <which of the five conditions was checked and why none matched — for a pure dependency-list change, cite "deferred to keel-finish Part 2c(3b)">, so the skip is an auditable decision, not a silent omission. When in doubt, dispatch. Skipping this axis carries the same evidence burden as raising a finding: the ledger line quotes the task'sDelivers:text and its diff file list, not a prose assurance. Spec and quality run unconditionally; this is the only axis whose omission is a judgment call, and the entity making that call is the same controller carrying the fan-out ceiling and the opus budget. Note the asymmetry the way this pipeline notes it everywhere else — a needless security pass costs one agent, a missed one costs whatever shipped. Findings go in the ledger, not just the conversation. When the axis runs, its Critical/Important findings and their disposition are written to the task's ledger line (security:field, see Progress ledger below).keel-finishPart 2c check (2) reads that field from a later, fresh context; a finding that exists only here is one that gate will never see. Give each reviewer the base commit explicitly — the commit before the task started, neverHEAD~1, which silently drops all but the last commit of a multi-commit task. A reviewer with no stated base returns BLOCKED rather than guessing. All diffs exclude.keel/. Splitting the axes across separate agents is what makes the no-merge rule below structural rather than aspirational: no reviewer can see, and so cannot be swayed by, another's verdict. Broadcast every verdict the moment it lands — the agent's own name (keel-exec-reviewer-quality, not "the quality reviewer"), its axis, PASS/FAIL, the single worst issue with itsfile:lineanchor, and what you do next. The name is what tells a watcher which stage they are in and which of the three axes just spoke; a paraphrase loses both. Never merge or rerank across axes — each axis (spec, quality, and security when triggered) reports its own findings and its own worst issue, no single winner (from mattpocock code-review: a change can follow every standard and build the wrong thing, or vice versa; one axis must not mask another — a third axis does not change this rule, it just adds a third independent voice). Each reviewer reads the task brief and report as file paths. It returns findings inline — reviewers hold noWritetool and their own text forbids using the shell for one, so "return it as a file too" would read as licence to breach the read-only grant. Cap the return instead: verdict plus the worst findings inline, the remainder in the appendix. Evidence gate: every finding quotes the diff/code line that motivates it (file:line + verbatim text); no quotable line → confidence 4-5/10, appendix only, never the main verdict.
- the task's
Name the failure, not just the line: concrete inputs or state, and the wrong output, crash, or missed requirement they produce. Cannot name one → capped at confidence 5.
Plan-mandated findings (from superpowers): a finding that conflicts
with the plan's own text is the USER's decision. Present the finding and
the plan line side by side and ask which wins. Never dismiss it because
"the plan says so" — the plan's authorship does not grade its own work —
and never dispatch a fix that contradicts the plan without asking.
4. Fix loop (capped, from superpowers 6.2.0): Critical/Important findings
→ keel-exec-fixer → scoped re-review of only the findings just fixed →
repeat. The fixer touches only the listed findings; anything else it
changes enters the next review as unreviewed risk. PLAN-CONFLICT
findings are never handed to the fixer — they go to the user (gate G6).
Round cap: 5. Rounds 1–3 resume the same keel-exec-fixer dispatch.
Rounds 4–5 switch to keel-exec-fixer-critical (opus, fresh context, no
memory of the failed attempts) — tier by agent identity, same as the
skeptic split; never pass a model override to escalate the standard
fixer, that's the exact anti-pattern this pipeline's model-pinning rule
exists to prevent. A fixer that failed twice with the same context and
model is not going to succeed a third time unchanged.
From round 4, the reviewer brief switches to the verdict-matrix form
(~/.claude/skills/learned/references/templates/verdict-matrix.md): one
named area per outstanding finding plus the three fixed areas — NEW
defect introduced by the fix itself, previous-RESOLVED regression, and
test adequacy (does the test enter the failure window or only the happy
path) — each answered RESOLVED / PARTIAL / NOT_RESOLVED with a line
anchor. Selective reporting is what lets a fix loop spin; round 4 on a
race/lifecycle fix is itself the signal the design is wrong, not the
patch (learned method.md §一.3).
At round 5, if findings remain: circuit breaker trips. Adjudicate each
remaining finding — load-bearing (breaks a Delivers: line, security, data
integrity) → BLOCKED, report to the user, do not mark the task done;
cosmetic/non-load-bearing → park in the ledger with the ruling and proceed.
Never loop past round 5 silently hoping the next attempt converges.
5. Drive any critical flow that can now run, then ledger append (see
below), update .keel/state.md, next task.
Read the plan's ## Critical flows. After this task, ask of each flow not
yet driven since its last touching change: can its Drive column run now?
If yes, run it and compare against Observable result — then record the
verdict on the ledger line as flow: <name> — ok or
flow: <name> — FAILED: <what you saw>. A flow whose Drive reads
after T<n> is not askable until task n is DONE; say nothing about it
until then.
A failing flow stops the loop the way a failing task does. It is not a note for the summary: the join it crosses is broken now, and every later task builds on it. Diagnose before dispatching anything else.
Why here and not at Finish: a flow that cannot work at all is a design error, and finding it after the last task means every task was written against a shape that does not hold. The whole point of driving early is that the cheapest moment to learn "these two sides do not fit" is the first moment it is knowable, which is the first task after which the boundary exists at all.
Fan-out ceiling
≤8 concurrent and ≤16 total agents per task loop. If findings exceed what the
fix loop can carry, sort by severity, handle the top N, and emit
SKIPPED: <n> — <id + reason>. Silent truncation reads as full coverage when
it isn't.
Fan-out ceiling: ≤8 concurrent, ≤16 total per task loop.
Dispatch discipline
Name the subagent_type on every dispatch — a general-purpose agent inside
this stage is a bug, and the type name is what tells the user which stage and
which role is currently running. Do not pass a model override: each agent
file pins its own model and tool set, and overriding re-introduces the silent
model-inheritance problem those pins exist to prevent.
Do not pass a model override at the call site — each agent file pins its own.
Name the agent, not the role: announce each dispatch before it runs and broadcast each result when it lands, both using the agent's literal keel-* name.
Implementer status protocol
| Status | Meaning | Controller action |
| DONE | Complete, tests pass | Review, proceed |
| DONE_WITH_CONCERNS | Complete but flagged | Review with the concerns in the reviewer brief |
| NEEDS_CONTEXT | Missing information | Answer from plan/spec; if absent there, that's a plan bug — fix the plan |
| BLOCKED | Cannot proceed | Never re-dispatch the same prompt to the same model unchanged; diagnose first |
Anything a subagent reports that you cannot verify from artifacts (diff, test output) — resolve personally before marking the task complete. "Agent said success" is not evidence; the diff is.
Model selection — pinned, not chosen per dispatch
Model choice lives in each agent's frontmatter, not in this prose. That is deliberate: the previous rule ("always specify the model explicitly") was prose, and prose rules drift — every dispatch silently inherited the session's expensive model instead.
| Agent | model | Why |
keel-exec-implementer | sonnet | Ordinary implementation |
keel-exec-reviewer-spec | sonnet | Checklist-shaped, high volume |
keel-exec-reviewer-quality | sonnet | Checklist-shaped, high volume |
keel-exec-reviewer-security | opus | R4-triggered third axis; higher-stakes judgment than the checklist-shaped axes |
keel-exec-fixer | sonnet | Scope is a given findings list |
keel-exec-fixer-critical | opus | Fix-loop rounds 4-5 only — standard tier stalled twice |
code-reviewer (final branch) | inherit | Widest scope, last line of defence |
Do not override these at the call site. If a task is pure transcription — the plan already contains the exact code — that is a signal the task is too small to dispatch, not a reason to hand-tune a model.
Turn count beats token price: a cheap model that takes 4 retries costs more than a capable one that takes 1.
Progress ledger — crash safety
Append one line per completed task to .keel/progress.md:
Task 3: auth middleware — DONE, reviewed (2 findings fixed), commit a1b2c3d, branch feat/auth
relocated: 1 (Files: said src/auth.py:120-140; found at :200-220 by Delivers)
security: 2 Important (SQL string-building svc/order.py:44; missing authz check api/admin.py:12) → both fixed in a1b2c3dThe task line carries the implementer's returned status verbatim —
DONE, DONE_WITH_CONCERNS, and so on. DONE_WITH_CONCERNS additionally
carries a one-line digest of the concern, because keel-finish Part 2b
reconciles flagged concerns out of this file and cannot see a status that
was paraphrased away.
The relocated field is what makes the drift threshold above countable —
criterion (b) counts relocates across completed tasks, and a count needs a
field, not free-text concerns. Write relocated: none when there were none.
The branch field exists because a controller resuming after compaction
reads this file to recover state, and "which branch was this on" is exactly
the fact that gets lost — the failure that puts a fresh implementer on main.
The security line is written whenever the security axis ran: every
Critical/Important finding with its file:line and disposition, or
security: none if it passed clean. When the axis was skipped, that line is
the skip justification instead (see step 3c). keel-finish Part 2c check (2)
reads these lines — with no producer here, that gate has nothing to check and
passes vacuously, which is not the same as passing.
The same ledger entry carries a findings: line: findings: <n> entries
counted from .keel/findings.md, or findings: none — <why> written by
hand when the file is absent or empty (legitimate for a branch with no
exploratory work; a branch that explored and wrote nothing down has no
honest <why>). keel-finish Part 2e reads this line before promotion.
On session start or after compaction: read the ledger FIRST. Trust the
ledger and git log over your recollection — controllers that lost their
place have re-executed entire completed task sequences, the single most
expensive failure mode observed. The ledger is why this workflow survives
a crashed session.
Finish
After all tasks: dispatch one final whole-branch code-reviewer (no model
override — it inherits the strongest available; diff from merge-base, same
two-axis rules: spec axis against the plan's
Goal + Success Criteria, quality axis with smells.md given as an
absolute path, not a relative link — resolve it to an absolute path from where this skill is actually installed (~/.claude/skills/… for a global install, <repo>/.claude/skills/… for a per-project one) and write that absolute path into the brief — a relative link resolves for you, reading this file, and for nobody in a subagent's cwd — no merged
ranking). The final reviewer additionally produces a coverage diagram
(from gstack): trace each entry point through its branches and error
paths as an ASCII tree, grade each path, and end with one line —
COVERAGE: N/M paths tested (X%). Coverage claims without the diagram are
vibes.
Findings follow the same evidence discipline as the plan's Architecture
field: every claim cites file:line, and a suspicion the reviewer could not
verify is reported as 待確認: <why unverified + what would confirm it> —
never silently dropped, never asserted as fact. A 待確認 edge is a ready-made
attack target for the next verification pass.
Grade by checklist, not by impression. Each star is one named test that
exists and passes; count them, do not judge them. Cite the test's
file:name for each star awarded — a star you cannot point at is a GAP.
| Grade | Requires |
| ★★★ | a test for the happy path, one for a boundary (empty, zero, max, longest plausible input), and one for the error path (the failure actually reachable here, not a generic throw) |
| ★★ | happy path plus one of boundary or error |
| ★ | happy path only — the path is exercised, nothing about it is pinned |
| GAP | no test reaches this path, or the only test asserts it "doesn't crash" |
Three named tests is a count. "Feels well covered" is not, and the star rating existed for two weeks as exactly that before this table.
If this plan edited the pipeline's own skill/rule files (this repo, not a
consumer repo): run bash eval-fixtures/check-structure.sh and paste its
summary line — it verifies the structural guarantees (model/tool pins,
read-only grants, roster completeness) mechanically, and a non-zero exit is
a real failure, not a report. Then, if eval-fixtures/RULE-INVENTORY.md
exists: also report
FIXTURE COVERAGE: N/M rules fixture-covered (X%), computed by running the
grep commands that file's ## Current coverage section documents —
run them, do not copy the prose figure, which that same
section forbids carrying forward and which has been wrong four times. A
computed value that disagrees with the prose is itself a finding. Also list
any rule this plan added or changed that the table doesn't yet have a row
for — an unlisted new rule is the same silent-regression risk the inventory
exists to catch, one release earlier. This is a report, not a gate: a plan
may ship with fixture gaps, same as COVERAGE above never blocks on its own.
Then one fix pass for its findings, and write the closing ledger line —
without it keel-finish Part 3 has nothing to confirm this review against,
and its check passes vacuously exactly the way the security chain's did
before it was persisted:
final-review: PASS — 2 Important (svc/order.py:44 unwired guard; api/admin.py:12 missing authz) → both fixed in 9ed28b5; COVERAGE: 23/27 paths (85%)FAIL with findings still open is a legitimate value; what is not legitimate
is the line being absent, because absent and clean are indistinguishable to
the stage that reads it. → keel-finish.
Reporting completion to the user in an interactive session, when the
branch's structure is complex: load the show-me-first skill and present
the risk-path map as its browser SVG — the review's 待確認 edges double as
the reader's "look here first" guide. This is for the human checkpoint only:
inside the pipeline (subagents, ledger, plan files) stay on the ASCII lane —
SVG per subagent would spray browser tabs and costs ~30-60% extra
tokens/time per agent (show-me-first's own eval).
INLINE mode
Run the same pre-flight as ORCHESTRATED mode, in full, before task 1: the plan-contradiction scan (G5), the Spec drift check, the Destructive-operation scan (G9), and the dependency graph read of step 0. Read the whole plan critically alongside it — concerns get raised BEFORE starting, not at task 7.
Those gates live under ORCHESTRATED above only because that is where they were written, not because they are a property of dispatching subagents. INLINE removes the second chance, not the requirement — and it removes it twice over, because the G9 backstop that
keel-exec-implementercarries never fires here: there is no implementer, you are it. This is also the modePROJECT-TYPE-GUIDE.mdmakes the default for serverless/edge, CLI, and scraping work — three of the project types most likely to deploy.- Create a todo per task. Execute in dependency order per step 0, not
task-number order: follow each step exactly, run each verification, mark
complete. Update the ledger the same as orchestrated mode — inline
sessions crash too — and overwrite
.keel/state.mdon the same beat, for the same reason: a resumed controller reads that file to learn where it is, and INLINE is the mode with no per-task reviewer to notice it went stale. The rulebook injection applies here too: with a.learned/, run the per-tasklearned.py searchand hold the hits as your own Global Constraints and self-review checklist — there is no brief to append them to, but the brief was only ever the carrier, not the rule. Driving critical flows applies here too, on the same beat as the ledger: after each task, run any## Critical flowsrow whoseDrivecan now run, and recordflow: <name> — ok/FAILED: <what you saw>. A failed flow stops this loop exactly as it stops the orchestrated one — more so, because here there is no per-task reviewer who might have noticed the join was broken. - Stop and ask rather than guess when: blocked, the plan has a critical gap, an instruction is ambiguous, or a verification keeps failing. G6 gate applies here too: a finding that conflicts with the plan's own text is never self-decided just because there's no separate reviewer subagent to raise it — the same single session that wrote the code must still stop and ask the user which wins, exactly as ORCHESTRATED mode's step 4 fix loop requires.
Run the ORCHESTRATED
### Finishblock unchanged — the final whole-branchcode-reviewer, its coverage diagram, theFIXTURE COVERAGEreport when this repo's own rule files were touched, then one fix pass for its findings. Write the closingfinal-review:ledger line.If subagents are genuinely unavailable (the reason you are in INLINE at all), you cannot dispatch
code-reviewer. Then do the whole-branch review yourself against the merge-base diff — same two axes, same coverage diagram — and record in thefinal-review:line that it was self-reviewed, because that is materially weaker and the reader deserves to know. Telling the user the branch ships without an independent reader, and writing aTODOS.mdentry, is the other acceptable answer. Silently skipping is not.INLINE removes the per-task reviewers. It does not remove the branch-level one — and it is the mode that needs it most, because here the code's author and its only reader are the same context.
keel-finishwill not cover for a skip: it explicitly does not re-run this review, on the stated assumption that it already happened.- Then → keel-finish.
Red flags
- Dispatching parallel implementers on overlapping files → conflicts; serialize them
- Letting the implementer's self-review substitute for review → independent reviewer, always
- "I remember where I was" after compaction → no you don't; read the ledger
- Skipping a task's failing-test step because "the code is obviously right" → the test IS the task
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

