devflow-kit 3.5.0 → 3.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 (107) hide show
  1. package/CHANGELOG.md +98 -0
  2. package/README.md +4 -4
  3. package/dist/agents/{diagnose.md → debug.md} +4 -4
  4. package/dist/agents/{code-fix.md → fix.md} +2 -2
  5. package/dist/agents/{scrutinize.md → harden.md} +6 -6
  6. package/dist/agents/{code-edit.md → refactor.md} +3 -3
  7. package/dist/cli/agents-view/render.js +1 -1
  8. package/dist/cli/commands/init.js +3 -3
  9. package/dist/cli/commands/learning.js +12 -12
  10. package/dist/cli/commands/legacy-hooks.js +1 -1
  11. package/dist/cli/commands/uninstall.js +111 -5
  12. package/dist/commands/bug-analysis.md +19 -15
  13. package/dist/commands/code-review.md +13 -22
  14. package/dist/commands/debug.md +15 -15
  15. package/dist/commands/dynamic-build.md +51 -55
  16. package/dist/commands/dynamic-plan.md +11 -9
  17. package/dist/commands/dynamic-profile.md +7 -5
  18. package/dist/commands/dynamic-tickets.md +11 -9
  19. package/dist/commands/explore.md +13 -13
  20. package/dist/commands/implement.md +58 -127
  21. package/dist/commands/plan.md +19 -41
  22. package/dist/commands/release.md +9 -5
  23. package/dist/commands/research.md +12 -8
  24. package/dist/commands/resolve.md +42 -86
  25. package/dist/commands/self-review.md +42 -42
  26. package/dist/core/agent-models.js +47 -11
  27. package/dist/core/{learning-tuning-config.js → curate-tuning-config.js} +14 -14
  28. package/dist/core/learning-queue-cleanup.js +1 -1
  29. package/dist/core/migrations.js +63 -44
  30. package/dist/core/plugins.js +14 -12
  31. package/dist/core/project-paths.js +3 -3
  32. package/dist/hud/codex-usage.js +247 -0
  33. package/dist/hud/components/codex-quota.js +37 -0
  34. package/dist/hud/components/usage-quota.js +1 -1
  35. package/dist/hud/config.js +1 -0
  36. package/dist/hud/index.js +16 -3
  37. package/dist/hud/render.js +3 -1
  38. package/dist/learning-off/agents/{diagnose.md → debug.md} +4 -4
  39. package/dist/learning-off/agents/{code-fix.md → fix.md} +2 -2
  40. package/dist/learning-off/agents/{scrutinize.md → harden.md} +6 -6
  41. package/dist/learning-off/agents/{code-edit.md → refactor.md} +3 -3
  42. package/dist/learning-off/commands/bug-analysis.md +9 -9
  43. package/dist/learning-off/commands/code-review.md +2 -15
  44. package/dist/learning-off/commands/debug.md +4 -8
  45. package/dist/learning-off/commands/dynamic-build.md +45 -51
  46. package/dist/learning-off/commands/dynamic-plan.md +5 -5
  47. package/dist/learning-off/commands/dynamic-profile.md +1 -1
  48. package/dist/learning-off/commands/dynamic-tickets.md +5 -5
  49. package/dist/learning-off/commands/explore.md +2 -6
  50. package/dist/learning-off/commands/implement.md +46 -119
  51. package/dist/learning-off/commands/plan.md +8 -33
  52. package/dist/learning-off/commands/release.md +4 -2
  53. package/dist/learning-off/commands/research.md +2 -2
  54. package/dist/learning-off/commands/resolve.md +31 -79
  55. package/dist/learning-off/commands/self-review.md +30 -34
  56. package/dist/skills/git/references/pr/check-merge-readiness.md +2 -0
  57. package/dist/skills/git/references/pr/update-pr-evidence.md +4 -6
  58. package/dist/targets/claude-code/installer.js +117 -84
  59. package/dist/targets/claude-code/tracker-servers.js +1 -1
  60. package/package.json +1 -1
  61. package/src/assets/agents/_partials/_code.mds +2 -2
  62. package/src/assets/agents/code.mds +2 -2
  63. package/src/assets/agents/{learning.md → curate.md} +4 -4
  64. package/src/assets/agents/{diagnose.mds → debug.mds} +4 -4
  65. package/src/assets/agents/evaluate.md +4 -4
  66. package/src/assets/agents/{code-fix.mds → fix.mds} +5 -5
  67. package/src/assets/agents/{scrutinize.mds → harden.mds} +6 -6
  68. package/src/assets/agents/{simplify.md → polish.md} +4 -4
  69. package/src/assets/agents/{code-edit.mds → refactor.mds} +6 -6
  70. package/src/assets/agents/test.md +2 -2
  71. package/src/assets/commands/_partials/_compliance.mds +1 -1
  72. package/src/assets/commands/_partials/_decisions.mds +26 -6
  73. package/src/assets/commands/_partials/_engine.mds +15 -15
  74. package/src/assets/commands/_partials/_evidence_policy.mds +0 -17
  75. package/src/assets/commands/_partials/_knowledge.mds +14 -9
  76. package/src/assets/commands/_partials/_preamble.mds +4 -2
  77. package/src/assets/commands/_partials/_roster.mds +4 -4
  78. package/src/assets/commands/bug-analysis.mds +7 -7
  79. package/src/assets/commands/code-review.mds +1 -14
  80. package/src/assets/commands/debug.mds +2 -2
  81. package/src/assets/commands/dynamic-build.mds +26 -32
  82. package/src/assets/commands/implement.mds +45 -102
  83. package/src/assets/commands/plan.mds +7 -37
  84. package/src/assets/commands/release.mds +5 -1
  85. package/src/assets/commands/resolve.mds +28 -76
  86. package/src/assets/commands/self-review.mds +27 -27
  87. package/src/assets/mds/git/_pr.mds +6 -6
  88. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -3
  89. package/src/assets/scripts/hooks/capture-prompt +1 -1
  90. package/src/assets/scripts/hooks/capture-question +1 -1
  91. package/src/assets/scripts/hooks/capture-turn +1 -1
  92. package/src/assets/scripts/hooks/json-helper.cjs +2 -2
  93. package/src/assets/scripts/hooks/lib/learning-store.cjs +1 -1
  94. package/src/assets/scripts/hooks/lib/project-paths.cjs +4 -4
  95. package/src/assets/scripts/hooks/preamble +1 -1
  96. package/src/assets/scripts/hooks/session-start-context +58 -45
  97. package/src/assets/scripts/verify-evidence.cjs +726 -9
  98. package/src/assets/skills/agent-references/SKILL.md +9 -5
  99. package/src/assets/skills/agent-references/references/commands/implement-evidence-asks.md +35 -0
  100. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +15 -0
  101. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +1 -1
  102. package/src/assets/skills/apply-decisions/SKILL.md +6 -4
  103. package/src/assets/skills/docs-framework/SKILL.md +3 -3
  104. package/src/assets/skills/qa/SKILL.md +1 -1
  105. package/src/assets/skills/quality-gates/SKILL.md +7 -7
  106. package/src/assets/skills/quality-gates/references/report-template.md +7 -7
  107. /package/src/assets/skills/agent-references/references/{learning → curate}/maintain.md +0 -0
