devflow-kit 3.11.0 → 3.12.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 (204) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/agents/architect.md +87 -0
  3. package/dist/agents/code.md +21 -25
  4. package/dist/agents/debug.md +21 -49
  5. package/dist/agents/design.md +9 -43
  6. package/dist/agents/fix.md +15 -29
  7. package/dist/agents/git.md +19 -22
  8. package/dist/agents/harden.md +14 -19
  9. package/dist/agents/knowledge.md +11 -19
  10. package/dist/agents/refactor.md +9 -14
  11. package/dist/agents/research.md +11 -34
  12. package/dist/agents/review.md +22 -52
  13. package/dist/agents/skim.md +7 -17
  14. package/dist/agents/triage.md +7 -14
  15. package/dist/commands/bug-analysis.md +31 -62
  16. package/dist/commands/code-review.md +38 -87
  17. package/dist/commands/debug.md +32 -82
  18. package/dist/commands/dynamic-build.md +155 -211
  19. package/dist/commands/dynamic-plan.md +71 -93
  20. package/dist/commands/dynamic-profile.md +7 -155
  21. package/dist/commands/dynamic-tickets.md +65 -186
  22. package/dist/commands/explore.md +27 -70
  23. package/dist/commands/implement.md +98 -186
  24. package/dist/commands/plan.md +60 -107
  25. package/dist/commands/release.md +25 -91
  26. package/dist/commands/research.md +34 -103
  27. package/dist/commands/resolve.md +64 -128
  28. package/dist/commands/self-review.md +35 -99
  29. package/dist/compliance-off/agents/git.md +15 -18
  30. package/dist/compliance-off/agents/triage.md +7 -14
  31. package/dist/compliance-off/commands/bug-analysis.md +31 -62
  32. package/dist/compliance-off/commands/code-review.md +34 -82
  33. package/dist/compliance-off/commands/dynamic-build.md +149 -205
  34. package/dist/compliance-off/commands/dynamic-tickets.md +65 -186
  35. package/dist/compliance-off/commands/implement.md +94 -180
  36. package/dist/compliance-off/commands/plan.md +60 -107
  37. package/dist/compliance-off/commands/release.md +25 -90
  38. package/dist/compliance-off/commands/resolve.md +54 -128
  39. package/dist/compliance-off/skills/git/references/tracker/github/ensure-pr-ready.md +3 -3
  40. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-pr-ready.md +3 -3
  41. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-pr-ready.md +3 -3
  42. package/dist/core/plugins.js +3 -3
  43. package/dist/curation-compliance-off/agents/triage.md +7 -13
  44. package/dist/curation-compliance-off/commands/bug-analysis.md +21 -41
  45. package/dist/curation-compliance-off/commands/code-review.md +25 -62
  46. package/dist/curation-compliance-off/commands/dynamic-build.md +142 -194
  47. package/dist/curation-compliance-off/commands/dynamic-tickets.md +54 -173
  48. package/dist/curation-compliance-off/commands/implement.md +86 -161
  49. package/dist/curation-compliance-off/commands/plan.md +51 -86
  50. package/dist/curation-compliance-off/commands/release.md +17 -78
  51. package/dist/curation-compliance-off/commands/resolve.md +45 -108
  52. package/dist/curation-off/agents/architect.md +81 -0
  53. package/dist/curation-off/agents/code.md +20 -23
  54. package/dist/curation-off/agents/debug.md +19 -47
  55. package/dist/curation-off/agents/design.md +8 -41
  56. package/dist/curation-off/agents/fix.md +14 -27
  57. package/dist/curation-off/agents/harden.md +13 -18
  58. package/dist/curation-off/agents/knowledge.md +9 -17
  59. package/dist/curation-off/agents/refactor.md +8 -12
  60. package/dist/curation-off/agents/research.md +9 -32
  61. package/dist/curation-off/agents/review.md +11 -40
  62. package/dist/curation-off/agents/skim.md +7 -17
  63. package/dist/curation-off/agents/triage.md +7 -13
  64. package/dist/curation-off/commands/bug-analysis.md +21 -41
  65. package/dist/curation-off/commands/code-review.md +29 -67
  66. package/dist/curation-off/commands/debug.md +24 -63
  67. package/dist/curation-off/commands/dynamic-build.md +148 -200
  68. package/dist/curation-off/commands/dynamic-plan.md +60 -80
  69. package/dist/curation-off/commands/dynamic-tickets.md +54 -173
  70. package/dist/curation-off/commands/explore.md +18 -50
  71. package/dist/curation-off/commands/implement.md +90 -167
  72. package/dist/curation-off/commands/plan.md +51 -86
  73. package/dist/curation-off/commands/release.md +17 -79
  74. package/dist/curation-off/commands/research.md +23 -81
  75. package/dist/curation-off/commands/resolve.md +55 -108
  76. package/dist/curation-off/commands/self-review.md +26 -78
  77. package/dist/skills/git/references/pr/update-pr-evidence.md +2 -1
  78. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +3 -3
  79. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +3 -3
  80. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +3 -3
  81. package/dist/targets/claude-code/curation-install.js +2 -2
  82. package/dist/variant-axes.json +5 -1
  83. package/package.json +1 -1
  84. package/src/assets/agents/_partials/_code.mds +3 -5
  85. package/src/assets/agents/_partials/_design.mds +86 -0
  86. package/src/assets/agents/architect.mds +41 -0
  87. package/src/assets/agents/code.mds +18 -20
  88. package/src/assets/agents/curate.md +26 -35
  89. package/src/assets/agents/debug.mds +21 -49
  90. package/src/assets/agents/design.mds +11 -114
  91. package/src/assets/agents/evaluate.md +6 -16
  92. package/src/assets/agents/explore.md +1 -2
  93. package/src/assets/agents/fix.mds +12 -24
  94. package/src/assets/agents/git.mds +20 -23
  95. package/src/assets/agents/harden.mds +14 -19
  96. package/src/assets/agents/knowledge.mds +10 -38
  97. package/src/assets/agents/polish.md +13 -39
  98. package/src/assets/agents/refactor.mds +6 -9
  99. package/src/assets/agents/research.mds +11 -34
  100. package/src/assets/agents/review.mds +12 -84
  101. package/src/assets/agents/skim.mds +7 -17
  102. package/src/assets/agents/synthesize.md +3 -21
  103. package/src/assets/agents/test.md +31 -32
  104. package/src/assets/agents/tracker.md +116 -229
  105. package/src/assets/agents/triage.mds +7 -26
  106. package/src/assets/agents/validate.md +1 -3
  107. package/src/assets/commands/_partials/_compliance.mds +2 -2
  108. package/src/assets/commands/_partials/_decisions.mds +17 -24
  109. package/src/assets/commands/_partials/_docs_root.mds +31 -10
  110. package/src/assets/commands/_partials/_engine.mds +34 -56
  111. package/src/assets/commands/_partials/_evidence_policy.mds +1 -1
  112. package/src/assets/commands/_partials/_factory.mds +10 -104
  113. package/src/assets/commands/_partials/_knowledge.mds +47 -51
  114. package/src/assets/commands/_partials/_plan_contract.mds +2 -2
  115. package/src/assets/commands/_partials/_preamble.mds +21 -21
  116. package/src/assets/commands/_partials/_publication.mds +3 -3
  117. package/src/assets/commands/_partials/_roster.mds +12 -13
  118. package/src/assets/commands/_partials/_settings.mds +6 -3
  119. package/src/assets/commands/_partials/_ticket_template.mds +3 -7
  120. package/src/assets/commands/_partials/_tracker.mds +10 -5
  121. package/src/assets/commands/_partials/_wave.mds +23 -32
  122. package/src/assets/commands/bug-analysis.mds +3 -7
  123. package/src/assets/commands/code-review.mds +12 -33
  124. package/src/assets/commands/debug.mds +5 -47
  125. package/src/assets/commands/dynamic-build.mds +48 -70
  126. package/src/assets/commands/dynamic-plan.mds +23 -42
  127. package/src/assets/commands/dynamic-profile.mds +7 -57
  128. package/src/assets/commands/dynamic-tickets.mds +9 -29
  129. package/src/assets/commands/explore.mds +5 -44
  130. package/src/assets/commands/implement.mds +75 -117
  131. package/src/assets/commands/plan.mds +27 -57
  132. package/src/assets/commands/release.mds +4 -62
  133. package/src/assets/commands/research.mds +7 -53
  134. package/src/assets/commands/resolve.mds +40 -87
  135. package/src/assets/commands/self-review.mds +5 -45
  136. package/src/assets/mds/git/_ops_pr.mds +1 -0
  137. package/src/assets/mds/git/_ops_steps.mds +4 -4
  138. package/src/assets/mds/git/_pr.mds +1 -1
  139. package/src/assets/rules/engineering.md +1 -1
  140. package/src/assets/rules/quality.md +2 -2
  141. package/src/assets/scripts/ci-wait.cjs +150 -18
  142. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +3 -3
  143. package/src/assets/scripts/hooks/preamble +2 -3
  144. package/src/assets/scripts/pr-evidence.cjs +1 -0
  145. package/src/assets/scripts/resolve-evidence-policy.cjs +14 -13
  146. package/src/assets/scripts/resolve-root.cjs +186 -0
  147. package/src/assets/scripts/resolve-settings.cjs +14 -9
  148. package/src/assets/scripts/verify-evidence.cjs +355 -22
  149. package/src/assets/skills/accessibility/SKILL.md +28 -95
  150. package/src/assets/skills/agent-references/SKILL.md +2 -4
  151. package/src/assets/skills/agent-references/references/commands/implement-evidence-asks.md +1 -1
  152. package/src/assets/skills/agent-references/references/commands/implement-levels.md +4 -7
  153. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +1 -1
  154. package/src/assets/skills/agent-references/references/commands/plan-levels.md +2 -2
  155. package/src/assets/skills/apply-decisions/SKILL.md +5 -6
  156. package/src/assets/skills/apply-feature-knowledge/SKILL.md +3 -13
  157. package/src/assets/skills/architecture/SKILL.md +29 -105
  158. package/src/assets/skills/boundary-validation/SKILL.md +27 -78
  159. package/src/assets/skills/complexity/SKILL.md +8 -104
  160. package/src/assets/skills/compliance/SKILL.md +9 -67
  161. package/src/assets/skills/consistency/SKILL.md +7 -107
  162. package/src/assets/skills/database/SKILL.md +7 -72
  163. package/src/assets/skills/dependencies/SKILL.md +9 -109
  164. package/src/assets/skills/dependencies/references/detection.md +10 -0
  165. package/src/assets/skills/dependency-research/SKILL.md +9 -63
  166. package/src/assets/skills/design-review/SKILL.md +1 -35
  167. package/src/assets/skills/docs-framework/SKILL.md +4 -47
  168. package/src/assets/skills/documentation/SKILL.md +7 -71
  169. package/src/assets/skills/documentation/references/patterns.md +1 -1
  170. package/src/assets/skills/documentation/references/violations.md +1 -1
  171. package/src/assets/skills/feature-knowledge/SKILL.md +19 -222
  172. package/src/assets/skills/feature-knowledge/references/new-kb.md +128 -0
  173. package/src/assets/skills/gap-analysis/SKILL.md +1 -31
  174. package/src/assets/skills/git/SKILL.md +2 -22
  175. package/src/assets/skills/go/SKILL.md +24 -113
  176. package/src/assets/skills/java/SKILL.md +12 -98
  177. package/src/assets/skills/patterns/SKILL.md +8 -93
  178. package/src/assets/skills/performance/SKILL.md +29 -88
  179. package/src/assets/skills/python/SKILL.md +22 -120
  180. package/src/assets/skills/qa/SKILL.md +16 -54
  181. package/src/assets/skills/qa/references/browser-testing.md +0 -24
  182. package/src/assets/skills/qa/references/sources.md +2 -2
  183. package/src/assets/skills/quality-gates/SKILL.md +13 -100
  184. package/src/assets/skills/react/SKILL.md +33 -95
  185. package/src/assets/skills/regression/SKILL.md +8 -73
  186. package/src/assets/skills/reliability/SKILL.md +11 -120
  187. package/src/assets/skills/research-codebase/SKILL.md +7 -49
  188. package/src/assets/skills/research-competitor/SKILL.md +4 -39
  189. package/src/assets/skills/research-external/SKILL.md +5 -43
  190. package/src/assets/skills/research-market/SKILL.md +5 -43
  191. package/src/assets/skills/research-technology/SKILL.md +8 -68
  192. package/src/assets/skills/review-methodology/SKILL.md +10 -56
  193. package/src/assets/skills/rust/SKILL.md +19 -109
  194. package/src/assets/skills/security/SKILL.md +39 -66
  195. package/src/assets/skills/software-design/SKILL.md +20 -105
  196. package/src/assets/skills/software-design/references/patterns.md +84 -2
  197. package/src/assets/skills/software-design/references/violations.md +1 -1
  198. package/src/assets/skills/test-driven-development/SKILL.md +32 -107
  199. package/src/assets/skills/test-driven-development/references/rationalization-prevention.md +33 -1
  200. package/src/assets/skills/testing/SKILL.md +35 -53
  201. package/src/assets/skills/typescript/SKILL.md +23 -102
  202. package/src/assets/skills/ui-design/SKILL.md +26 -74
  203. package/src/assets/skills/worktree-support/SKILL.md +4 -10
  204. package/dist/curation-off/commands/dynamic-profile.md +0 -214
