@arbiterforge/ca-pi 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +558 -0
  3. package/package.json +35 -0
  4. package/plugins/ca-pi/CHANGELOG.md +1030 -0
  5. package/plugins/ca-pi/COMMANDS.md +90 -0
  6. package/plugins/ca-pi/ORCHESTRATOR.md +159 -0
  7. package/plugins/ca-pi/SKILLS.md +47 -0
  8. package/plugins/ca-pi/SPRINT.md +142 -0
  9. package/plugins/ca-pi/agents/INDEX.md +31 -0
  10. package/plugins/ca-pi/agents/architecture-drift-reviewer.md +86 -0
  11. package/plugins/ca-pi/agents/auth-crypto-reviewer.md +60 -0
  12. package/plugins/ca-pi/agents/backend-author.md +60 -0
  13. package/plugins/ca-pi/agents/checkpoint-aggregator.md +111 -0
  14. package/plugins/ca-pi/agents/coverage-auditor.md +71 -0
  15. package/plugins/ca-pi/agents/decision-challenger.md +116 -0
  16. package/plugins/ca-pi/agents/dependency-reviewer.md +79 -0
  17. package/plugins/ca-pi/agents/design-quality-reviewer.md +80 -0
  18. package/plugins/ca-pi/agents/finding-triage.md +86 -0
  19. package/plugins/ca-pi/agents/frontend-author.md +64 -0
  20. package/plugins/ca-pi/agents/grader.md +173 -0
  21. package/plugins/ca-pi/agents/infra-author.md +64 -0
  22. package/plugins/ca-pi/agents/map-deps.md +35 -0
  23. package/plugins/ca-pi/agents/map-structure.md +37 -0
  24. package/plugins/ca-pi/agents/migration-reviewer.md +65 -0
  25. package/plugins/ca-pi/agents/scout.md +127 -0
  26. package/plugins/ca-pi/agents/security-reviewer.md +72 -0
  27. package/plugins/ca-pi/agents/tribunal-lens-reviewer.md +65 -0
  28. package/plugins/ca-pi/extensions/codearbiter-child.js +1885 -0
  29. package/plugins/ca-pi/extensions/codearbiter.js +9802 -0
  30. package/plugins/ca-pi/generated/command-catalog.json +197 -0
  31. package/plugins/ca-pi/generated/roles.json +213 -0
  32. package/plugins/ca-pi/helpers/windows-supervisor.js +205 -0
  33. package/plugins/ca-pi/hooks/_activationlib.py +196 -0
  34. package/plugins/ca-pi/hooks/_arbiterstatelib.py +208 -0
  35. package/plugins/ca-pi/hooks/_babysitlib.py +76 -0
  36. package/plugins/ca-pi/hooks/_bashguardlib.py +1667 -0
  37. package/plugins/ca-pi/hooks/_boxlib.py +131 -0
  38. package/plugins/ca-pi/hooks/_colorlib.py +304 -0
  39. package/plugins/ca-pi/hooks/_durabilitylib.py +186 -0
  40. package/plugins/ca-pi/hooks/_entrylib.py +41 -0
  41. package/plugins/ca-pi/hooks/_fmtlib.py +161 -0
  42. package/plugins/ca-pi/hooks/_gitexec.py +45 -0
  43. package/plugins/ca-pi/hooks/_githooks.py +920 -0
  44. package/plugins/ca-pi/hooks/_gitlib.py +110 -0
  45. package/plugins/ca-pi/hooks/_hooklib.py +595 -0
  46. package/plugins/ca-pi/hooks/_host.py +115 -0
  47. package/plugins/ca-pi/hooks/_intentlib.py +242 -0
  48. package/plugins/ca-pi/hooks/_ledgerlib.py +1035 -0
  49. package/plugins/ca-pi/hooks/_metricslib.py +709 -0
  50. package/plugins/ca-pi/hooks/_pathnorm.py +74 -0
  51. package/plugins/ca-pi/hooks/_planfilelib.py +664 -0
  52. package/plugins/ca-pi/hooks/_previewlib.py +193 -0
  53. package/plugins/ca-pi/hooks/_protectedlib.py +312 -0
  54. package/plugins/ca-pi/hooks/_protectedstatelib.py +411 -0
  55. package/plugins/ca-pi/hooks/_provenancelib.py +971 -0
  56. package/plugins/ca-pi/hooks/_prunelib.py +1398 -0
  57. package/plugins/ca-pi/hooks/_prunepolicy.py +235 -0
  58. package/plugins/ca-pi/hooks/_readinjectlib.py +1080 -0
  59. package/plugins/ca-pi/hooks/_releaselib.py +2657 -0
  60. package/plugins/ca-pi/hooks/_scopelib.py +262 -0
  61. package/plugins/ca-pi/hooks/_segmentslib.py +278 -0
  62. package/plugins/ca-pi/hooks/_sensitivelib.py +270 -0
  63. package/plugins/ca-pi/hooks/_sessionlib.py +78 -0
  64. package/plugins/ca-pi/hooks/_sloplib.py +244 -0
  65. package/plugins/ca-pi/hooks/_standuplib.py +214 -0
  66. package/plugins/ca-pi/hooks/_subagentslib.py +219 -0
  67. package/plugins/ca-pi/hooks/_taskboardlib.py +1088 -0
  68. package/plugins/ca-pi/hooks/_updatelib.py +278 -0
  69. package/plugins/ca-pi/hooks/babysit.py +47 -0
  70. package/plugins/ca-pi/hooks/boardsync.py +129 -0
  71. package/plugins/ca-pi/hooks/doctor.py +420 -0
  72. package/plugins/ca-pi/hooks/git-enforce.py +325 -0
  73. package/plugins/ca-pi/hooks/hostapi.py +460 -0
  74. package/plugins/ca-pi/hooks/init-codearbiter.py +225 -0
  75. package/plugins/ca-pi/hooks/metrics.py +62 -0
  76. package/plugins/ca-pi/hooks/migration-pass.py +129 -0
  77. package/plugins/ca-pi/hooks/pi-bridge.py +543 -0
  78. package/plugins/ca-pi/hooks/post-write-edit.py +231 -0
  79. package/plugins/ca-pi/hooks/pre-bash.py +90 -0
  80. package/plugins/ca-pi/hooks/pre-edit.py +284 -0
  81. package/plugins/ca-pi/hooks/pre-read.py +81 -0
  82. package/plugins/ca-pi/hooks/pre-write.py +217 -0
  83. package/plugins/ca-pi/hooks/preview.py +69 -0
  84. package/plugins/ca-pi/hooks/prune-transcript.py +232 -0
  85. package/plugins/ca-pi/hooks/releasehash.py +216 -0
  86. package/plugins/ca-pi/hooks/security-pass.py +139 -0
  87. package/plugins/ca-pi/hooks/session-start.py +1218 -0
  88. package/plugins/ca-pi/hooks/statusline.py +736 -0
  89. package/plugins/ca-pi/hooks/taskwrite.py +351 -0
  90. package/plugins/ca-pi/hooks/update-refresh.py +51 -0
  91. package/plugins/ca-pi/hooks/wire-statusline.py +435 -0
  92. package/plugins/ca-pi/includes/anti-slop-design/INDEX.md +55 -0
  93. package/plugins/ca-pi/includes/anti-slop-design/color.md +43 -0
  94. package/plugins/ca-pi/includes/anti-slop-design/core.md +244 -0
  95. package/plugins/ca-pi/includes/anti-slop-design/images.md +32 -0
  96. package/plugins/ca-pi/includes/anti-slop-design/layout.md +45 -0
  97. package/plugins/ca-pi/includes/anti-slop-design/medium-cli.md +39 -0
  98. package/plugins/ca-pi/includes/anti-slop-design/medium-dataviz.md +43 -0
  99. package/plugins/ca-pi/includes/anti-slop-design/medium-diagram.md +35 -0
  100. package/plugins/ca-pi/includes/anti-slop-design/medium-documents.md +70 -0
  101. package/plugins/ca-pi/includes/anti-slop-design/medium-slides.md +30 -0
  102. package/plugins/ca-pi/includes/anti-slop-design/medium-web.md +39 -0
  103. package/plugins/ca-pi/includes/anti-slop-design/typography.md +51 -0
  104. package/plugins/ca-pi/includes/author-tdd-workflow.md +14 -0
  105. package/plugins/ca-pi/includes/compaction-charter.md +16 -0
  106. package/plugins/ca-pi/includes/cut-docs.md +16 -0
  107. package/plugins/ca-pi/includes/dev-mode.md +30 -0
  108. package/plugins/ca-pi/includes/farm.md +237 -0
  109. package/plugins/ca-pi/includes/fresh-verification.md +14 -0
  110. package/plugins/ca-pi/includes/harvest.md +69 -0
  111. package/plugins/ca-pi/includes/maturity-coverage.md +102 -0
  112. package/plugins/ca-pi/includes/pi-host-notes.md +69 -0
  113. package/plugins/ca-pi/includes/redirect.md +69 -0
  114. package/plugins/ca-pi/includes/reference-map.md +22 -0
  115. package/plugins/ca-pi/includes/review-matrix.md +14 -0
  116. package/plugins/ca-pi/includes/reviewer-contract.md +53 -0
  117. package/plugins/ca-pi/includes/routing-table.md +47 -0
  118. package/plugins/ca-pi/includes/security-gate-record.md +22 -0
  119. package/plugins/ca-pi/includes/smarts/core.md +90 -0
  120. package/plugins/ca-pi/includes/smarts/decision-log-format.md +56 -0
  121. package/plugins/ca-pi/routines/INDEX.md +32 -0
  122. package/plugins/ca-pi/routines/brainstorming/SKILL.md +122 -0
  123. package/plugins/ca-pi/routines/commit-gate/SKILL.md +151 -0
  124. package/plugins/ca-pi/routines/context-check/SKILL.md +85 -0
  125. package/plugins/ca-pi/routines/context-creation/SKILL.md +171 -0
  126. package/plugins/ca-pi/routines/crypto-compliance/SKILL.md +41 -0
  127. package/plugins/ca-pi/routines/debug/SKILL.md +99 -0
  128. package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +104 -0
  129. package/plugins/ca-pi/routines/decision-lifecycle/references/adr-template.md +74 -0
  130. package/plugins/ca-pi/routines/decision-variance/SKILL.md +147 -0
  131. package/plugins/ca-pi/routines/decompose/SKILL.md +168 -0
  132. package/plugins/ca-pi/routines/dispatching-parallel-agents/SKILL.md +76 -0
  133. package/plugins/ca-pi/routines/executing-plans/SKILL.md +83 -0
  134. package/plugins/ca-pi/routines/finishing-a-development-branch/SKILL.md +91 -0
  135. package/plugins/ca-pi/routines/post-merge-cleanup/SKILL.md +233 -0
  136. package/plugins/ca-pi/routines/refactor/SKILL.md +91 -0
  137. package/plugins/ca-pi/routines/release/SKILL.md +315 -0
  138. package/plugins/ca-pi/routines/secret-handling/SKILL.md +67 -0
  139. package/plugins/ca-pi/routines/security-architecture/SKILL.md +63 -0
  140. package/plugins/ca-pi/routines/skill-author/SKILL.md +108 -0
  141. package/plugins/ca-pi/routines/skill-author/references/skill-template.md +58 -0
  142. package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +149 -0
  143. package/plugins/ca-pi/routines/subagent-driven-development/references/farm-dispatch.md +145 -0
  144. package/plugins/ca-pi/routines/tdd/SKILL.md +139 -0
  145. package/plugins/ca-pi/routines/tribunal/SKILL.md +109 -0
  146. package/plugins/ca-pi/routines/tribunal/references/ai-markers.md +29 -0
  147. package/plugins/ca-pi/routines/tribunal/references/cost-and-models.md +64 -0
  148. package/plugins/ca-pi/routines/tribunal/references/finding-record.md +27 -0
  149. package/plugins/ca-pi/routines/tribunal/references/issue-filing.md +47 -0
  150. package/plugins/ca-pi/routines/tribunal/references/lenses/appsec.md +22 -0
  151. package/plugins/ca-pi/routines/tribunal/references/lenses/architecture.md +23 -0
  152. package/plugins/ca-pi/routines/tribunal/references/lenses/coverage.md +20 -0
  153. package/plugins/ca-pi/routines/tribunal/references/lenses/infra.md +24 -0
  154. package/plugins/ca-pi/routines/tribunal/references/lenses/migration.md +22 -0
  155. package/plugins/ca-pi/routines/tribunal/references/lenses/observability.md +21 -0
  156. package/plugins/ca-pi/routines/tribunal/references/lenses/performance.md +22 -0
  157. package/plugins/ca-pi/routines/tribunal/references/lenses/reliability.md +23 -0
  158. package/plugins/ca-pi/routines/tribunal/references/lenses/secrets-supply.md +22 -0
  159. package/plugins/ca-pi/routines/tribunal/references/lenses/test-fidelity.md +24 -0
  160. package/plugins/ca-pi/routines/tribunal/references/lenses/typesafety.md +21 -0
  161. package/plugins/ca-pi/routines/tribunal/references/report.md +19 -0
  162. package/plugins/ca-pi/routines/tribunal/references/schemas.md +58 -0
  163. package/plugins/ca-pi/routines/tribunal/references/telemetry.md +28 -0
  164. package/plugins/ca-pi/routines/tribunal/references/triage.md +53 -0
  165. package/plugins/ca-pi/routines/using-git-worktrees/SKILL.md +85 -0
  166. package/plugins/ca-pi/routines/writing-plans/SKILL.md +129 -0
  167. package/plugins/ca-pi/routines/writing-plans/references/farm-plan.md +50 -0
  168. package/plugins/ca-pi/skills/ca-add-dep/SKILL.md +88 -0
  169. package/plugins/ca-pi/skills/ca-adr/SKILL.md +30 -0
  170. package/plugins/ca-pi/skills/ca-adr-status/SKILL.md +30 -0
  171. package/plugins/ca-pi/skills/ca-arbiter/SKILL.md +36 -0
  172. package/plugins/ca-pi/skills/ca-audit/SKILL.md +51 -0
  173. package/plugins/ca-pi/skills/ca-btw/SKILL.md +23 -0
  174. package/plugins/ca-pi/skills/ca-checkpoint/SKILL.md +50 -0
  175. package/plugins/ca-pi/skills/ca-chore/SKILL.md +58 -0
  176. package/plugins/ca-pi/skills/ca-cleanup/SKILL.md +55 -0
  177. package/plugins/ca-pi/skills/ca-commands/SKILL.md +21 -0
  178. package/plugins/ca-pi/skills/ca-commit/SKILL.md +27 -0
  179. package/plugins/ca-pi/skills/ca-conflict/SKILL.md +61 -0
  180. package/plugins/ca-pi/skills/ca-context-check/SKILL.md +32 -0
  181. package/plugins/ca-pi/skills/ca-create-context/SKILL.md +32 -0
  182. package/plugins/ca-pi/skills/ca-debug/SKILL.md +42 -0
  183. package/plugins/ca-pi/skills/ca-decompose/SKILL.md +30 -0
  184. package/plugins/ca-pi/skills/ca-dev/SKILL.md +42 -0
  185. package/plugins/ca-pi/skills/ca-doctor/SKILL.md +44 -0
  186. package/plugins/ca-pi/skills/ca-feature/SKILL.md +105 -0
  187. package/plugins/ca-pi/skills/ca-fix/SKILL.md +42 -0
  188. package/plugins/ca-pi/skills/ca-init/SKILL.md +56 -0
  189. package/plugins/ca-pi/skills/ca-metrics/SKILL.md +80 -0
  190. package/plugins/ca-pi/skills/ca-new-skill/SKILL.md +34 -0
  191. package/plugins/ca-pi/skills/ca-override/SKILL.md +72 -0
  192. package/plugins/ca-pi/skills/ca-pr/SKILL.md +61 -0
  193. package/plugins/ca-pi/skills/ca-preview/SKILL.md +86 -0
  194. package/plugins/ca-pi/skills/ca-prune/SKILL.md +100 -0
  195. package/plugins/ca-pi/skills/ca-reconcile/SKILL.md +43 -0
  196. package/plugins/ca-pi/skills/ca-refactor/SKILL.md +43 -0
  197. package/plugins/ca-pi/skills/ca-release/SKILL.md +57 -0
  198. package/plugins/ca-pi/skills/ca-review/SKILL.md +63 -0
  199. package/plugins/ca-pi/skills/ca-spike/SKILL.md +41 -0
  200. package/plugins/ca-pi/skills/ca-sprint/SKILL.md +44 -0
  201. package/plugins/ca-pi/skills/ca-standup/SKILL.md +112 -0
  202. package/plugins/ca-pi/skills/ca-status/SKILL.md +56 -0
  203. package/plugins/ca-pi/skills/ca-task/SKILL.md +61 -0
  204. package/plugins/ca-pi/skills/ca-threat-model/SKILL.md +45 -0
  205. package/plugins/ca-pi/skills/ca-tribunal/SKILL.md +44 -0
  206. package/plugins/ca-pi/skills/ca-watch/SKILL.md +78 -0
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: skill-author
3
+ description: The authoring gate for new skills. Routed to when the user invokes /new-skill "<gap>". Five gated phases — gap evidence, scope, authoring, self-review against the v2 house style, routing integration. A new skill is not written until an existing one is proven not to cover the gap, and not shipped until it carries gated phases, hard rules, and a routing entry. Every authored skill matches the v2 format (frontmatter name+description, # name, Pre-flight, Phase N · gate, Hard rules).
4
+ ---
5
+
6
+ # skill-author
7
+
8
+ Author a new skill, the right way. Routed to when the user invokes `/new-skill "<gap>"`.
9
+
10
+ ## Pre-flight
11
+
12
+ Read these, or STOP and surface the gap — never author on assumption:
13
+
14
+ - The `<gap>` argument. Absent → STOP and ask: "Describe the gap this skill would fill. What situation does no existing skill cover today?"
15
+ - `<plugin-root>/routines/INDEX.md` — the surface scan of every existing skill. This is the gap-overlap check in Phase 1 and the integration target in Phase 5. Never bulk-read the skill bodies.
16
+ - `<plugin-root>/routines/commit-gate/SKILL.md` and `<plugin-root>/routines/tdd/SKILL.md` — the canonical v2 format the authored skill must mirror. Read them before Phase 3.
17
+ - `<project-root>/.codearbiter/CONTEXT.md` — project context, only if the gap is project-specific. A generic skill needs no project state.
18
+
19
+ ## Phase 1 — Gap evidence · gate: BLOCK
20
+
21
+ A new skill is permanent surface area. It is not written until the gap is proven real and proven uncovered.
22
+
23
+ Restate the gap in one sentence. Then scan `INDEX.md` for overlap: if an existing skill's "Owns" column already covers this, STOP and name it — "The `<name>` skill already owns this; review it before requesting a new one."
24
+
25
+ If no skill covers it, demand evidence — one of:
26
+
27
+ - **A** — three specific cases where the gap blocked work: what was attempted, what happened with no skill, what it cost.
28
+ - **B** — one high-impact case with traceable evidence: a blocked PR, an introduced defect, a compliance finding, a repeated failure pattern.
29
+
30
+ Hypothetical cases do not count. Fewer than three (Option A) or no traceable evidence (Option B) → STOP and decline: "Insufficient evidence of a real, recurring gap. A skill adds permanent maintenance cost. Return with evidence and I'll author it."
31
+
32
+ Gate: the gap is restated, proven uncovered against `INDEX.md`, and backed by Option-A or Option-B evidence. Speculation does not pass.
33
+
34
+ ## Phase 2 — Scope · gate: BLOCK
35
+
36
+ Settle scope with the user before any prose is written. Ask, and wait for an explicit answer:
37
+
38
+ - **Routed or dispatched?** A *skill* is routed to (gated phases, lives at `<plugin-root>/routines/<name>/SKILL.md`). An *agent* is dispatched by a skill (a reviewer/author, lives at `<plugin-root>/agents/<name>.md`). If the gap is really a reviewer, this is the wrong skill — redirect to agent authoring.
39
+ - **Command-invoked or internal?** Does a user type `/<name>` to reach it, or does another skill route to it mid-workflow? A command needs a routing-table entry; an internal skill needs a named parent that routes to it.
40
+ - **Single responsibility.** State the one thing the skill owns in a sentence. If it needs "and" to describe its job, it is two skills — split it or pick one.
41
+
42
+ Confirm back: "I will write a [command-invoked / internal] skill at `<plugin-root>/routines/<name>/SKILL.md`, owning <one responsibility>. [A `/<name>` command will be added to the routing table. / The `<parent>` skill will route to it.]"
43
+
44
+ Gate: explicit user agreement on routed-vs-dispatched, command-vs-internal, and a one-sentence single responsibility. Assumed answers do not pass.
45
+
46
+ ## Phase 3 — Authoring · gate: BLOCK
47
+
48
+ Write `SKILL.md` to the v2 house style — mirror `commit-gate` and `tdd` exactly. Start from `<plugin-root>/routines/skill-author/references/skill-template.md`. Required shape:
49
+
50
+ - **Frontmatter** — `name:` and `description:` only. Description is terse: what routes to it, the phase count, the gate. No cut doc refs, no trigger disclaimer.
51
+ - **`# <name>`** H1, then a one-line intro naming what routes to it (`/<command>` or the parent skill).
52
+ - **`## Pre-flight`** — the docs to read or STOP on. Project state cites `<project-root>/.codearbiter/<doc>`; other skills cite `<plugin-root>/routines/<name>`; agents cite `<plugin-root>/agents/<name>.md`. Never guess a command — read it or STOP.
53
+ - **`## Phase N — <title> · gate: BLOCK|STOP`** — sequential, each ending in a one-line `Gate:`. A phase with output that could be wrong has a gate; only a purely declarative phase may omit one.
54
+ - **`## Hard rules`** — `MUST NOT` lines, one per rule, no duplication.
55
+
56
+ Authoring rules:
57
+
58
+ - Imperative, terse, no hedging. No "should", no "if it looks wrong". A gate is a concrete, checkable condition.
59
+ - Surviving project docs only: `CONTEXT.md`, `tech-stack.md`, `coding-standards.md`, `specs/`, `plans/`, `security-controls.md`, `decisions/`, `overrides.log`. Do not reference cut docs or cut skills.
60
+ - Terminology lock: a skill is *routed to*; an agent is *dispatched*. Never "trigger", "fires", or "runs".
61
+ - An out-of-scope finding gets one line with an inline `[NEEDS-TRIAGE]` marker.
62
+
63
+ ## Phase 4 — Self-review · gate: BLOCK
64
+
65
+ Re-read the authored skill against the v2 quality bar. Each line below is a checkable defect, not a vibe:
66
+
67
+ - **Single responsibility** — the skill owns one thing. If a phase belongs to a different job, it is the wrong skill; cut it.
68
+ - **Concrete gates** — every non-declarative phase ends in a `Gate:` line stating a checkable condition. "Looks good" / "seems right" is not a gate; rewrite it.
69
+ - **House-style prose** — terse, imperative, matches `commit-gate`/`tdd`. Strip hedging and filler.
70
+ - **No duplicated rules** — a rule stated in a phase is not restated in Hard rules, and Hard rules carry no duplicates. State each rule once.
71
+ - **Format conformance** — frontmatter is `name`+`description`, plus `disable-model-invocation: true` ONLY on a chain-internal skill (never user-typed, reached solely via routing-table path loads — see ADR-0028); H1 matches `name`; phases are numbered with `· gate:`; paths use `<plugin-root>` / `<project-root>` correctly; no cut docs/skills, no legacy `${FRAMEWORK_ROOT}`/`${PROJECT_ROOT}`/`.agents/` paths.
72
+ - **Frontmatter scalar quoting** — any frontmatter scalar that starts with `[` or `{`, or contains `": "` or `" | "`, MUST be JSON-quoted (the `_yaml_safe_scalar` predicate the surface generator applies to codex/pi wrappers; the claude surface ships frontmatter verbatim, so the author quotes it at the source).
73
+ - **No trigger language** — "routed to" / "dispatched" only, and no `## Trigger` disclaimer block.
74
+ - **Evidence lenses** (issue #612) — each checked where the skill's shape triggers it, skipped where it does not:
75
+ - A gate an agent is tempted to skip carries a rationalization guard AT the decision point — the known excuses paired with rebuttals. The best rebuttal carries its own instrument: a check the agent can run that falsifies the excuse either way. A tempting gate with no guard is a defect.
76
+ - An acceptance or verification step names what is READ, never what is claimed — "the subagent reports green" is a defect; "the runner's output shows green" is not.
77
+ - A user-facing ask leads with a recommendation AND its strongest counter-consideration.
78
+ - A rule a tested helper could enforce is mechanized rather than accreted as prose — the helper enforces, the prose explains.
79
+ - A rule whose literal reading has an exploitable edge names what it protects.
80
+ - **Behavior-changing gate revisions are validated, not assumed** — an A/B pass (fixed scenarios, rubrics written before any output exists, both versions run under identical conditions) scaled to the change's blast radius, with results recorded in the PR (issue #612's method).
81
+
82
+ Compile the findings, fix each, and re-read once. Present the corrected skill and the findings list to the user.
83
+
84
+ Gate: zero open self-review defects, and the user has seen the corrected skill. An unaddressed defect blocks Phase 5.
85
+
86
+ ## Phase 5 — Routing integration · gate: BLOCK
87
+
88
+ A skill no one routes to is dead code. Wire it in.
89
+
90
+ - Add a row to `<plugin-root>/routines/INDEX.md`: skill name (linked), "Routed to by", and "Owns" (the one-sentence responsibility from Phase 2).
91
+ - Add the skill to the routing table — the invocation cue (the `/<command>` or condition), the primary route, any dispatched agents, the hard gate. For a command-invoked skill, also register the `/<command>` in the command reference.
92
+ - For an internal skill, update the named parent so it routes to the new skill explicitly.
93
+
94
+ Verify no broken references: every path the skill cites resolves. `INDEX.md` row parity and routing-table dangling-route freedom are no longer a hand-check here — `.github/scripts/check_routing_index_parity.py` enforces both mechanically in CI (issue #592); a missing row, an orphan row, or a route to a name that does not exist fails the build.
95
+
96
+ Hand off to `commit-gate` — never `git commit` directly. The skill change ships only through the commit gate.
97
+
98
+ Gate: `INDEX.md` and the routing table updated, no broken references, and the change handed to `commit-gate`. CI's routing-parity check is the authority on row/route correctness, not a self-report.
99
+
100
+ ## Hard rules
101
+
102
+ - MUST NOT author a skill before the gap is proven uncovered against `INDEX.md` and backed by Option-A or Option-B evidence.
103
+ - MUST NOT begin authoring without explicit user agreement on scope (routed-vs-dispatched, command-vs-internal, single responsibility).
104
+ - MUST NOT emit a skill whose phases lack concrete `Gate:` lines, or whose Hard rules duplicate phase rules.
105
+ - MUST NOT use trigger language ("trigger", "fires", "runs") or a `## Trigger` disclaimer — a skill is routed to, an agent dispatched.
106
+ - MUST NOT reference a cut doc, cut skill, or a legacy `.agents/` / `${FRAMEWORK_ROOT}` / `${PROJECT_ROOT}` path in an authored skill.
107
+ - MUST NOT ship a skill without an `INDEX.md` row and a routing entry.
108
+ - MUST NOT commit the new skill directly — hand off to `commit-gate`.
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: <skill-name>
3
+ description: <One terse sentence: what routes to this skill, the phase count, and the hard gate. No doc refs, no trigger disclaimer. JSON-quote the whole scalar if it starts with `[`/`{` or contains `": "` or `" | "`. Example: "The only path to X. Routed to when the user invokes /foo. Three gated phases — A, B, C. Nothing ships until every gate clears.">
4
+ ---
5
+ <!-- Chain-internal skill (never user-typed, reached only via routing-table path loads)?
6
+ Add `disable-model-invocation: true` as a third frontmatter line — ADR-0028. -->
7
+
8
+ # <skill-name>
9
+
10
+ <One-line intro naming what routes to it: `/<command>` (user-invoked) or the parent skill (internal).>
11
+
12
+ ## Pre-flight
13
+
14
+ Read these, or STOP and surface the gap — never guess a command:
15
+
16
+ - `<project-root>/.codearbiter/<doc>.md` — <what it provides>. Stop if missing; do not guess.
17
+ - `<plugin-root>/routines/<other-skill>/SKILL.md` — <only if a sibling skill must clear first>.
18
+ - `<plugin-root>/agents/<agent>.md` — <only if this skill dispatches an agent>.
19
+
20
+ ## Phase 1 — <title> · gate: BLOCK
21
+
22
+ <Imperative description of what this phase does. Terse, no hedging.>
23
+
24
+ Gate: <a concrete, checkable exit condition>. A partial result does not pass.
25
+
26
+ ## Phase 2 — <title> · gate: BLOCK
27
+
28
+ <...>
29
+
30
+ Gate: <...>.
31
+
32
+ ## Phase N — <title> · gate: BLOCK
33
+
34
+ <Final phase. If the skill ends by persisting, hand off to `commit-gate` — never `git commit` directly.>
35
+
36
+ Gate: <...>.
37
+
38
+ ## Hard rules
39
+
40
+ - MUST NOT <invariant, stated once — not duplicated from a phase>.
41
+ - MUST NOT <invariant>.
42
+ - MUST NOT guess a command — read the cited `.codearbiter/` doc or STOP.
43
+
44
+ <!--
45
+ House-style reminders (delete before shipping):
46
+ - Frontmatter is `name:` + `description:` only.
47
+ - H1 matches `name`. One-line intro names what routes to it.
48
+ - Each non-declarative phase ends in a one-line `Gate:`.
49
+ - Paths: project state -> `<project-root>/.codearbiter/<doc>`;
50
+ skills -> `<plugin-root>/routines/<name>`;
51
+ agents -> `<plugin-root>/agents/<name>.md`.
52
+ - Surviving project docs only: CONTEXT.md, tech-stack.md, coding-standards.md,
53
+ specs/, plans/, security-controls.md, decisions/, overrides.log.
54
+ - Terminology lock: a skill is *routed to*; an agent is *dispatched*.
55
+ Never "trigger", "fires", "runs". No `## Trigger` block.
56
+ - Out-of-scope finding -> one line with inline `[NEEDS-TRIAGE]`.
57
+ - Terse, imperative. No "should", no "if it looks wrong".
58
+ -->
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: subagent-driven-development
3
+ description: The implementation engine. Routed to by /sprint (full plan, autonomous) and by executing-plans (scoped batch, checkpoint-gated). One fresh subagent per task — test-first via tdd — followed by spec-compliance review, quality review, and fresh-run verification. No single context accumulates drift, and nothing is accepted on a subagent's word.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # subagent-driven-development
8
+
9
+ One task, one fresh subagent, two reviews, proof on a fresh run. Routed to by `/sprint` (full plan,
10
+ autonomous) and by `executing-plans` (one batch at a time, with human checkpoints between batches).
11
+ The loop processes tasks in dependency order and never trusts a self-report.
12
+
13
+ ## Pre-flight
14
+
15
+ Read these, or STOP and surface the gap — never guess scope, command, or obligation:
16
+
17
+ - `<project-root>/.codearbiter/CONTEXT.md` — the `stage:` frontmatter (the maturity value) and project context.
18
+ - `<project-root>/.codearbiter/plans/<slug>.md` — the approved plan. Each task carries an exact path set and a verification command. This is the task source.
19
+ - `<project-root>/.codearbiter/specs/<slug>.md` — the approved spec. Each task's obligation traces to it. The spec-compliance review measures against it.
20
+ - `<project-root>/.codearbiter/tech-stack.md` — build, test, and verification invocations; file layout; the scope-to-author mapping.
21
+ - `<project-root>/.codearbiter/security-controls.md` — only when a task touches a security boundary (auth, crypto, secrets, a trust boundary).
22
+
23
+ **Optional `scope` parameter:** when invoked by `executing-plans`, a list of task IDs is passed. The
24
+ loop processes only those tasks (in their internal dependency order). When `scope` is absent (the
25
+ `/sprint` path), the loop processes the full plan from first unblocked task to last.
26
+
27
+ ## Phase 1 — Task selection · gate: BLOCK
28
+
29
+ Pull the next unblocked task from the plan in dependency order. When a `scope` was passed, restrict
30
+ selection to tasks in that list. A task is one verifiable unit of work with a path set, a spec
31
+ obligation, and a verification command.
32
+
33
+ - Confirm every dependency task is `ACCEPTED` before selecting.
34
+ - Confirm no unresolved `[CONFIRM-NN]` blocks the task. One that does halts the loop — see Hard rules.
35
+
36
+ Gate: exactly one task selected, dependency-clean, with its spec obligation and verification command in hand.
37
+
38
+ ## Phase 2 — Implementation dispatch · gate: BLOCK
39
+
40
+ **Farm path (when `<slug>.plan.json` exists alongside the `.md` plan):** skip the subagent dispatch
41
+ loop below and follow `<plugin-root>/routines/subagent-driven-development/references/farm-dispatch.md`.
42
+ The farm path replaces only the *authoring* step for the plan's tasks (cheap Zen workers under hard
43
+ gates instead of premium subagents); it does **not** replace review — every task the farm reports green
44
+ is still routed through Phases 3–5 before acceptance. The cost arbitrage is in who *writes* the code,
45
+ never in whether it is *reviewed*. In brief: select a model (canary-probe with a cache→websearch
46
+ fallback ladder), invoke the trusted `codearbiter_farm_preview` tool with the project-relative
47
+ plan path, honor a circuit-breaker abort as a hard-gate STOP, then for
48
+ each result either accept-after-Phases-3–5 (green) or re-dispatch via premium Phase 2 (escalate).
49
+ Results stream to `.farm/farm-results.jsonl` and are consumed in completion order — Phase 3 + Phase 5
50
+ per green task as it lands, Phase 4 still the once-per-scope barrier (reconcile against `farm-report.json`
51
+ on abort). The reference has the full step-by-step.
52
+
53
+ ---
54
+
55
+ **Normal path (no `plan.json`):** dispatch ONE fresh subagent for the selected task — `backend-author`, `frontend-author`, or
56
+ `infra-author` by the scope mapping in `tech-stack.md`
57
+ (`<plugin-root>/agents/<name>.md`). A fresh context per task is the whole point: no carried-over
58
+ assumptions, no accumulated drift.
59
+
60
+ The subagent works test-first by routing through the `tdd` skill (`<plugin-root>/routines/tdd/SKILL.md`) — no implementation code before
61
+ `tdd` Phase 1. Brief it with the task's path set, its spec obligation, and its verification command.
62
+ Nothing else from prior tasks leaks in.
63
+
64
+ Gate: the subagent reports `tdd` complete — all six phases green. A `tdd` BLOCK halts the loop; do not
65
+ re-dispatch around it.
66
+
67
+ ## Phase 3 — Spec-compliance review · gate: BLOCK
68
+
69
+ Did the change satisfy the task's obligation? Measure the result against the spec line the task
70
+ traces to — not against whether tests merely pass.
71
+
72
+ - Every acceptance claim in the task's obligation is met by the change.
73
+ - Scope is clean: nothing implemented beyond the task; nothing required by it omitted.
74
+ - Out-of-scope work the subagent noticed is recorded with an inline `[NEEDS-TRIAGE]` marker — never
75
+ acted on inside this task.
76
+
77
+ Gate: the obligation is fully satisfied and scope is clean. A shortfall returns the task to Phase 2
78
+ with a corrective brief.
79
+
80
+ ## Phase 4 — Quality review (once per scope) · gate: BLOCK
81
+
82
+ Runs ONCE per scope — after every task in the current scope has cleared Phase 3 and Phase 5 — over
83
+ the **combined diff** of the scope, not per 2–5-minute task. Per-task review at that granularity
84
+ costs more context than the work and catches nothing the batch diff doesn't; the batch boundary is
85
+ where review pays. (A scope of one task reviews that task's diff — same rule, degenerate case.)
86
+
87
+ Dispatch the reviewers applicable to what the combined diff touches, then `finding-triage`
88
+ (`<plugin-root>/agents/finding-triage.md`) to classify every finding by severity. Select
89
+ reviewers by the diff, not blanket — dispatching an irrelevant reviewer wastes a context:
90
+
91
+ - `security-reviewer` (`<plugin-root>/agents/security-reviewer.md`) — any security-relevant path (authn/authz, deploy, CI, trust boundary).
92
+ - `auth-crypto-reviewer` (`<plugin-root>/agents/auth-crypto-reviewer.md`) — auth, crypto, key, or secret changes.
93
+ - `dependency-reviewer` (`<plugin-root>/agents/dependency-reviewer.md`) — `package.json` / lockfile / base-image changes.
94
+ - `migration-reviewer` (`<plugin-root>/agents/migration-reviewer.md`) — DB migration add/modify.
95
+
96
+ (Do NOT dispatch `grader` or `scout` — they are INTERNAL to `decision-variance` and must never be
97
+ dispatched here.) If the change touches none of the above domains, the quality bar is `tdd`'s own gates
98
+ plus `coverage-auditor` (already run in `tdd` Phase 4) — record that and proceed.
99
+
100
+ - A security CRITICAL finding halts the loop — see Hard rules.
101
+ - A HIGH finding returns the offending task(s) — attributed by file — to Phase 2; the scope's
102
+ quality review re-runs over the corrected combined diff.
103
+ - MEDIUM and LOW findings are recorded; the user decides whether they block.
104
+
105
+ Gate: no CRITICAL, no HIGH across the scope's combined diff. Nothing in the scope is `ACCEPTED`
106
+ until this passes.
107
+
108
+ ## Phase 5 — Verification · gate: BLOCK
109
+
110
+ Verification-before-completion: apply the shared fresh-run discipline in
111
+ `<plugin-root>/includes/fresh-verification.md`, with **the task's verification command from the
112
+ plan** as the target. Run it yourself in a clean invocation; do not accept a logged result from Phase 2.
113
+ A non-zero exit, or output that does not demonstrate the obligation, returns the task to Phase 2.
114
+
115
+ Gate: the verification command exits clean and its output demonstrates the obligation. Only then.
116
+
117
+ ## Phase 6 — Accept and advance · gate: BLOCK
118
+
119
+ Mark the task `ACCEPTED` only when its spec-compliance review and fresh verification passed AND the
120
+ scope's Phase 4 quality review passed.
121
+ Record acceptance **in the plan file itself** — set the task's `status` cell in
122
+ `.codearbiter/plans/<slug>.md` to `ACCEPTED` the moment it is accepted, plus any `[NEEDS-TRIAGE]`
123
+ markers and the `.codearbiter/` audit trail. The plan's status column is the pipeline's resume
124
+ ledger: an interrupted run is re-entered at the first non-`ACCEPTED` task, and an acceptance that
125
+ lives only in conversation context is lost to the interruption.
126
+
127
+ - Tasks remain in the current scope → return to Phase 1.
128
+ - **Scoped invocation** (`scope` was passed by `executing-plans`): all scoped tasks `ACCEPTED` → signal
129
+ batch complete and return to `executing-plans`. Do NOT hand to `commit-gate`; the caller owns that decision.
130
+ - **Full-plan invocation** (no `scope`, i.e. `/sprint`): plan complete → hand the branch to
131
+ `commit-gate`, then to the caller's finishing step. The loop does not commit on its own authority.
132
+
133
+ Gate: every task in the current scope `ACCEPTED`, the suite green, ready for the caller's next step.
134
+
135
+ ## Hard rules
136
+
137
+ - MUST dispatch a fresh subagent per task — never reuse one context across tasks.
138
+ - MUST NOT write implementation code before the task's `tdd` Phase 1 completes.
139
+ - MUST accept a task only when both reviews pass AND verification passes on a fresh run.
140
+ - MUST NOT accept a task on a subagent's self-report — run the verification command and read its exit code.
141
+ - MUST halt and surface to the user on a `tdd` BLOCK, a security CRITICAL finding, or an unresolved `[CONFIRM-NN]` inside the loop — and on a `commit-gate` failure at the finish handoff — even under `/sprint`. These never auto-proceed.
142
+ - MUST NOT commit — hand the accepted branch to `commit-gate`.
143
+ - MUST mark out-of-scope findings with an inline `[NEEDS-TRIAGE]` marker and never act on them inside the task.
144
+ - MUST NOT invoke `farm.js` before writing `meta.model` into `plan.json` (or setting `FARM_MODEL`) — the dispatcher fails loudly otherwise.
145
+ - MUST NOT skip model selection (Step 1) when `FARM_MODEL` is not set — exhaust the canary→cache→websearch fallback ladder before BLOCKing; never blind-invoke with an unknown model id.
146
+ - MUST route every green farm task through Phases 3–5 before acceptance — the farm replaces authoring, never review. A cheap model gets the same scrutiny as a premium subagent, not less.
147
+ - MUST treat a single task's drift/gaming/tampered-test escalation as model incapacity (re-dispatch via premium Phase 2); raise `[CONFIRM-NN]` and HALT only when multiple tasks drift onto the same out-of-scope path (a real spec gap).
148
+ - MUST treat a `farm.js` circuit-breaker abort (`aborted: true`) as a hard-gate STOP — surface to the user; do not silently re-dispatch the whole slice to premium.
149
+ - MUST NOT dispatch `grader` or `scout` in Phase 4 — they are INTERNAL to `decision-variance`.
@@ -0,0 +1,145 @@
1
+ # Farm dispatch — reference for subagent-driven-development's farm path
2
+
3
+ Loaded from `subagent-driven-development` Phase 2 when `<slug>.plan.json` exists alongside the `.md`
4
+ plan. The farm is a pluggable execution backend — its value is deterministic, gated, parallel, isolated
5
+ execution. The farm path replaces only the *authoring* step for the plan's tasks — a worker implements
6
+ under hard gates instead of a premium subagent. The `Worker` seam admits cheap, premium, and agentic
7
+ implementations; only the cheap HTTP-chat worker ships today (premium and agentic are what the seam is
8
+ designed for — roadmap, not built). It does **not** replace review: every task the farm reports green is
9
+ still routed through Phases 3, 4, and 5 before acceptance. Swapping the worker only changes who *writes*
10
+ the code, never whether it is *reviewed*. See `<plugin-root>/includes/farm.md` for setup.
11
+
12
+ ## Step 1 — Model selection
13
+
14
+ If `FARM_MODEL` env var is set, use it directly and skip selection. Otherwise, prefer a **measured**
15
+ choice over web hearsay:
16
+
17
+ 1. Read `.farm/model-cache.json` if present. If it records a model chosen within the last 7 days whose
18
+ last canary pass-rate was acceptable, reuse it (skip to Step 2). Re-research only on a stale or
19
+ missing cache.
20
+ 2. Websearch `"OpenCode Zen free models <current month year>"` + the OpenCode model catalog to enumerate
21
+ the *candidate* free model ids (codenames included). This step is candidate **discovery**, not a
22
+ quality judgment.
23
+ 3. Run a canary probe to judge quality objectively: set `FARM_CANDIDATE_MODELS=<comma-separated ids>`
24
+ and call `codearbiter_farm_preview` with the project-relative plan plus
25
+ `canary: true`. It runs the plan's
26
+ smallest task against each candidate and writes `.farm/canary-report.json` ranked by measured
27
+ pass-rate / attempts / latency. Pick the top passing model.
28
+ 4. Surface the choice with its measured basis: "Selected `<model-id>` — canary passed in `<n>` attempts,
29
+ `<ms>`ms (vs. `<alternatives>`). Proceed, or set `FARM_MODEL` to override." For any opaque codename,
30
+ add one line of websearched identity context (e.g. "community reports GLM4-based") for the audit log.
31
+ 5. Fallback ladder if the canary can't run or none pass: (a) the cached model from Step 1; (b) a
32
+ websearch-selected model with a clear warning that the choice is unmeasured; (c) only if all fail,
33
+ BLOCK and ask the user to set `FARM_MODEL`. Halting the whole feature on a noisy websearch is wrong —
34
+ exhaust the ladder first.
35
+ 6. Write the chosen `meta.model` + `meta.apiBaseUrl` into `plan.json`, and update `.farm/model-cache.json`
36
+ (model + timestamp + canary pass-rate) before dispatching.
37
+
38
+ ## Step 2 — Farm dispatch
39
+
40
+ Invoke the farm dispatcher:
41
+
42
+ Call the trusted `codearbiter_farm_preview` tool with:
43
+
44
+ ```json
45
+ { "plan": ".codearbiter/plans/<slug>.plan.json" }
46
+ ```
47
+
48
+ For the measured canary step, add `"canary": true`. The tool resolves the one shared built backend;
49
+ if it reports `terminal: degraded`, surface that preview degradation and rebuild the sibling bundle.
50
+ Do not shell out to a Pi-local farm dispatcher — this host ships none, so any path you construct for one resolves to nothing — and do not fall back silently.
51
+
52
+
53
+ Run it with cwd set to `<project-root>` (the dispatcher resolves `.farm/` and git worktrees
54
+ against the current directory). It runs tasks concurrently (up to `FARM_CONCURRENCY`, default 4),
55
+ enforces gates and a zero-token anti-gaming guard, and writes to `<project-root>/.farm/`:
56
+ - `farm-report.json` / `farm-report.md` — per-task status, attempts, files, worker token spend, warnings
57
+ - `farm-results.jsonl` — the incremental stream: one `Result` JSON object per line, appended the moment
58
+ each task settles (drives completion-order consumption — see Step 2.6)
59
+ - `diffs/<task-id>.patch` — the actual change per task, for audit
60
+
61
+ Each of those is published twice: once under the run's own artifact directory
62
+ `<project-root>/.farm/runs/<run-id>/` (the durable, attributable receipt — concurrent runs never
63
+ overwrite each other's artifacts) and once at the top-level `.farm/` path above as a **latest**
64
+ convenience pointer. The final summary line prints both. When two runs may share a repository, reconcile
65
+ against the run directory; the pointer is last-writer-wins (always complete, never truncated).
66
+
67
+ Isolated receipts are not a licence to run two farms on one repository unattended: the git state is
68
+ still shared. Concurrent runs each need a distinct `FARM_INTEGRATION_BRANCH` and `FARM_WORKTREE_ROOT`,
69
+ and non-overlapping task ids (each task branch is `farm/<task-id>`). At defaults the second run fails at
70
+ startup on `cannot lock ref 'refs/heads/farm/integration'`.
71
+
72
+ Exit code 0 = all green; exit code 2 = some tasks escalated, blocked, or the run was aborted;
73
+ **exit code 3 = the run's authoritative, run-scoped report could not be published in full.** Exit 3 is a
74
+ RECEIPT failure, not a task failure — the tasks may all have been green — and it means this run's
75
+ durable record is missing or incomplete. Treat the run as unverified and re-dispatch; do not accept
76
+ tasks off a run that exited 3. Inspect `.farm/runs/<run-id>/` for whatever did land before discarding.
77
+
78
+ A failure to refresh the top-level **latest** pointer is *not* exit 3 — that pointer is explicitly
79
+ non-authoritative. The run settles on its task outcome and prints a `WARNING:` naming what could not be
80
+ refreshed; when you see it, `.farm/farm-report.json` describes some *other* run, so read the run
81
+ directory.
82
+
83
+ `farm-report.json` also carries an `artifacts` block: `artifacts.stream.complete` is `false` when a
84
+ streaming-rail write failed (so a short `.jsonl` is not mistaken for a short run), and
85
+ `artifacts.diffs.unavailable[]` names tasks whose patch could not be written, with the reason. That
86
+ list is capped — `artifacts.diffs.unavailable_total` is the true count. Never assume a
87
+ `diffs/<task-id>.patch` exists for a task listed there.
88
+
89
+ ## Step 2.5 — Circuit-breaker abort
90
+
91
+ If `farm-report.json` has `aborted: true`, the dispatcher tripped its escalation-rate breaker — the
92
+ chosen model is likely not capable of this slice. This is a hard-gate surface: STOP and tell the user,
93
+ recommending the premium path or a different `FARM_MODEL`. Do not silently re-dispatch every task to
94
+ premium Phase 2 (that defeats the backend's purpose and hides a bad signal).
95
+
96
+ ## Step 2.6 — Streaming consumption contract
97
+
98
+ The dispatcher writes two artifacts (D7): the incremental `farm-results.jsonl` stream and the final
99
+ `farm-report.json` summary. The escalation/acceptance handler (Step 3) MUST consume the stream in
100
+ **completion order** — read `farm-results.jsonl` line by line (one `Result` JSON object per line) and
101
+ process each task the moment it settles, rather than waiting to parse only the final report. Each
102
+ `green` task is routed through **Phase 3 (spec-compliance) + Phase 5 (verification)** as it lands.
103
+
104
+ - **Per-green-task = Phase 3 + Phase 5 only.** Only the spec-compliance and fresh-verification reviews
105
+ run per green task as it streams in.
106
+ - **Phase 4 stays a once-per-scope barrier.** The quality review (Phase 4) MUST NOT be pipelined per
107
+ task — it still runs ONCE over the combined diff of the whole scope, after every task has cleared
108
+ Phase 3 and Phase 5. The streaming rail moves Phase 3 + Phase 5 earlier; it does NOT move Phase 4.
109
+ - **`farm-report.json` is authority on abort (D7).** `farm-report.json` is always written in the
110
+ dispatcher's `finally` — even on a circuit-breaker abort or crash — and remains the AUTHORITATIVE
111
+ final summary. On an abort or crash, reconcile settled-task state against `farm-report.json`, NOT the
112
+ partial `.jsonl` stream. The stream is an append-only progress feed; the report is the source of truth.
113
+ - **Temporal overlap is roadmap, not today.** `farm.js` runs in the foreground, so the consumer
114
+ processes the stream in completion order *after* the run returns — true *temporal* overlap (running
115
+ review WHILE the farm is still executing) requires backgrounding `farm.js` and is explicitly a
116
+ future/roadmap item. The streaming rail is the enabling primitive, not the full overlap yet.
117
+
118
+ ## Step 3 — Escalation handler (Phase 2.5)
119
+
120
+ Consume `farm-results.jsonl` in completion order (Step 2.6); `farm-report.json` is the authoritative
121
+ reconciliation source on abort. For each result:
122
+
123
+ - **status `green`** — the test gate + anti-gaming guard passed, but it is NOT yet accepted. Route the
124
+ task through **Phase 3 (spec-compliance), Phase 4 (quality review), and Phase 5 (fresh verification)**
125
+ exactly as a premium subagent's output would be, measuring the merged change against the spec line the
126
+ task traces to. A green result carrying a `warning` (gaming-risk) gets extra attention in Phase 3.
127
+ Only after Phases 3–5 pass does the task reach Phase 6.
128
+ - **status `escalate`, note starts with `"drift:"`** — the cheap model wrote outside `filesInScope`
129
+ even after a hardened-prompt retry. First occurrence on a task → treat as model incapacity, not a spec
130
+ gap: re-dispatch via premium Phase 2 (the worktree at `result.worktree` shows the attempt). Only when
131
+ **multiple tasks drift onto the same out-of-scope path** does it signal a genuine decomposition/spec
132
+ gap — then raise `[CONFIRM-NN]` and halt.
133
+ - **status `escalate`, note starts with `"gaming:"`** — the model hard-coded the test's asserted value.
134
+ Re-dispatch via premium Phase 2; do not accept the farm output.
135
+ - **status `escalate`, note starts with `"tampered test:"`** — the model altered the failing test.
136
+ Re-dispatch via premium Phase 2; the test is the gate's integrity anchor.
137
+ - **status `escalate`, gate-failure note** — the model couldn't pass the test after retries. Re-dispatch
138
+ via premium Phase 2, seeding the brief with `result.worktree`, the gate note, and `test.path`.
139
+ - **status `escalate`, note starts with `"merge failed"`** — re-order after the conflicting sibling and
140
+ re-dispatch via Phase 2.
141
+ - **blocked** tasks (`farm-report.json` `blocked[]` array, each with a `reason`) — resolve the upstream
142
+ escalation first, then re-queue.
143
+
144
+ Gate: every task is green AND passed Phases 3–5, or was re-dispatched via premium Phase 2 and accepted.
145
+ No task advances to commit-gate while any sibling is unresolved.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: tdd
3
+ description: The test-first gate. Routed to by /feature (after the spec is approved), /fix, and /refactor before any implementation code is written. Six gated phases — obligation scan, red, green, obligation verify, coverage, lint. No feature code exists before Phase 1 clears; nothing reaches commit-gate until all six are green.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # tdd
8
+
9
+ Test-first, or it does not ship. Routed to by `/feature` (after spec approval), `/fix`, and `/refactor`.
10
+
11
+ ## Pre-flight
12
+
13
+ Read these, or STOP and surface the gap — never guess a command or a threshold:
14
+
15
+ - `<project-root>/.codearbiter/CONTEXT.md` — the `stage:` frontmatter (the maturity value) and project context.
16
+ - `<project-root>/.codearbiter/tech-stack.md` — test, coverage, and lint invocations; file layout; mock patterns.
17
+ - `<project-root>/.codearbiter/coding-standards.md` — style, structure, naming. Required for Phase 3.
18
+ - `<project-root>/.codearbiter/specs/<slug>.md` — the approved spec, when `/feature` produced one. It is the primary obligation source.
19
+ - `<project-root>/.codearbiter/security-controls.md` — only when the change touches a security boundary (auth, crypto, secrets, a trust boundary). Optional; absent on most changes.
20
+ - `<project-root>/.codearbiter/code-map.md` — if present, a coarse concern→path→role map to orient before writing tests and code. Absent is fine — it is read-on-demand, populated by context-creation or commit-gate heal.
21
+
22
+ ## Phase 1 — Obligation scan · gate: BLOCK
23
+
24
+ An **obligation** is one verifiable claim about the change: (a) a unique ID, (b) a source citation,
25
+ (c) a status. Status moves `OPEN → MAPPED → COVERED`; an obligation Phase 4 cannot tie to a passing
26
+ test is `MISSING`. "We should test X" is not an obligation.
27
+
28
+ Derive every obligation before any code is written, and record each as `ID · source · OPEN`:
29
+
30
+ - **Spec** — one obligation per acceptance criterion in the approved spec.
31
+ - **Contract** — API and input-validation invariants, error responses, boundary conditions.
32
+ - **Security** — only when `security-controls.md` applies: the assertion that the security-relevant boundary holds.
33
+
34
+ Gate: the obligation list is complete. **Auto-pass** when every obligation maps one-to-one onto the
35
+ acceptance criteria of an already-approved spec (full-lane spec or small-lane mini-spec) — the user
36
+ approved that list once; do not re-ask. **User review is required** only for obligations derived
37
+ BEYOND the spec (Contract and Security rows): surface just those additions, not the whole list.
38
+ Under `/sprint`, spec-derived obligations auto-pass the same way and beyond-spec additions are
39
+ SMARTS-decided and logged like any other auto-decision. A partial list never passes either way.
40
+
41
+ ## Phase 2 — Red · gate: BLOCK
42
+
43
+ Write one or more failing tests per obligation. Bind each test ID to its obligation ID and move that
44
+ obligation `OPEN → MAPPED`. Run the test command from `tech-stack.md`.
45
+
46
+ - Every new test MUST fail, and fail **for the right reason** — the assertion, not an import error or a typo. A new test that passes with no implementation is wrong; fix it before continuing.
47
+ - Every pre-existing test MUST stay green. One that breaks here is a conflict — stop and surface it.
48
+
49
+ Reject the standard traps: asserting on a mock instead of behavior; a test that can never fail; a
50
+ snapshot so broad it asserts nothing; coupling to an implementation detail instead of observable
51
+ behavior; asserting on the framework's behavior rather than your own.
52
+
53
+ The reasons to skip red are known. Hearing one is the tell that this gate is about to be waived —
54
+ never the license to waive it:
55
+
56
+ | excuse | reality |
57
+ |---|---|
58
+ | "Too simple to fail first." | Simple changes have the cheapest red tests — and "too simple to test" and "too simple to break" have never been the same claim. |
59
+ | "I'll write the test right after." | A test written after green has never been seen red: it is authored against the implementation it was meant to constrain, and its power to catch the bug is never demonstrated. |
60
+ | "The test would just restate the implementation." | Then it is aimed at the wrong seam — assert the observable behavior, not the wiring. A change with no observable behavior to assert is a design finding, not an exemption. |
61
+ | "The existing suite already covers this." | Then the failing test is impossible to write — try it. If it genuinely cannot go red, the obligation is already COVERED and Phase 4 records exactly that; if it goes red, the claim was wrong and you are holding the proof. |
62
+
63
+ Gate: the runner confirms new tests red (for the right reason) and existing tests green, with every
64
+ obligation `MAPPED` to a failing test. No implementation code is written until this gate clears.
65
+
66
+ ## Phase 3 — Green · gate: BLOCK
67
+
68
+ Write the **minimum** implementation that satisfies the Phase 2 tests — no speculative logic, no
69
+ gold-plating — to the conventions in `coding-standards.md`. Run the full suite. A broken pre-existing
70
+ test is a regression: fix it.
71
+
72
+ Gate: full suite green, reached by satisfying the Phase 2 tests — not by weakening them. A test's
73
+ assertions MUST be unchanged between red and green; only fixtures and setup may move. A relaxed
74
+ assertion is a gate violation.
75
+
76
+ ## Phase 4 — Obligation verify · gate: BLOCK
77
+
78
+ Walk the Phase 1 list item by item. Each `MAPPED` obligation moves to `COVERED` (a real passing test
79
+ that exercises the claim) or `MISSING` (no test truly covers it). For security-relevant or
80
+ contract-critical logic, dispatch the `coverage-auditor` agent
81
+ (`<plugin-root>/agents/coverage-auditor.md`) to confirm the tests exercise the claim.
82
+
83
+ A `MISSING` obligation returns the workflow to Phase 2 — author a correct failing test, then re-run
84
+ Phase 3 — and loops until it is `COVERED`.
85
+
86
+ **Stakes:** when you block on a `MISSING` obligation, state what the untested seam leaves exposed, not
87
+ just that it is `MISSING` — one line naming the consequence: "this error path is untested; a 500 here
88
+ would reach users silently." The block is the rule; the stakes are why it is worth the friction.
89
+
90
+ Gate: every obligation `COVERED`, each backed by a passing test. Any `MISSING` blocks Phase 5.
91
+
92
+ ## Phase 5 — Coverage · gate: BLOCK
93
+
94
+ Coverage scales with the maturity value (`stage:` in `CONTEXT.md`) — a rigor knob, not a promotion
95
+ gate. The threshold table is the shared `<plugin-root>/includes/maturity-coverage.md` (the
96
+ single source of truth, also used by `refactor` Phase 2).
97
+
98
+ Run the coverage command from `tech-stack.md`. **Lines and branches must both clear the threshold**
99
+ — a report satisfying one and not the other does not pass (issue #507). Below it on either → add
100
+ tests until both are met.
101
+
102
+ **Name the host you measured on**, and for a tree `tech-stack.md` marks as platform-forked, the
103
+ figure is the UNION across its supported hosts — a single-host report scores the other platform's
104
+ arm as permanently uncovered (issue #521, conditions in `<plugin-root>/includes/maturity-coverage.md`).
105
+ Where only one host is available, say so and name what is missing rather than quoting it as the
106
+ whole.
107
+
108
+ Where the surface has no coverage tooling at all, take the no-tooling exemption in
109
+ `<plugin-root>/includes/maturity-coverage.md` — which requires QUOTING the `tech-stack.md`
110
+ Coverage section that omits a command for this surface — and pass the phase on the Phase 4
111
+ obligation verify alone. Without that citation the phase STOPs: "I could not find the command" and
112
+ "this surface has none" look identical from here and demand opposite responses. Do NOT invent a
113
+ command, and do NOT silently skip the phase as though it had been run — a gate that cannot execute
114
+ still reads as satisfied, which is worse than an absent one.
115
+
116
+ **Stakes:** when coverage blocks below threshold, name the class of code left dark — the paths a later
117
+ regression could rot unnoticed — not just "below threshold." The number is the rule; the untested paths
118
+ are why it matters.
119
+
120
+ Gate: threshold met on BOTH lines and branches for the current maturity value, or the no-tooling
121
+ exemption taken WITH its citation. A test added only to move the percentage fails this gate in
122
+ spirit — it converts an honest red into a green that asserts nothing.
123
+
124
+ ## Phase 6 — Lint · gate: BLOCK
125
+
126
+ Run lint, and the type-check if the project is statically typed, from `tech-stack.md`. Resolve every
127
+ error.
128
+
129
+ Gate: clean lint and type-check, zero errors — this is what clears the path to `commit-gate`.
130
+ "Mostly passes" is not passing.
131
+
132
+ ## Hard rules
133
+
134
+ - MUST NOT skip, suppress, or comment out a test to clear any gate.
135
+ - MUST NOT mark an obligation `COVERED` without a passing test that exercises the claim.
136
+ - MUST NOT lower a coverage threshold without a decision recorded in `CONTEXT.md`.
137
+ - MUST NOT inline-suppress a lint rule without a written reason, and never to bypass a security-relevant rule.
138
+ - MUST NOT guess the test, coverage, or lint command — read `tech-stack.md` or STOP.
139
+ - MUST, at exit, run the follow-up harvest (`<plugin-root>/includes/harvest.md`) over any `[NEEDS-TRIAGE]` raised this run — batch-confirm promoting work to `open-tasks.md` and decisions to `open-questions.md` so nothing languishes; nothing auto-promotes interactively.