@@ -3,12 +3,12 @@
3
3
 
4
4
  ORDER IS LOAD-BEARING. Run exactly in this sequence:
5
5
 
6
- 1. **Simplify agent** — reduce complexity, remove duplication
7
- 2. **Scrutinize agent** — 9-pillar self-review (deep structural analysis); returns `{"status": "PASS" | "FIXED" | "BLOCKED"}`
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 `scrutiny-blocked`; Validate does not run on code Scrutinize 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 Simplify and Scrutinize left, so it covers their commits whether or not Scrutinize changed code
6
+ 1. **Polish agent** — reduce complexity, remove duplication
7
+ 2. **Harden agent** — 9-pillar self-review (deep structural analysis); returns `{"status": "PASS" | "FIXED" | "BLOCKED"}`
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
10
  - Build/test commands follow `build_execution_doctrine()`: the Validate agent's Running commands block, foreground under an explicit Bash timeout.
11
- - FAIL → Code-fix agent fix (max 2 retries), each followed by a Validate agent re-run
11
+ - FAIL → Fix agent fix (max 2 retries), each followed by a Validate agent re-run
12
12
  - If still FAIL after 2 retries → escalate as `validation-exhausted` (do not loop endlessly)
13
13
 
14
14
  **Gate 1 contains NO Evaluate agent and NO Test agent.** Those are Gate 2 only.
@@ -16,8 +16,8 @@ ORDER IS LOAD-BEARING. Run exactly in this sequence:
16
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
17
 
18
18
  **Cadence — Gate 1 runs at exactly TWO points per ticket:**
19
- 1. **Gate 1 #1** — immediately after the initial Code agent implementation (inside `implement_bundle()`). An escalated result — Validate exhausted, or Scrutinize 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. Scrutinize BLOCKED here is `ESCALATED` as well.
19
+ 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
21
 
22
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.
23
23
  @end
@@ -31,11 +31,11 @@ Gate 2 inputs are produced by `/devflow:dynamic-plan`'s plan-challenge step —
31
31
 
32
32
  **Evaluate agent** (only if a plan exists):
33
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 Code-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.
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.
35
35
 
36
36
  **Test agent** (only if acceptance criteria or a test plan exist):
37
37
  - Scenario-based acceptance tests covering functionality, API contracts, performance
38
- - FAIL → fix-and-continue — a Code-fix agent applies the demanded fixes and self-verifies its own build. The recorded verdict becomes `FAIL-FIXED`; Gate 2 then proceeds. In SINGLE mode the run reports it as `UNVERIFIED`, never PASS.
38
+ - FAIL → fix-and-continue — a Fix agent applies the demanded fixes and self-verifies its own build. The recorded verdict becomes `FAIL-FIXED`; Gate 2 then proceeds. In SINGLE mode the run reports it as `UNVERIFIED`, never PASS.
39
39
 
40
40
  **When Gate 2 inputs are absent:**
41
41
  - No plan → skip the Evaluate agent silently (note in output: "Gate 2 Evaluate agent skipped — no plan available")
@@ -70,9 +70,9 @@ Code(agentType:"Code", prompt: "OPERATION: implement" first line, then full task
70
70
  ```
71
71
 
72
72
  <!-- learning:on -->
73
- 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:"Code-fix"`. It must include: task description, implementation plan (if one exists), relevant DECISIONS_CONTEXT (the index you loaded before authoring), 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.
73
+ 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), relevant DECISIONS_CONTEXT (the index you loaded before authoring), 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.
74
74
  <!-- learning:off -->
75
- 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:"Code-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.
75
+ 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.
76
76
  <!-- learning:end -->