@@ -1,14 +1,24 @@
1
+ @import { root_paths } from "./_docs_root.mds"
2
+
1
3
  A partial: the decisions-index steps the knowledge-workflow commands and the
2
4
  dynamic commands share.
3
5
 
6
+ `decisions_locate()` names where the ledger belongs and expands
7
+ the shared `root_paths()` step of `_docs_root.mds`. One `resolve-root.cjs` call, run once per
8
+ run, prints `LEDGER=`: the main worktree when the checkout is a linked worktree whose main
9
+ worktree holds a `.devflow/` folder that is not the home directory, else the toplevel, else
10
+ the start directory. That is the rule the curation hooks apply, so a command reads the index
11
+ the Curate agent writes. The import is selective and takes `root_paths` alone: that define has
12
+ no imports of its own, so it adds one node to the scope of each define here.
13
+
4
14
  D-DECISIONS-LEARNING-GATE: a decisions load is gated on the settings line's
5
15
  `CURATION`. Curation can be narrowed by the repository or the machine, and neither
6
16
  can turn it back on (D-FEATURES-NARROW-ONLY). The settings line also reads
7
17
  `CURATION=off` while git tracks the curation folders, or does not answer for them:
8
18
  the files there are the repository's own content, and devflow reads nothing in a
9
19
  folder it cannot tell is its own. So `decisions_gate()` is the one sentence every