77
77
 
78
78
  Gate 2 runs at implementation acceptance — this matches devflow's deliberate placement: "evaluation is part of implementation acceptance, not post-review" (§6.1).
@@ -120,7 +120,7 @@ Majority-survives: a finding needs >50% of verification lenses to confirm it. St
120
120
 
121
121
  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.
122
122
 
123
- 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 Simplify agent, no Scrutinize 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).
123
+ 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).
124
124
  @end
125
125
 
126
126
  @define concurrency_doctrine():
@@ -199,7 +199,7 @@ Each ticket engine run returns a structured result. The Synthesize agent or the
199
199
  },
200
200
  "escalations": [
201
201
  {
202
- "type": "merge-conflict | gate2-fail | validation-exhausted | scrutiny-blocked | ambiguous-resolution | review-coverage-incomplete | dependency-blocked | engine-crash | ticket-link-missing | branch-missing",
202
+ "type": "merge-conflict | gate2-fail | validation-exhausted | harden-blocked | ambiguous-resolution | review-coverage-incomplete | dependency-blocked | engine-crash | ticket-link-missing | branch-missing",
203
203
  "description": "string"
204
204
  }
205
205
  ],
@@ -215,9 +215,9 @@ Each ticket engine run returns a structured result. The Synthesize agent or the
215
215
  @define engine_invariants():
216
216
  ### Engine invariants (non-negotiable)
217
217
 
218
- 1. **Code is written ONLY by the Code family (Code, Code-fix).** No other agent type writes code — not Review agent, not Evaluate agent.
218
+ 1. **Code is written ONLY by the Code family (Code, Fix).** No other agent type writes code — not Review agent, not Evaluate agent.
219
219
  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.
220
- 3. **All written code passes Gate 1.** No code merge, commit, or handoff before Simplify agent + Scrutinize agent + Validate agent (in that order — Validate last, so its one run covers the commits of the two before it).
220
+ 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).
221
221
  4. **Gate 2 runs once, at implementation acceptance.** It does not re-run after review-fixes.
222
222
  5. **NEVER auto-merge to main or master.** All merges target the integration branch. The user merges to main themselves.
223
223
  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.
@@ -10,21 +10,4 @@ Accept the output only when it is exactly two lines: `exit=0` last and, before i
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
12
12
 
13
- @define evidence_exception():
14
- **Render each evidence exception** as one line under a `## Evidence Exceptions` heading, in exactly this shape:
15
-
16
- ```markdown
17
- ## Evidence Exceptions
18
- - `<kind>` self-attested by @<login> at <utc>: <reason>
19
- ```
20
-
21
- - `<kind>` is one of `ticket-link` or `test-plan` — a closed set; no other kind is ever rendered, and the section holds each kind at most once.
22
- - `@<login>` is `@` followed by the output of `gh api user --jq .login` when that output matches `^[A-Za-z0-9][A-Za-z0-9-]{0,38}$`. On any other output, or a failed call, it is `(login unavailable)` instead, with no `@`.
23
- - `<utc>` is the output of `date -u +%Y-%m-%dT%H:%M:%SZ`.
24
- - `<reason>` is the user's own words, made inert: replace every character outside printable ASCII (newlines and tabs included) with a space, remove every `<`, `>`, `` ` ``, `[`, `]`, `\`, `/`, `#`, `@`, `&` and `$`, collapse runs of spaces, trim, keep the first 200 characters, and trim again. A reason that is empty after this is no reason.
25
-
26
- Note: the section reaches a public PR body. The Code agent re-checks every line against this shape before it pastes, and the body's D11 scrub is the reason's secret scrub — rendering filters no secrets. A rendered reason carries no HTML or comment markers, link or image syntax, @-mentions, `#N` or full-URL references (no `/` survives), entities or shell-expansion characters; plain emphasis and `www.` or `GH-N` autolinks can remain — the requester authors the reason.
27
- @end
28
-
29
13
  @export evidence_policy
30
- @export evidence_exception
@@ -3,6 +3,15 @@ imports nothing from `_settings.mds`. Write-back Step 1 takes `KNOWLEDGE` from t
3
3
  settings line the host's settings block resolved above, and keeps the
4
4
  `KNOWLEDGE=off` skip inside its own step.
5
5
 
6
+ D-CMD-CONDENSE (#456): a cut here lands in every host, so each one names the line
7
+ that keeps its text in the same context. Load's closing summary restated Steps 1-4,
8
+ which each name their read, and Step 2's closing sentence restated Step 3's fallback
9
+ fields. The Knowledge spawn names what only the caller knows (root, slug, directories,
10
+ files, the two paths, the index line format and its caps); how the agent writes the
11
+ index, writes the two files directly and commits them is held by its own body
12
+ (knowledge.mds steps 6-8, Direct Write Protocol, Commit Protocol), so the spawn no
13
+ longer restates it.
14
+
6
15
  @define knowledge_load():
7
16
  ### Load Feature Knowledge
8
17
 
@@ -26,7 +35,7 @@ If `index.md` exists and contains at least one entry line, use it for relevance
26
35
 
27
36
  **Step 2 — Fallback: glob frontmatter (if `index.md` is absent or empty):**
28
37
 
29
- Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters). The frontmatter fields `name`, `description`, and `directories` are the authoritative relevance surface — `index.md` is only a cache.
38
+ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters).
30
39
 
31
40
  **Step 3 — Pick relevant KBs:**
32
41
 
@@ -57,7 +66,7 @@ Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
57
66
 