10
- decisions host carries: with `CURATION=off` the step is skipped before it locates a
11
- ledger or reads an index. An unresolvable settings line reads `CURATION=off`, as the
20
+ decisions host carries: with `CURATION=off` the step is skipped before it reads an index (the shared
21
+ root step may already have named the ledger folder, but reads no file in it). An unresolvable settings line reads `CURATION=off`, as the
12
22
  fail-closed line does, because a failed resolution cannot show what git tracks. The
13
23
  gate reads the line the host's settings block resolved above; this partial imports
14
24
  nothing from `_settings.mds`. In a multi-worktree run the line is the start root's:
@@ -33,23 +43,13 @@ the gate and the locator, reached only from inside a curation-on arm, so a curat
33
43
  none of the rule (D-LEARNING-VARIANTS).
34
44
 
35
45
  @define decisions_gate():
36
- When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
46
+ When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, reading no index.
37
47
  @end
38
48
 
39
49
  @define decisions_locate():
40
- The decisions ledger belongs to the repository, not to one checkout: a linked worktree reads the main worktree's copy, a subdirectory session the repository root's. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
41
-
42
- ```bash
43
- git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
44
- ```
45
-
46
- Line 1 is the checkout's toplevel, line 2 the common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first that applies:
50
+ The decisions ledger belongs to the repository, not to one checkout: a linked worktree reads the main worktree's copy.
47
51
 
48
- 1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
49
- 2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
50
- 3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
51
-
52
- This is the rule the curation hooks apply, so you read the index the Curate agent writes.
52
+ {{root_paths()}}
53
53
  @end
54
54
 
55
55
  @define decisions_slice():
@@ -64,14 +64,9 @@ Hand each agent that takes `DECISIONS_CONTEXT` a slice, not the whole index: the
64
64
 
65
65
  {{decisions_locate()}}
66
66
 
67
- **Step 1 — Read the pre-rendered index:**
68
-
69
- Attempt to read `{ledger}/.devflow/curation/index.md`.
67
+ **Step 1 — Read the pre-rendered index** `{ledger}/.devflow/curation/index.md`. Its content is `DECISIONS_CONTEXT`; if it is absent or empty, `DECISIONS_CONTEXT` is `(none)`.
70
68
 
71
- - If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
72
- - If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
73
-
74
- The index is one direct file read, written at render time by `render-decisions.cjs` — no `.cjs` script runs here.
69
+ The index is one direct file read.
75
70
 
76
71
  **Step 2 — Slice the index, then hand it on:**
77
72
 
@@ -79,8 +74,6 @@ When `DECISIONS_CONTEXT` is not `(none)`, hand it only to the agents whose contr
79
74
 
80
75
  {{decisions_slice()}}
81
76
 
82
- Those agents follow `devflow:apply-decisions`. A host that uses the index in its own thread says so in its own step.
83
-
84
77
  <!-- curation:end -->
85
78
  @end
86
79
 
@@ -1,4 +1,18 @@
1
- A partial: where a command's `.devflow/docs/` artifacts live (D-DOCS-ROOT, #406).
1
+ A partial: where a command's roots are, and where its `.devflow/docs/` artifacts live (D-DOCS-ROOT, #406).
2
+
3
+ `root_paths()` is the one step that resolves both roots a command works from. One call
4
+ of `resolve-root.cjs` prints `WORKTREE=` (the checkout's toplevel, else the start
5
+ directory) and `LEDGER=` (the decisions ledger's root: the main worktree when the
6
+ checkout is a linked worktree and the main worktree holds a `.devflow/` folder, else the
7
+ toplevel). The script holds no judgment: it takes the git call and the ledger rule from
8
+ `resolve-settings.cjs`, the rule the curation hooks apply. The step runs once per start
9
+ directory, so a run over several worktrees resolves each one.
10
+ `docs_root()` here, `knowledge_root()` in `_knowledge.mds` and `decisions_locate()` in
11
+ `_decisions.mds` each expand it, so no host needs to know which of its steps comes
12
+ first: the first one to run calls the script and the others reuse the answer. Each of the
13
+ three adds only the facts its own host needs after the step. When the script fails, both
14
+ roots are the start directory. A curation-off build also carries the `LEDGER=` line: the
15
+ script only names that folder and reads no file in it.
2
16
 
3
17
  D-DOCS-ROOT extends D-PROMPT-ROOT from the decisions and knowledge loaders to
4
18
  every docs artifact a command reads or writes — design documents, research
@@ -6,9 +20,8 @@ output, bug-analysis and wave directories, ticket sets, and `/implement`'s
6
20
  handoff and evidence files. They belong to the checkout, not to the directory
7
21
  the session started in: a relative `.devflow/docs/…` path written from
8
22
  `packages/app` scattered a second `.devflow/docs/` tree there, which no later
9
- run found. The rule is the knowledge loader's — the toplevel, else the start
10
- directory — because docs artifacts are per checkout like knowledge bases, not
11
- per repository like the decisions ledger.
23
+ run found. The root is `WORKTREE`, because docs artifacts are per checkout like
24
+ knowledge bases, not per repository like the decisions ledger.
12
25
 