58
67
  A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
59
68
 
60
- **One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
69
+ **One git call, then direct reads — no `.cjs` script.**
61
70
  @end
62
71
 
63
72
  @export knowledge_load
@@ -96,22 +105,18 @@ FEATURE_NAME: {human-readable name}
96
105
  DIRECTORIES: {list of primary directories touched by this workflow}
97
106
  FILES_CHANGED: {list of files changed}
98
107
  <!-- learning:on -->
99
- DECISIONS_CONTEXT: {DECISIONS_CONTEXT if available, else (none)}
108
+ DECISIONS_CONTEXT: {the slice for these directories, else (none)}
100
109
  <!-- learning:end -->
101
110
 
102
111
  Write the knowledge base to:
103
112
  {worktree}/.devflow/features/{slug}/KNOWLEDGE.md
104
113
 
105
- Then update the index cache by performing a read-modify-write on:
114
+ Then update the index cache:
106
115
  {worktree}/.devflow/features/index.md
107
116
 
108
117
  Index line format: `- **{slug}** — {areas} — {Use-when description}` — at most 300 characters, the description at most 220; reword a longer one, never cut it.
109
118
 
110
- If the line for this slug already exists in index.md, replace it. If it does not exist, append it. If index.md does not exist, create it with just this line.
111
-
112
- The frontmatter in KNOWLEDGE.md is the source of truth — index.md is only a cache. Write the two files directly — no intermediate result JSON files, no external scripts.
113
-
114
- After writing, commit the two files to the current worktree branch yourself by running git via your Bash tool (do not use a script). Stage ONLY .devflow/features/index.md and .devflow/features/{slug}/KNOWLEDGE.md, then commit just those paths with a docs(knowledge): message. Do NOT push, do NOT force, do NOT stage anything else. Follow your Commit Protocol — it is non-blocking, so if any git step fails, report KB_COMMIT and finish normally."
119
+ Then commit the two files as your Commit Protocol directs."
115
120
  ```
116
121
 
117
122
  **Step 4 — Surface an uncommitted knowledge base:**
@@ -56,7 +56,7 @@ Spawn devflow agents with:
56
56
  agent("your prompt here", { agentType: "Code" })
57
57
  ```
58
58
 
59
- Valid `agentType` values: Code, Code-fix, Validate, Simplify, Scrutinize, Evaluate, Test, Review, Git, Synthesize, Knowledge, Design.
59
+ Valid `agentType` values: Code, Fix, Validate, Polish, Harden, Evaluate, Test, Review, Git, Synthesize, Knowledge, Design.
60
60
 
61
61
  **OMIT `opts.model` whenever `agentType` is set.** The agent frontmatter carries its own model tier (Code→sonnet, Validate→haiku, Review→opus, etc.) and that tier is honored automatically. Passing `opts.model` overrides it — always a mistake.
62
62
 
@@ -101,7 +101,9 @@ When a ticket requires multiple sequential Code agent phases, each Code agent ap
101
101
 
102
102
  Before you author the workflow script, read `{ledger}/.devflow/learning/index.md`. If the file is absent or empty, set `DECISIONS_CONTEXT` to `(none)`; otherwise use the file content as `DECISIONS_CONTEXT`.
103
103
 
104
- The script body cannot perform this read — you (the main model) do it before authoring. Then inject the relevant DECISIONS_CONTEXT into the prompts of the Code, Code-fix, Design, Knowledge, Review and Scrutinize agents, using the `devflow:apply-decisions` consumption algorithm (scan index → Read relevant entries → cite verbatim IDs in agent prompts). Those are the agent types above whose contract declares it; every other agent type gets no decisions context.
104
+ The script body cannot perform this read — you (the main model) do it before authoring. Then inject the relevant DECISIONS_CONTEXT into the prompts of the Code, Fix, Design, Knowledge, Review and Harden agents, which follow `devflow:apply-decisions`. Those are the agent types above whose contract declares it; every other agent type gets no decisions context.
105
+
106
+ {{decisions.decisions_slice()}} The script carries one `DECISIONS_CONTEXT` for every agent, so cut it once, over the whole run.
105
107
 
106
108
  <!-- learning:end -->
107
109
  @end
@@ -6,10 +6,10 @@ The following agentType values are valid. Model tiers are shown for reference
6
6
  | agentType | Model tier | Role |
7
7
  |-----------|-----------|------|
8
8
  | Code | sonnet | Implements the plan and fixes review findings — the Code family is the ONLY one that writes code |
9
- | Code-fix | sonnet | Fixes the listed validation, alignment and QA failures — part of the Code family |
9
+ | Fix | sonnet | Fixes the listed validation, alignment and QA failures — part of the Code family |
10
10
  | Validate | haiku | Build / typecheck / lint / test — fast correctness gate |
11
- | Simplify | sonnet | Reduces complexity, removes duplication, improves readability |
12
- | Scrutinize | opus | 9-pillar self-review — deep structural analysis |
11
+ | Polish | sonnet | Reduces complexity, removes duplication, improves readability |
12
+ | Harden | opus | 9-pillar self-review — deep structural analysis |
13
13
  | Evaluate | sonnet | Plan-fidelity / alignment — "was the plan implemented correctly?" |
14
14
  | Test | sonnet | Scenario-based acceptance tests against acceptance criteria |
15
15
  | Review | opus | Focus-parameterized code review — spawn ONE agent() per focus area |
@@ -22,7 +22,7 @@ The following agentType values are valid. Model tiers are shown for reference
22
22
  @define agent_caveats():
23
23
  ### Agent caveats
24
24
 
25
- - **The Code family writes every fix** — Code for review findings, Code-fix for gate failures; no other agent type writes code. Finding-verification uses adversarial Review agent-style passes (§6.3 of design doc). Risk-assessment and tech-debt routing live in the post-code pipeline + escalation doctrine.
25
+ - **The Code family writes every fix** — Code for review findings, Fix for gate failures; no other agent type writes code. Finding-verification uses adversarial Review agent-style passes (§6.3 of design doc). Risk-assessment and tech-debt routing live in the post-code pipeline + escalation doctrine.
26
26
  - **Always omit `opts.model` with `agentType`.** Each agent honors its own frontmatter model tier; overriding it defeats the per-agent specialization.
27
27
  - **Review agents are focus-parameterized.** Each focus is a SEPARATE `agent()` call with `agentType: "Review"` and the focus baked into the prompt. Do NOT batch multiple focuses into one Review agent call — that defeats parallel specialization.
28
28
  - **Do not depend on agents enumerating their own skills.** Skills are loaded (spike F5 confirmed) but self-reporting is imperfect. Write agent prompts that give the agent full context directly.