13
26
  A path handed to an agent in repo-relative form (the fields the Git agent's
14
27
  operations print into a PR or issue comment, where an absolute path would leak
@@ -18,18 +31,26 @@ relative to, which the receiving agent resolves it under.
18
31
  forms; `tests/commands/partials-root.test.ts` runs the resolution command below
19
32
  from a root, a subdirectory and a worktree.
20
33
 
21
- One define, imported selectively: MDS deep-clones a module's whole scope into
34
+ Two defines, no imports of their own: MDS deep-clones a module's whole scope into
22
35
  every define, so a selective import's capture cost is paid over the importer's
23
- scope, and a single define with no imports of its own adds one node to it.
36
+ scope. The hosts import `docs_root` alone, and `_knowledge.mds` and `_decisions.mds`
37
+ import `root_paths` alone; each adds one node to the importer's scope.
24
38
 
25
- @define docs_root():
26
- **Docs root (D-DOCS-ROOT).** Every `.devflow/docs/` path this command reads or writes lives at the checkout's toplevel, never under the directory the session started in. Resolve `{worktree}` from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — by running
39
+ @define root_paths():
40
+ Once per start directory (`WORKTREE_PATH` if provided, otherwise cwd), run from it:
27
41
 
28
42
  ```bash
29
- git -C "{start}" rev-parse --show-toplevel
43
+ node "$HOME/.devflow/scripts/resolve-root.cjs" "{start}"; echo "exit=$?"
30
44
  ```
31
45
 
32
- and using its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. Every docs path below is written `{worktree}/.devflow/docs/…`; a repo-relative docs path handed to an agent always travels with a `WORKTREE_PATH` naming the checkout it is relative to.
46
+ Accept only the three lines `WORKTREE=<absolute path>`, `LEDGER=<absolute path>` and `exit=0`, which set `{worktree}` and `{ledger}`. Otherwise both are the start directory.
47
+ @end
48
+
49
+ @define docs_root():
50
+ **Docs root (D-DOCS-ROOT).** Every `.devflow/docs/` path is `{worktree}/.devflow/docs/…`. A repo-relative docs path handed to an agent travels with a `WORKTREE_PATH` naming its checkout.
51
+
52
+ {{root_paths()}}
33
53
  @end
34
54
 
55
+ @export root_paths
35
56
  @export docs_root
@@ -1,37 +1,30 @@
1
1
  @define gate1_postcode():
2
- ### GATE 1 — Post-code pipeline (runs exactly TWICE per ticket)
2
+ ### GATE 1 — Post-code pipeline
3
3
 
4
- ORDER IS LOAD-BEARING. Run exactly in this sequence:
4
+ Run in this order:
5
5
 
6
6
  1. **Polish agent** — reduce complexity, remove duplication
7
7
  2. **Harden agent** — 9-pillar self-review (deep structural analysis); returns `{"status": "PASS" | "FIXED" | "BLOCKED"}`
8
8
  - BLOCKED (a P0 issue cannot be fixed in scope), or a missing or unrecognised status, which counts as BLOCKED → stop the pass and escalate as `harden-blocked`; Validate does not run on code Harden could not accept
9
- 3. **Validate agent** — build / typecheck / lint / test; returns `{"verdict": "PASS" | "FAIL", "details": "..."}`. It runs LAST and UNCONDITIONALLY: one full run over the HEAD that Polish and Harden left, so it covers their commits whether or not Harden changed code
10
- - Build/test commands follow `build_execution_doctrine()`: the Validate agent's Running commands block, foreground under an explicit Bash timeout.
9
+ 3. **Validate agent** — build / typecheck / lint / test; returns `{"verdict": "PASS" | "FAIL", "details": "..."}`. It runs last and unconditionally: one full run over the HEAD that Polish and Harden left, so it covers their commits whether or not Harden changed code
11
10
  - FAIL → Fix agent fix (max 2 retries), each followed by a Validate agent re-run
12
- - If still FAIL after 2 retries → escalate as `validation-exhausted` (do not loop endlessly)
11
+ - If still FAIL after 2 retries → escalate as `validation-exhausted`
13
12
 
14
13
  **Gate 1 contains NO Evaluate agent and NO Test agent.** Those are Gate 2 only.
15
14
 
16
- Depth scales to change size + budget: a trivial one-line fix warrants a lighter pass; a multi-file refactor warrants the full depth.
17
-
18
- **Cadence — Gate 1 runs at exactly TWO points per ticket:**
15
+ **Cadence — Gate 1 runs at exactly two points per ticket:**
19
16
  1. **Gate 1 #1** — immediately after the initial Code agent implementation (inside `implement_bundle()`). An escalated result — Validate exhausted, or Harden BLOCKED — returns early: the ticket's engine returns `ESCALATED` with one escalation, and Gate 2 and the review pass never run on a broken or unfinished build.
20
- 2. **Gate 1 #2** — the FINAL gate, after ALL Gate-2 fixes AND the entire review pass have completed. Harden BLOCKED here is `ESCALATED` as well.
21
-
22
- It does NOT run inside the review pass, nor after each individual Gate-2 / review / QA fix. At those points the fixing Code agent self-verifies its OWN build compiles (see `review_pass()` and the Code agent's Running commands block). The final Gate 1 #2 is the invariant that all written code passes before merge.
17
+ 2. **Gate 1 #2** — the final gate, after all Gate-2 fixes and the entire review pass have completed. Harden BLOCKED here is `ESCALATED` as well.
23
18
  @end
24
19
 
25
20
  @define gate2_acceptance():
26
- ### GATE 2 — Acceptance gate (per ticket, plan-scoped — fires ONCE at implementation acceptance)
21
+ ### GATE 2 — Acceptance gate (per ticket, plan-scoped)
27
22
 
28
- Gate 2 fires ONCE: after the implement-bundle and BEFORE the review pass. It does NOT re-run after review-fixes (those get Gate 1 only).
29
-
30
- Gate 2 inputs are produced by `/devflow:dynamic-plan`'s plan-challenge step — the acceptance criteria and test plan written for the Evaluate agent and Test agent.
23
+ Gate 2 fires once: after the implement-bundle and before the review pass. It does not re-run after review-fixes (those get Gate 1 only).
31
24
 
32
25
  **Evaluate agent** (only if a plan exists):
33
- - Run `evaluator_panel()` — see that block for the one spawn and the two lenses it names
34
- - If the Evaluate agent returns FAIL (either lens failed): fix-and-continue — the demanded fixes are applied by a Fix agent that self-verifies its own build (batched per the review-pass batching doctrine if numerous). The recorded verdict becomes `FAIL-FIXED` (issues found, fixes applied, not re-evaluated by design); Gate 2 then proceeds. In SINGLE mode the run reports it as `UNVERIFIED`, never PASS.
26
+ - Run `evaluator_panel()`
27
+ - If the Evaluate agent returns FAIL (either lens failed): fix-and-continue — a Fix agent applies the demanded fixes and self-verifies its own build (batched as in the review pass if numerous). The recorded verdict becomes `FAIL-FIXED` (fixes applied, not re-evaluated); Gate 2 then proceeds. In SINGLE mode the run reports it as `UNVERIFIED`, never PASS.
35
28
 
36
29
  **Test agent** (only if acceptance criteria or a test plan exist):
37
30
  - Scenario-based acceptance tests covering functionality, API contracts, performance
@@ -41,24 +34,18 @@ Gate 2 inputs are produced by `/devflow:dynamic-plan`'s plan-challenge step —
41
34
  **When Gate 2 inputs are absent:**
42
35
  - No plan → skip the Evaluate agent silently (note in output: "Gate 2 Evaluate agent skipped — no plan available")
43
36
  - No acceptance criteria and no test plan → skip Test agent silently (note in output: "Gate 2 Test agent skipped — no criteria available")
44
- - Build proceeds Gate-1-only. Never refuse to build; never force-generate fake criteria. Trust the user.
45
37
  @end
46
38
 
47
39
  @define evaluator_panel():
48
40
  ### Evaluate agent spawn (one agent, two lenses)
49
41
 
50
- Run ONE Evaluate agent whose prompt names both lenses, so a ticket pays for one spawn and one read of the plan:
51
-
52
- 1. **Acceptance criteria** — "Does the implementation satisfy each numbered acceptance criterion, INCLUDING the negative criteria (what it must NOT do)?"
53
- 2. **Scope / intent drift** — "Did the Code agent smuggle in unplanned changes, deviate from the plan's intent, or introduce anti-features?"
54
-
55
- It returns `{"verdict": "PASS" | "FAIL", "rationale": "..."}`: FAIL when either lens fails, the rationale naming the failing criterion or the drift. A FAIL on either lens blocks acceptance. A wave ticket runs this same skeleton through `runSingleTicketEngine`, so it gets the same single spawn.
42
+ Run one Evaluate agent whose prompt names both lenses, as the SINGLE skeleton's Gate 2 prompt words them: acceptance criteria (negative criteria included) and scope or intent drift. FAIL when either lens fails.
56
43
  @end
57
44
 
58
45
  @define implement_bundle():
59
46
  ### Implement bundle
60
47
 
61
- The standard implementation unit for one ticket. Run in order:
48
+ Run in order:
62
49
 
63
50
  ```
64
51
  <!-- curation:on -->
@@ -75,8 +62,6 @@ Every Code-family agent prompt opens with `OPERATION: <mode>` as its first line:
75
62
  <!-- curation:off -->
76
63
  Every Code-family agent prompt opens with `OPERATION: <mode>` as its first line: `implement` and `issue-fix` go to `agentType:"Code"`, `validation-fix`, `alignment-fix` and `qa-fix` go to `agentType:"Fix"`. It must include: task description, implementation plan (if one exists), the compliance directive (`COMPLIANCE_DIRECTIVE` — every Code prompt carries it when it is not empty, fix prompts included), and any PRIOR_PHASE_SUMMARY / HANDOFF_FILE for sequential multi-phase tickets.
77
64
  <!-- curation:end -->
78
-
79
- Gate 2 runs at implementation acceptance — this matches devflow's deliberate placement: "evaluation is part of implementation acceptance, not post-review" (§6.1).
80
65
  @end
81
66
 
82
67
  @define review_pass():
@@ -93,7 +78,7 @@ Core Review agents (always, 8 total): security, architecture, performance, compl
93
78
  Conditional by file type detected in the diff (add these when relevant):
94
79
  - `.ts` / `.tsx` → typescript
95
80
  - `.tsx` / `.jsx` → react, accessibility, ui-design
96
- - `.tsx` / `.jsx` / `.css` / `.scss` → ui-design (deduplicate with above)
81
+ - `.css` / `.scss` → ui-design
97
82
  - `.go` → go
98
83
  - `.java` → java
99
84
  - `.py` → python
@@ -102,18 +87,13 @@ Conditional by file type detected in the diff (add these when relevant):
102
87
  - `package.json` / `go.mod` / `Cargo.toml` / etc. → dependencies
103
88
  - Markdown / doc files → documentation
104
89
 
105
- **Spawn pacing:** launch Review agents in staggered chunks of 4–6 (sequential groups of parallel spawns) — the full roster is preserved, paced to avoid 429 batch death.
90
+ **Spawn pacing:** launch Review agents in staggered chunks of 4–6 (sequential groups of parallel spawns).
106
91
 
107
- **Review agent result contract:** every Review agent MUST return a structured result with fields `focus`, `reviewed: true`, `filesExamined`, and `findings`. Each item in `findings` must carry: `file` (path of the primary file the finding relates to, or `null` if scope is unknown), `description` (one-sentence issue statement), and `severity` (`critical | high | medium | low`). A result is DEAD if: the agent returned null, threw, returned a guard string, or `reviewed !== true`. A DEAD Review agent is NEVER treated as a clean reviewer. Retry once sequentially. If still dead after retry: record the focus in `coverageGaps`. A pass with any coverage gaps can never early-exit as clean, and the run verdict can NEVER be PASS; escalate with message "review coverage incomplete: <focus>".
108
-
109
- Each Review agent gets `agentType: "Review"` with its focus baked into the prompt. Total: 8–19 Review agents per pass.
92
+ **Review agent result contract:** every Review agent must return a structured result with fields `focus`, `reviewed: true`, `filesExamined`, and `findings`. Each item in `findings` must carry: `file` (path of the primary file the finding relates to, or `null` if scope is unknown), `description` (one-sentence issue statement), and `severity` (`critical | high | medium | low`). A result is DEAD if: the agent returned null, threw, returned a guard string, or `reviewed !== true`. A DEAD Review agent is never treated as a clean reviewer. Retry once sequentially. If still dead after retry: record the focus in `coverageGaps`. A pass with any coverage gaps can never early-exit as clean, and the run verdict can never be PASS; escalate with message "review coverage incomplete: <focus>".
110
93
 
111
94
  **Step 2 — Adversarial finding verification**
112
95
 
113
- Before any fix, verify findings with perspective-diverse lenses. Run 2–3 agents asking:
114
- - "Does this finding actually reproduce given the current code?"
115
- - "Is this a real issue or a false positive in context?"
116
- - "Does the cited rule/principle actually apply here?"
96
+ Before any fix, verify findings with 2–3 agents, one per lens of the skeleton's verification panel.
117
97
 
118
98
  Majority-survives: a finding needs >50% of verification lenses to confirm it. Strip unconfirmed findings.
119
99
 
@@ -121,27 +101,27 @@ Majority-survives: a finding needs >50% of verification lenses to confirm it. St
121
101
 
122
102
  If no surviving findings: return early (no fixes needed). Any coverageGaps are carried in the return — they block a PASS verdict downstream, not the early exit.
123
103
 
124
- If survivors remain: batch the confirmed findings for fixing: group findings by file — one file per set of sub-batches, chunked at max 5 findings per sub-batch; never mix two files in one batch. A finding with no `file` field is its own singleton batch. Sub-batches for the SAME file run sequentially (never two Code agents editing the same file concurrently — same-file edits in `parallel()` cause index contention and lost fixes); sub-batches for DISTINCT files run via `parallel()` in staggered chunks of ~5, same pacing bar as the Review spawn path (different code areas — safe per concurrency doctrine). Each Code agent's prompt pins a return contract: `{"status": "fixed"|"blocked", "commitShas": [...], "unresolved": [...]}` — a chunk is FIXED only when `result.status === "fixed"` AND `commitShas` is non-empty AND `result.unresolved` is empty; never decide disposition from status alone. A non-empty `unresolved` list means the agent named work it could not complete — carry the whole chunk into `survivingFindings` rather than guessing which findings the strings map to. `survivingFindings` = findings NOT addressed: fix Code agent dead/failed/blocked/deferred OR committed but left work named in `unresolved`. The fixing Code agent **self-verifies its own fix builds** (build/typecheck per the Code agent's Running commands block, once over its whole batch). Do **NOT** run Gate 1 or Gate 2 inside the pass (no Validate agent, no Polish agent, no Harden agent, no Evaluate agent, no Test agent). The engine runs ONE final Gate 1 after the pass exits — see the `gate1_postcode()` cadence (Gate 1 #2).
104
+ If survivors remain: batch the confirmed findings for fixing: group findings by file — one file per set of sub-batches, chunked at max 5 findings per sub-batch; never mix two files in one batch. A finding with no `file` field is its own singleton batch. Sub-batches for the same file run sequentially (never two Code agents editing the same file concurrently); sub-batches for distinct files run via `parallel()` in staggered chunks of ~5. Each Code agent's prompt pins a return contract: `{"status": "fixed"|"blocked", "commitShas": [...], "unresolved": [...]}` — a chunk is FIXED only when `result.status === "fixed"` AND `commitShas` is non-empty AND `result.unresolved` is empty; never decide disposition from status alone. A non-empty `unresolved` list means the agent named work it could not complete — carry the whole chunk into `survivingFindings` rather than guessing which findings the strings map to. `survivingFindings` = findings not addressed: fix Code agent dead/failed/blocked/deferred or committed but left work named in `unresolved`. The fixing Code agent **self-verifies its own fix builds** (build/typecheck per the Code agent's Running commands block, once over its whole batch). Do not run Gate 1 or Gate 2 inside the pass (no Validate, Polish, Harden, Evaluate or Test agent).
125
105
  @end
126
106
 
127
107
  @define concurrency_doctrine():
128
- ### Code agent concurrency doctrine (§7.1 — LOAD-BEARING)
108
+ ### Code agent concurrency doctrine
129
109
 
130
110
  **DEFAULT: SEQUENTIAL.** Parallelism is the rare, tightly-gated exception.
131
111
 
132
- - **Same task → sequential Code agents with handoff. NEVER parallel.** Sequential Code agents passing a handoff artifact produce far more coherent code than parallel Code agents dividing one task. Two Code agents splitting one task is a coherence hazard, not a speedup.
133
- - **Different tasks MAY parallelize, but ONLY when ALL THREE bars hold:**
112
+ - **Same task → sequential Code agents with handoff. Never parallel.**
113
+ - **Different tasks may parallelize, but only when all three bars hold:**
134
114
  1. Completely different areas of the code — different files/modules, no imports between them, no shared contracts/interfaces
135
115
  2. Different feature logic — they do not touch the same feature's logic or cooperate on a single outcome
136
116
  3. Different goals — they are not two steps converging on the same end state
137
- - **Default-sequential even across multiple tasks.** "They look independent" is NOT sufficient. If two tasks are somewhat related — they touch the same feature, one's completion makes the other meaningful, or they march toward a shared goal — run them sequentially.
138
- - **When in doubt, sequential.** Parallel must be affirmatively justified against all three bars. The cost of a wrong parallel call (incoherent merge, contended edits) dwarfs the wall-clock saved.
117
+ - "They look independent" is not sufficient. If two tasks are somewhat related — they touch the same feature, one's completion makes the other meaningful, or they march toward a shared goal — run them sequentially.
118
+ - **When in doubt, sequential.** Parallel must be affirmatively justified against all three bars.
139
119
 
140
- This applies to both: multiple Code agents working on a single ticket AND multi-ticket scheduling in a wave.
120
+ This applies to both: multiple Code agents working on a single ticket and multi-ticket scheduling in a wave.
141
121
  @end
142
122
 
143
123
  @define build_execution_doctrine():
144
- ### Build execution doctrine — the Running commands block (LOAD-BEARING)
124
+ ### Build execution doctrine — the Running commands block
145
125
 
146
126
  The Code, Fix, Refactor, Validate and Test agents each carry this `## Running commands` block in their bodies, so each prompt in this engine names the block ("your Running commands block") instead of copying it:
147
127
 
@@ -156,17 +136,15 @@ Run builds, typechecks, lints and tests in the foreground, each with an explicit
156
136
  - Never wrap a build or test command in `sh -c`, `bash -c`, `python3 -c` or `node -e`: permission rules deny wrapped commands they allow directly.
157
137
  - The same rules hold inside a dynamic Workflow sub-agent.
158
138
 
159
- **Cheapest-sufficient validation:** iterate with the fastest check that proves the change — `tsc --noEmit`, `cargo check`, `go vet`, a single test file — the ecosystem's cheapest sufficient signal. Reserve expensive full/optimized builds and whole-suite runs for the final gates only.
160
-
161
- **One build gate per phase:** batch related fixes, validate once. A fix-pass Code agent runs ONE light check over its whole batch — never several invocations per small fix. Do NOT validate after every individual mutation; validate once after the batch is complete.
139
+ **Cheapest-sufficient validation:** iterate with the fastest check that proves the change — `tsc --noEmit`, `cargo check`, `go vet`, a single test file. Reserve full builds and whole-suite runs for the final gates.
162
140
 
163
- **Scope commands to stay short.** During the engine, prefer the scoped command for the change over the whole workspace — `cargo build -p <crate>`, `cargo test -p <crate>`, `npm test -- <path>`, `go test ./pkg/...` — and, when the whole set is needed, one workspace-level command over a per-package loop. After the wave, the full-workspace regression is the human's job (the wave already hands the integrated branch back to the user).
141
+ **One build gate per phase:** batch related fixes, validate once. A fix-pass Code agent runs one light check over its whole batch, never one per fix. After the wave, the full-workspace regression is the human's job.
164
142
  @end
165
143
 
166
144
  @define engine_output_schema():
167
145
  ### Engine output schema
168
146
 
169
- Each ticket engine run returns a structured result. The Synthesize agent or the wave loop reads this to decide next steps. The engine fills `verdict`: the SINGLE skeleton's `overallVerdict`, or `ESCALATED` from the ticket-link or branch stop. The wave merges `PASS` and `UNVERIFIED` and quarantines every other value, or none.
147
+ Each ticket engine run returns a structured result. The engine fills `verdict`: the SINGLE skeleton's `overallVerdict`, or `ESCALATED` from the ticket-link or branch stop. The wave merges `PASS` and `UNVERIFIED` and quarantines every other value, or none.
170
148
 
171
149
  ```json
172
150
  {
@@ -214,15 +192,15 @@ Each ticket engine run returns a structured result. The Synthesize agent or the
214
192
  @end
215
193
 
216
194
  @define engine_invariants():
217
- ### Engine invariants (non-negotiable)
195
+ ### Engine invariants
218
196
 
219
- 1. **Code is written ONLY by the Code family (Code, Fix).** No other agent type writes code — not Review agent, not Evaluate agent.
220
- 2. **Findings are verified before any fix is written.** The adversarial verification step is not optional; unverified findings are not passed to the Code agent.
221
- 3. **All written code passes Gate 1.** No code merge, commit, or handoff before Polish agent + Harden agent + Validate agent (in that order — Validate last, so its one run covers the commits of the two before it).
222
- 4. **Gate 2 runs once, at implementation acceptance.** It does not re-run after review-fixes.
223
- 5. **NEVER auto-merge to main or master.** All merges target the integration branch. The user merges to main themselves.
197
+ 1. **Code is written only by the Code family (Code, Fix).** No other agent type writes code.
198
+ 2. **Findings are verified before any fix is written.** Unverified findings are not passed to the Code agent.
199
+ 3. **All written code passes Gate 1.** No code merge, commit, or handoff before Polish agent + Harden agent + Validate agent (in that order).
200
+ 4. **Gate 2 runs once, at implementation acceptance.**
201
+ 5. **NEVER auto-merge to main or master.** All merges target the integration branch.
224
202
  6. **No unauthorized tracker or remote side-effects.** Sub-agents NEVER create issues/PRs on the tracker, comment on them, or push beyond the ticket-authorized branch unless the ticket, plan, or user explicitly authorizes that exact action. This applies to whatever tracker is resolved, not to one vendor. Proposed follow-ups go in the run report.
225
- 7. **The review pass runs exactly ONCE per ticket.** Never author additional cycles or a delta re-review of fix commits. Fix commits are covered by the fixing Code agent's self-verification and the final Gate 1 #2. Budget scales roster size and verification votes, never pass count.
203
+ 7. **The review pass runs exactly ONCE per ticket.** Never author additional cycles or a delta re-review of fix commits.
226
204
  @end
227
205
 
228
206
  @export gate1_postcode
@@ -5,7 +5,7 @@
5
5
  node "$HOME/.devflow/scripts/resolve-evidence-policy.cjs" 2>/dev/null; echo "exit=$?"
6
6
  ```
7
7
 
8
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `EVIDENCE_POLICY=<required|standard> SOURCE=<file|worktree|default|invalid|error> REF=<branch|none>[ WARN=<remote-unavailable|invalid-file|raised-by-compliance|pr-changes-policy>[,…]] ISSUE_REQUIRED=<true|false> APPLY_CONVENTIONS=<true|false> REQUIRE_NON_AUTHOR_APPROVAL=<true|false>` — these fields, in this order, nothing else, where `<branch>` is a branch name such as `main`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `EVIDENCE_POLICY=required SOURCE=error REF=none ISSUE_REQUIRED=true APPLY_CONVENTIONS=true REQUIRE_NON_AUTHOR_APPROVAL=true` instead.
8
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `EVIDENCE_POLICY=<required|standard> SOURCE=<file|worktree|default|invalid|error> REF=<branch|none>[ WARN=<remote-unavailable|invalid-file|raised-by-compliance|pr-changes-policy>[,…]] ISSUE_REQUIRED=<true|false> APPLY_CONVENTIONS=<true|false> REQUIRE_NON_AUTHOR_APPROVAL=<true|false>` — these fields, in this order, nothing else, where `<branch>` is a branch name. **Anything else** (including a script that cannot run) ⇒ use `EVIDENCE_POLICY=required SOURCE=error REF=none ISSUE_REQUIRED=true APPLY_CONVENTIONS=true REQUIRE_NON_AUTHOR_APPROVAL=true` instead.
9
9
 
10
10
  Set `EVIDENCE_POLICY`, `ISSUE_REQUIRED`, `APPLY_CONVENTIONS` and `REQUIRE_NON_AUTHOR_APPROVAL` from the accepted line. Pass agents only the three mechanism inputs, never `EVIDENCE_POLICY`. Report `Evidence policy: {EVIDENCE_POLICY} (source: {SOURCE})`, plus any `WARN` tokens as advisory, once in the final report.
11
11
  @end
@@ -1,27 +1,11 @@
1
1
  @define factory_shape():
2
2
  ### Ticket-factory pipeline shape (generalized)
3
3
 
4
- This is the standard shape for converting an initiative or spec into a reviewed, amended, self-consistent set of tickets plus a tracking issue. It generalises the `l3-ticket-factory` reference (`draft → [2-lens review in parallel] → revise → whole-set critic → per-ticket amend → tracking-issue`).
5
-
6
- The candidate ticket slate is **proposed by the model** (you, reading the initiative/spec), then **user-editable** before the pipeline runs. Never hardcode ticket identities — let the user confirm the slate first.
7
-
8
4
  ---
9
5
 
10
6
  #### Stage 1 — Draft (one agent per ticket, parallelisable)
11
7
 
12
- Spawn one Design agent or Synthesize agent per candidate ticket:
13
-
14
- ```js
15
- // Parallel per-ticket drafters — each is fully independent at draft time
16
- const drafts = await parallel(candidates.map(c => () =>
17
- agent(`Draft ticket for: ${c.title}\nInitiative: ${initiative}\n${constraints}`, {
18
- agentType: "Design",
19
- schema: DRAFT_SCHEMA
20
- })
21
- ));
22
- ```
23
-
24
- DRAFT_SCHEMA (in fenced block — braces are raw):
8
+ Spawn one Design agent or Synthesize agent per candidate ticket. DRAFT_SCHEMA:
25
9
 
26
10
  ```json
27
11
  {
@@ -45,29 +29,9 @@ DRAFT_SCHEMA (in fenced block — braces are raw):
45
29
 
46
30
  #### Stage 2 — Two-lens review (parallel per ticket)
47
31
 
48
- For each draft, run TWO independent Review agents **in parallel** — one per lens:
49
-
50
- **Lens A — Planner-readiness (cold read):** Could a planner build from this ticket alone, with no other context? Hunt: missing information; untestable or missing negative acceptance criteria; ambiguous constraints; scope holes (things the feature obviously needs that neither In nor Out mentions); undefined terms a cold reader cannot resolve. Severity: critical = planner would be blocked or misled; major = planner would guess; minor = polish.
51
-
52
- **Lens B — Accuracy / scope-discipline audit:** Every claim is sourced from the initiative or spec. No smuggled anti-features (scope items the initiative explicitly excludes). Constraints are honored. Dependency placeholders are consistent with the candidate slate. Severity: critical = invented fact / anti-feature / leak; major = unsourced claim or stance contradiction; minor = citation polish.
53
-
54
- ```js
55
- // Two Review agents per ticket, parallel across both lens and all tickets
56
- const reviews = await parallel(drafts.map((draft, i) => () =>
57
- parallel([
58
- () => agent(`Planner-readiness cold read of ticket: ${JSON.stringify(draft)}`, {
59
- agentType: "Review",
60
- schema: REVIEW_SCHEMA
61
- }),
62
- () => agent(`Accuracy/scope-discipline audit of ticket: ${JSON.stringify(draft)}`, {
63
- agentType: "Review",
64
- schema: REVIEW_SCHEMA
65
- }),
66
- ])
67
- ));
68
- ```
32
+ For each draft, run two independent Review agents **in parallel**, one per lens, with the checks and severities the skeleton's review prompts state: Lens A, planner-readiness (a cold read), and Lens B, accuracy and scope discipline. A scope hole is a thing the feature obviously needs that neither In nor Out names. A smuggled anti-feature is a scope item the initiative explicitly excludes.
69
33
 
70
- REVIEW_SCHEMA (in fenced block — braces are raw):
34
+ REVIEW_SCHEMA:
71
35
 
72
36
  ```json
73
37
  {
@@ -92,22 +56,7 @@ REVIEW_SCHEMA (in fenced block — braces are raw):
92
56
 
93
57
  #### Stage 3 — Revise (one agent per ticket, per review findings)
94
58
 
95
- For each ticket, spawn one Synthesize agent or Design agent to apply review findings:
96
-
97
- ```js
98
- // Sequential per ticket (shared file state); parallelisable across tickets only if separate files
99
- const revised = await parallel(drafts.map((draft, i) => () =>
100
- agent(`Revise ticket per review findings. Fix all critical + major findings; apply minor only where they clarify.
101
- Ticket: ${JSON.stringify(draft)}
102
- Reviews: ${JSON.stringify(reviews[i])}
103
- Rules: if a finding asks for information that does not exist in the source initiative, add it to Open Questions — never invent. If a finding contradicts the stated initiative scope, the initiative wins; note the decline.`, {
104
- agentType: "Synthesize",
105
- schema: REVISE_SCHEMA
106
- })
107
- ));
108
- ```
109
-
110
- REVISE_SCHEMA (in fenced block — braces are raw):
59
+ For each ticket, spawn one Synthesize agent or Design agent to apply review findings. REVISE_SCHEMA:
111
60
 
112
61
  ```json
113
62
  {
@@ -125,25 +74,9 @@ REVISE_SCHEMA (in fenced block — braces are raw):
125
74
 
126
75
  #### Stage 4 — Whole-set cross-critic (single agent, sees all revised tickets)
127
76
 
128
- One Design agent reviews the FULL revised set for set-level issues — not individual prose quality:
129
-
130
- 1. **Coverage:** does the union of tickets cover every item the initiative mandates? Anything the initiative mandates that no ticket owns?
131
- 2. **Overlaps / contradictions:** same responsibility claimed by two tickets; contradictory constraints between tickets; inconsistent terminology for the same concept.
132
- 3. **Dependency graph:** placeholders used consistently; wave assignment matches stated dependencies; anything that should be a dependency but isn't declared.
133
- 4. **Acceptance-criteria coherence:** no criterion in one ticket contradicts a criterion in another.
134
-
135
- ```js
136
- const critic = await agent(`Whole-set completeness & coherence audit.
137
- Revised tickets: ${JSON.stringify(revised)}
138
- Initiative: ${initiative}
139
- Audit: coverage · overlaps/contradictions · dependency graph · acceptance-criteria coherence.
140
- Return: setVerdict + perTicketAmendments + trackingGuidance.`, {
141
- agentType: "Design",
142
- schema: CRITIC_SCHEMA
143
- });
144
- ```
77
+ One Design agent reviews the full revised set for set-level issues, not individual prose quality, on the four axes the skeleton's cross-critic prompt names: coverage, overlaps and contradictions, the dependency graph, and acceptance-criteria coherence. The dependency-graph check also flags a dependency that a ticket needs but does not declare.
145
78
 
146
- CRITIC_SCHEMA (in fenced block — braces are raw):
79
+ CRITIC_SCHEMA:
147
80
 
148
81
  ```json
149
82
  {
@@ -168,48 +101,21 @@ CRITIC_SCHEMA (in fenced block — braces are raw):
168
101
 
169
102
  #### Stage 5 — Per-ticket amend (parallel, only tickets with amendments)
170
103
 
171
- Apply cross-set amendments to the tickets that need them:
172
-
173
- ```js
174
- const toAmend = (critic.perTicketAmendments || []).filter(a => a.amendments.length > 0);
175
- if (toAmend.length) {
176
- await parallel(toAmend.map(a => () =>
177
- agent(`Apply cross-set amendments to ticket "${a.title}":
178
- Amendments: ${JSON.stringify(a.amendments)}
179
- Rules: same as revise — never invent; unresolvable items go to Open Questions; initiative scope wins over any amendment that contradicts it.`, {
180
- agentType: "Synthesize"
181
- })
182
- ));
183
- }
184
- ```
185
-
186
104
  ---
187
105
 
188
106
  #### Stage 6 — Assemble tracking issue
189
107
 
190
- One Synthesize agent writes the tracking-issue document from the final ticket set + critic guidance:
191
-
192
- ```js
193
- const tracker = await agent(`Write a tracking-issue document for the initiative.
194
- Guidance from cross-set critic: ${JSON.stringify(critic.trackingGuidance)}
195
- Final tickets: ${JSON.stringify(revised)}
196
- Structure: initiative context (1–2 paragraphs) + wave-structured execution checklist + ticket index (one line per ticket, user-facing) + explicitly-excluded items (decisions, not oversights) + invariants that bind every ticket.
197
- Output: write to the artifact path and return { path, title }.`, {
198
- agentType: "Synthesize",
199
- schema: { type: "object", required: ["path", "title"],
200
- properties: { path: { type: "string" }, title: { type: "string" } } }
201
- });
202
- ```
108
+ One Synthesize agent writes the tracking-issue document from the final ticket set + critic guidance.
203
109
 
204
110
  ---
205
111
 
206
- #### Usage notes for commands that import this partial
112
+ #### Usage notes
207
113
 
114
+ - Each schema is its stage's return shape, passed as `schema:`: `{ agentType: "Design", schema: DRAFT_SCHEMA }`, `{ agentType: "Review", schema: REVIEW_SCHEMA }`, `{ agentType: "Synthesize", schema: REVISE_SCHEMA }`, `{ agentType: "Design", schema: CRITIC_SCHEMA }`. A field that the host script's `Return:` line adds joins the schema.
208
115
  - The `candidates` array is **what the model proposed + user confirmed** — never hardcoded.
209
116
  - The `initiative` variable is the raw user input (a description, a spec doc path, or inline text) — read it and distill before passing to agents.
210
117
  - The `constraints` variable is optional: any cross-cutting rules (naming discipline, scope filters, authority order) the user supplied.
211
- - Emit artifact files using the `ticket_body_template()` shape (from `_ticket_template.mds`) for each ticket — write inside agents, since the script body has no filesystem access.
212
- - Tracking-issue doc goes to `${ROOT}/.devflow/docs/tickets/{slug}/{ts}/tracking-issue.md`, `ROOT` being the workflow's `root` argument (agents do the writing).
118
+ - Write each ticket's artifact file inside an agent, with the ticket body template above.
213
119
  - For large initiatives (more than ~8 tickets), chunk the `parallel(map())` fan-outs into batches (e.g. `for` loop over slices, `await`-ing each batch) so agent concurrency stays bounded and provider rate limits are respected.
214
120
  @end
215
121