@@ -217,11 +217,11 @@ Determine which focus analyzers to run using `CHANGED_FILES` (already computed i
217
217
  **Requires:** DIFF_RANGE, ANALYSIS_DIR, ACTIVE_FOCUSES, STATIC_FINDINGS, ACCEPTANCE_RULES, PLAN_CONTEXT, FEATURE_KNOWLEDGE
218
218
  <!-- learning:end -->
219
219
 
220
- Spawn ALL active Diagnose agents **in a single message** (parallel, NOT background):
220
+ Spawn ALL active Debug agents **in a single message** (parallel, NOT background):
221
221
 
222
222
  For each active focus, spawn:
223
223
  ```
224
- Agent(subagent_type="Diagnose", run_in_background=false):
224
+ Agent(subagent_type="Debug", run_in_background=false):
225
225
  "Analyze focusing on {focus}.
226
226
  FOCUS: {focus}
227
227
  DIFF_COMMAND: git diff {DIFF_RANGE}
@@ -325,10 +325,10 @@ Run `/resolve` to process and fix these findings.
325
325
  │ └─ Detect active focuses (security + functional always; integration + usability conditional)
326
326
  │
327
327
  ├─ Phase 5: Bug Analysis (PARALLEL)
328
- │ ├─ Diagnose agent: security (+ STATIC_FINDINGS)
329
- │ ├─ Diagnose agent: functional
330
- │ ├─ Diagnose agent: integration (conditional)
331
- │ └─ Diagnose agent: usability (conditional)
328
+ │ ├─ Debug agent: security (+ STATIC_FINDINGS)
329
+ │ ├─ Debug agent: functional
330
+ │ ├─ Debug agent: integration (conditional)
331
+ │ └─ Debug agent: usability (conditional)
332
332
  │
333
333
  ├─ Phase 6: Synthesis
334
334
  │ └─ Synthesize agent (mode: bug-analysis)
@@ -365,7 +365,7 @@ Run `/resolve` after `/bug-analysis` to fix identified bugs. `/resolve` automati
365
365
  2. **Parallel, not background** — Analyzers spawn in one message with `run_in_background=false`
366
366
  3. **Static + semantic** — Two complementary tracks, each validates the other
367
367
  4. **Incremental by default** — Only analyze new changes unless `--full` specified
368
- 5. **Verify before reporting** — Diagnose agents self-verify every finding
368
+ 5. **Verify before reporting** — Debug agents self-verify every finding
369
369
  6. **Honest reporting** — Display risk level and counts directly from synthesis
370
370
 
371
371
  ## Phase Completion Checklist
@@ -277,7 +277,7 @@ The core, database, dependencies, documentation and compliance focuses, and ever
277
277
 
278
278
  {{decisions_load()}}
279
279
  <!-- learning:on -->
280
- This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT` to all Review agents. Review agents use `devflow:apply-decisions` to Read full entry bodies on demand.
280
+ This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT` to all Review agents as one shared slice, cut over the diff's files. Review agents use `devflow:apply-decisions` to Read full entry bodies on demand.
281
281
 
282
282
  <!-- learning:end -->
283
283
  {{knowledge_load()}}
@@ -442,21 +442,8 @@ In multi-worktree mode, report results per worktree.
442
442
 
443
443
  | Case | Handling |
444
444
  |------|----------|
445
- | No new commits since last review | Skip review, report: "No new commits since last review. Use --full for a full re-review." |
446
- | Rebase invalidates `.last-review-head` SHA | `git cat-file -t` check fails → fallback to full diff |
447
- | Same-minute review collision | `mkdir` fails → retry with seconds appended (`YYYY-MM-DD_HHMMSS`) |
448
- | Worktree in detached HEAD | Filtered out (no branch name → not reviewable) |
449
- | Worktree mid-rebase or mid-merge | Filtered out by status check |
450
- | Two worktrees on same branch | Deduplicate by branch — review once, use first worktree's path |
451
- | Worktree on protected branch | Filtered out (not reviewable) |
452
- | Worktree pre-flight fails | Report failure, continue with other worktrees |
453
445
  | `--full` in multi-worktree mode | Applies to all worktrees (global modifier) |
454
- | Many worktrees (5+) | Report count and proceed — user manages their worktree count |
455
446
  | Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7); a re-review in the same cycle (different timestamp) posts its own comment. The marker's format belongs to the operation; this caller passes the pair and never restates the literal |
456
- | First review (no prior resolution) | PRIOR_RESOLUTIONS=(none), no convergence check |
457
- | fp_ratio denominator = 0 | fp_ratio = 0, no warning |
458
- | `--full` flag | Bypass incremental detection (Step 0d), still load PRIOR_RESOLUTIONS for cross-cycle awareness |
459
- | Parsing failure on resolution-summary.md | fp_ratio = 0, convergence tracking degraded (see Step 0e-ii) |
460
447
  | Concurrent sessions | Advisory only, each session computes independently |
461
448
  | Docs-only diff | `docs-only`: documentation, consistency, security on `diff.patch`; no language or conditional focus |
462
449
  | Tests-only diff | `tests-only`: testing, reliability, consistency, security on `diff.patch`; no language or conditional focus |
@@ -202,7 +202,7 @@ Produce the final report:
202
202
 
203
203
  Ask user via AskUserQuestion: "Want me to implement this fix?"
204
204
 
205
- - **YES** → implement the fix through the Code agent, never in this thread, then spawn `Agent(subagent_type="Simplify")` on the changed files. /debug loads no feature knowledge, so the fix gets none:
205
+ - **YES** → implement the fix through the Code agent, never in this thread, then spawn `Agent(subagent_type="Polish")` on the changed files. /debug loads no feature knowledge, so the fix gets none:
206
206
 
207
207
  ```
208
208
  Agent(subagent_type="Code"):
@@ -249,7 +249,7 @@ Ask user via AskUserQuestion: "Want me to implement this fix?"
249
249
  ├─ Phase 6: Root cause report with confidence level
250
250
  │
251
251
  ├─ Phase 7: Offer Fix
252
- │ └─ AskUserQuestion → Code agent (fix) + Simplify agent, or done
252
+ │ └─ AskUserQuestion → Code agent (fix) + Polish agent, or done
253
253
  │
254
254
  └─ Feature Knowledge Write-Back (Conditional)
255
255
  └─ Knowledge agent (if investigation surfaced durable cross-cutting knowledge)
@@ -67,7 +67,7 @@ Author the resolved `ISSUE_REQUIRED` and `APPLY_CONVENTIONS` into the workflow s
67
67
 
68
68
  {{compliance.compliance_lens()}}
69
69
 
70
- Pass it as `complianceFrameworks` when invoking the workflow; the engine builds `COMPLIANCE_DIRECTIVE` from it and hands that to every Code and Code-fix agent.
70
+ Pass it as `complianceFrameworks` when invoking the workflow; the engine builds `COMPLIANCE_DIRECTIVE` from it and hands that to every Code and Fix agent.
71
71
 
72
72
  **0c. Resolve the docs root**
73
73
 
@@ -165,7 +165,7 @@ const ISSUE_INPUT = args.issueInput || args.issueNumber || "(none)"; // this ti
165
165
  const ISSUE_REQUIRED = String(args.issueRequired) === "false" ? "false" : "true"; // Pre-authoring step 0; only an explicit false turns it off — absent or unrecognised fails closed, like the resolver
166
166
  const APPLY_CONVENTIONS = String(args.applyConventions) === "false" ? "false" : "true";
167
167
  const COMPLIANCE_FRAMEWORKS = /^(?:off|none|[a-z][a-z0-9-]{0,15}(?:,[a-z][a-z0-9-]{0,15}){0,7})$/.test(String(args.complianceFrameworks)) ? String(args.complianceFrameworks) : "off"; // Pre-authoring step 0b; any other shape is no lens
168
- const COMPLIANCE_DIRECTIVE = COMPLIANCE_FRAMEWORKS === "off" ? "" : `When the task touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention), invoke Skill(skill="devflow:compliance") and load references/{id}.md only for the ids in ${COMPLIANCE_FRAMEWORKS} (none: generic controls only); never fabricate guidance for a framework you were not given.`; // D-COMPLIANCE-INJECT: empty when the lens is off, so a Code or Code-fix spawn then carries nothing about compliance; otherwise the one line _compliance.mds renders as compliance_directive(), with the validated ids in place of <ids>
168
+ const COMPLIANCE_DIRECTIVE = COMPLIANCE_FRAMEWORKS === "off" ? "" : `When the task touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention), invoke Skill(skill="devflow:compliance") and load references/{id}.md only for the ids in ${COMPLIANCE_FRAMEWORKS} (none: generic controls only); never fabricate guidance for a framework you were not given.`; // D-COMPLIANCE-INJECT: empty when the lens is off, so a Code or Fix spawn then carries nothing about compliance; otherwise the one line _compliance.mds renders as compliance_directive(), with the validated ids in place of <ids>
169
169
 
170
170
  // Phase 1: Git setup — declare the operation; the agent owns the process, the branch name included
171
171
  const setup = await phase("setup", () =>
@@ -220,16 +220,16 @@ After implementing, commit your changes with a conventional-commit message and r
220
220
  - Any open questions or blockers`, { agentType: "Code" })
221
221
  );
222
222
 
223
- // Phase 3: Gate 1 #1 — post-code pipeline: Simplify agent → Scrutinize agent → Validate agent.
223
+ // Phase 3: Gate 1 #1 — post-code pipeline: Polish agent → Harden agent → Validate agent.
224
224
  // Validate runs last and unconditionally, so its one full run covers every commit the pass made (see gate1_postcode()).
225
225
  const gate1 = await phase("gate1", async () => {
226
- await agent(`Simplify and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Simplify" });
226
+ await agent(`Polish and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Polish" });
227
227
 
228
- const scrutiny = await agent(`9-pillar self-review of recent changes on branch ${BRANCH}. Fix P0/P1 issues and commit the fixes.
229
- Return: {"status": "PASS" | "FIXED" | "BLOCKED"}`, { agentType: "Scrutinize" });
230
- // Anything but an explicit PASS or FIXED is a stop: a Scrutinize that returned no status, or one this skeleton does not know, has not accepted the code.
231
- if (!["PASS", "FIXED"].includes(scrutiny?.status)) {
232
- return { verdict: "ESCALATED", type: "scrutiny-blocked", reason: scrutiny?.status === "BLOCKED" ? "Scrutinize agent returned BLOCKED: a P0 issue cannot be fixed in scope" : "Scrutinize agent returned no recognised status: counted as BLOCKED" };
228
+ const harden = await agent(`9-pillar self-review of recent changes on branch ${BRANCH}. Fix P0/P1 issues and commit the fixes.
229
+ Return: {"status": "PASS" | "FIXED" | "BLOCKED"}`, { agentType: "Harden" });
230
+ // Anything but an explicit PASS or FIXED is a stop: a Harden that returned no status, or one this skeleton does not know, has not accepted the code.
231
+ if (!["PASS", "FIXED"].includes(harden?.status)) {
232
+ return { verdict: "ESCALATED", type: "harden-blocked", reason: harden?.status === "BLOCKED" ? "Harden agent returned BLOCKED: a P0 issue cannot be fixed in scope" : "Harden agent returned no recognised status: counted as BLOCKED" };
233
233
  }
234
234
 
235
235
  const validation = await agent(`Run build, typecheck, lint, and tests on branch ${BRANCH}.
@@ -248,19 +248,19 @@ ${failureDetails}
248
248
  DECISIONS_CONTEXT: ${DECISIONS_CONTEXT}
249
249
  <!-- learning:end -->
250
250
  ${COMPLIANCE_DIRECTIVE}
251
- Commit fixes with conventional-commit message.`, { agentType: "Code-fix" });
251
+ Commit fixes with conventional-commit message.`, { agentType: "Fix" });
252
252
  const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} after fix attempt ${attempt} (follow your Running commands block).
253
253
  Return: {"verdict": "PASS" | "FAIL", "details": "..."}`, { agentType: "Validate" });
254
254
  if (recheck?.verdict === "PASS") break;
255
255
  failureDetails = recheck?.details || failureDetails;
256
- if (attempt === 2) return { verdict: "ESCALATED", type: "validation-exhausted", reason: "Validation exhausted after 2 Code agent fix attempts" };
256
+ if (attempt === 2) return { verdict: "ESCALATED", type: "validation-exhausted", reason: "Validation exhausted after 2 Fix agent attempts" };
257
257
  }
258
258
  }
259
259
 
260
260
  return { verdict: "PASS" };
261
261
  });
262
262
 
263
- // Gate 1 #1 stop, before Gate 2: an exhausted Validate or a BLOCKED Scrutinize leaves a broken or unfinished build,
263
+ // Gate 1 #1 stop, before Gate 2: an exhausted Validate or a BLOCKED Harden leaves a broken or unfinished build,
264
264
  // so Gate 2 and the review pass never run on it — a correctness stop, like the ticket-link and branch stops.
265
265
  if (gate1.verdict === "ESCALATED") {
266
266
  return { ticket: TICKET, branch: BRANCH, verdict: "ESCALATED", issueId: ISSUE_NUMBER, issuePrLink: ISSUE_PR_LINK, escalations: [{ type: gate1.type, description: gate1.reason }] };
@@ -291,7 +291,7 @@ ${evaluation?.rationale || "see the Evaluate agent's report"}
291
291
  DECISIONS_CONTEXT: ${DECISIONS_CONTEXT}
292
292
  <!-- learning:end -->
293
293
  ${COMPLIANCE_DIRECTIVE}
294
- Self-verify your fix compiles, following your Running commands block. Commit fixes.`, { agentType: "Code-fix" });
294
+ Self-verify your fix compiles, following your Running commands block. Commit fixes.`, { agentType: "Fix" });
295
295
  evalVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
296
296
  }
297
297
  }
@@ -313,7 +313,7 @@ ${testResult.failures}
313
313
  DECISIONS_CONTEXT: ${DECISIONS_CONTEXT}
314
314
  <!-- learning:end -->
315
315
  ${COMPLIANCE_DIRECTIVE}
316
- Self-verify your fix compiles and the scenarios pass, following your Running commands block. Commit fixes.`, { agentType: "Code-fix" });
316
+ Self-verify your fix compiles and the scenarios pass, following your Running commands block. Commit fixes.`, { agentType: "Fix" });
317
317
  testVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
318
318
  }
319
319
  }
@@ -468,16 +468,16 @@ Return: {"status": "fixed"|"blocked", "commitShas": ["<sha>"], "unresolved": ["<
468
468
  return { survivingFindings: notAddressed, fixedFindings, coverageGaps };
469
469
  });
470
470
 
471
- // Phase 5.5: Gate 1 #2 — FINAL post-fix gate (Simplify agent → Scrutinize agent → full Validate agent, Validate last and unconditional).
471
+ // Phase 5.5: Gate 1 #2 — FINAL post-fix gate (Polish agent → Harden agent → full Validate agent, Validate last and unconditional).
472
472
  // Runs ONCE, after the review pass. Inside the pass the Code agent self-verified its own fixes;
473
473
  // this is the build gate before the branch is handed back. See gate1_postcode() cadence.
474
474
  const gate1Final = await phase("gate1-final", async () => {
475
- await agent(`Simplify and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Simplify" });
475
+ await agent(`Polish and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Polish" });
476
476
 
477
- const scrutiny = await agent(`9-pillar self-review of recent changes on branch ${BRANCH}. Fix P0/P1 issues and commit the fixes.
478
- Return: {"status": "PASS" | "FIXED" | "BLOCKED"}`, { agentType: "Scrutinize" });
479
- if (!["PASS", "FIXED"].includes(scrutiny?.status)) {
480
- return { verdict: "ESCALATED", type: "scrutiny-blocked", reason: scrutiny?.status === "BLOCKED" ? "Final Gate 1 Scrutinize agent returned BLOCKED: a P0 issue cannot be fixed in scope" : "Final Gate 1 Scrutinize agent returned no recognised status: counted as BLOCKED" };
477
+ const harden = await agent(`9-pillar self-review of recent changes on branch ${BRANCH}. Fix P0/P1 issues and commit the fixes.
478
+ Return: {"status": "PASS" | "FIXED" | "BLOCKED"}`, { agentType: "Harden" });
479
+ if (!["PASS", "FIXED"].includes(harden?.status)) {
480
+ return { verdict: "ESCALATED", type: "harden-blocked", reason: harden?.status === "BLOCKED" ? "Final Gate 1 Harden agent returned BLOCKED: a P0 issue cannot be fixed in scope" : "Final Gate 1 Harden agent returned no recognised status: counted as BLOCKED" };
481
481
  }
482
482
 
483
483
  const validation = await agent(`Run build, typecheck, lint, and tests on branch ${BRANCH} (final gate after all fixing).
@@ -494,12 +494,12 @@ ${failureDetails}
494
494
  DECISIONS_CONTEXT: ${DECISIONS_CONTEXT}
495
495
  <!-- learning:end -->
496
496
  ${COMPLIANCE_DIRECTIVE}
497
- Self-verify your fix compiles. Commit fixes with conventional-commit message.`, { agentType: "Code-fix" });
497
+ Self-verify your fix compiles. Commit fixes with conventional-commit message.`, { agentType: "Fix" });
498
498
  const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (final gate, after fix attempt ${attempt}; follow your Running commands block).
499
499
  Return: {"verdict": "PASS" | "FAIL", "details": "..."}`, { agentType: "Validate" });
500
500
  if (recheck?.verdict === "PASS") break;
501
501
  failureDetails = recheck?.details || failureDetails;
502
- if (attempt === 2) return { verdict: "ESCALATED", type: "validation-exhausted", reason: "Final Gate 1 validation exhausted after 2 Code agent fix attempts" };
502
+ if (attempt === 2) return { verdict: "ESCALATED", type: "validation-exhausted", reason: "Final Gate 1 validation exhausted after 2 Fix agent attempts" };
503
503
  }
504
504
  }
505
505
 
@@ -795,19 +795,13 @@ git -C "{integration worktree root}" push origin HEAD; echo "exit=$?"
795
795
 
796
796
  {{pub.publication_gate()}}
797
797
 
798
- Then spawn:
798
+ Then run the script inline — it is the whole `update-pr-evidence` operation, with no Git agent spawn — through the Bash tool with `timeout: 180000`:
799
799
 
800
- ```
801
- Agent(subagent_type="Git"):
802
- "OPERATION: update-pr-evidence
803
- PR_NUMBER: {n}
804
- EVIDENCE_FILE: .devflow/docs/evidence-wave-{slug}.md
805
- REVIEW_PUBLICATION: {REVIEW_PUBLICATION resolved above, or auto}
806
- WORKTREE_PATH: {integration worktree root}
807
- Update the wave PR's test-plan block and post its evidence comment."
800
+ ```bash
801
+ cd "{integration worktree root}" && node "$HOME/.devflow/scripts/verify-evidence.cjs" publish --pr {n} --evidence ".devflow/docs/evidence-wave-{slug}.md" --publication {REVIEW_PUBLICATION resolved above, or auto}; echo "exit=$?"
808
802
  ```
809
803
 
810
- `update-pr-evidence` decides what each publication value means for the evidence comment. Report its `## PR Evidence` block — its `EVIDENCE` line and its `**Body**:` / `**Comment**:` line — or its `TRACEABILITY: DEGRADED ({reason})` line; a spawn that returns neither ⇒ `TRACEABILITY: DEGRADED (evidence refresh failed)`. Whatever it returns, the run ends here.
804
+ `{n}` is the number admitted above, and the publication value is `auto`, `full`, `off` or `stub`. `publish` decides what each publication value means for the evidence comment. Report its `## PR Evidence` block — its `EVIDENCE` line and its `**Body**:` / `**Comment**:` line — with any `TRACEABILITY: DEGRADED ({reason})` lines after it, or its `TRACEABILITY: DEGRADED (evidence unavailable)` line; empty stdout or any other exit ⇒ `TRACEABILITY: DEGRADED (evidence refresh failed)`. Whatever it returns, the run ends here.
811
805
 
812
806
  ---
813
807