devflow-kit 3.9.0 → 3.11.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 (168) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/README.md +1 -1
  3. package/dist/agents/code.md +6 -6
  4. package/dist/agents/fix.md +6 -6
  5. package/dist/agents/harden.md +7 -6
  6. package/dist/agents/refactor.md +6 -6
  7. package/dist/cli/commands/ambient.js +10 -2
  8. package/dist/cli/commands/backup-session.js +131 -0
  9. package/dist/cli/commands/compliance-prompts.js +9 -4
  10. package/dist/cli/commands/compliance.js +184 -24
  11. package/dist/cli/commands/curation.js +23 -10
  12. package/dist/cli/commands/gate-level-prompts.js +39 -25
  13. package/dist/cli/commands/gates.js +5 -7
  14. package/dist/cli/commands/init.js +169 -184
  15. package/dist/cli/commands/install-report.js +129 -0
  16. package/dist/cli/commands/legacy-sweep.js +159 -0
  17. package/dist/cli/commands/proxy.js +6 -1
  18. package/dist/cli/commands/rules.js +75 -21
  19. package/dist/cli/commands/skills.js +42 -9
  20. package/dist/cli/commands/tracker.js +9 -3
  21. package/dist/cli/commands/uninstall.js +339 -75
  22. package/dist/commands/bug-analysis.md +69 -120
  23. package/dist/commands/dynamic-build.md +23 -23
  24. package/dist/commands/implement.md +46 -32
  25. package/dist/commands/release.md +1 -1
  26. package/dist/commands/resolve.md +35 -31
  27. package/dist/commands/self-review.md +8 -7
  28. package/dist/compliance-off/agents/git.md +120 -0
  29. package/dist/compliance-off/agents/triage.md +180 -0
  30. package/dist/compliance-off/commands/bug-analysis.md +398 -0
  31. package/dist/compliance-off/commands/code-review.md +520 -0
  32. package/dist/compliance-off/commands/dynamic-build.md +1251 -0
  33. package/dist/compliance-off/commands/dynamic-tickets.md +676 -0
  34. package/dist/compliance-off/commands/implement.md +736 -0
  35. package/dist/compliance-off/commands/plan.md +671 -0
  36. package/dist/compliance-off/commands/release.md +309 -0
  37. package/dist/compliance-off/commands/resolve.md +742 -0
  38. package/dist/compliance-off/skills/git/references/decision-markers.md +17 -0
  39. package/dist/compliance-off/skills/git/references/learn-conventions.md +80 -0
  40. package/dist/compliance-off/skills/git/references/pr/check-ci-status.md +33 -0
  41. package/dist/compliance-off/skills/git/references/pr/check-merge-readiness.md +49 -0
  42. package/dist/compliance-off/skills/git/references/pr/fetch-review-threads.md +52 -0
  43. package/dist/compliance-off/skills/git/references/pr/validate-branch.md +47 -0
  44. package/dist/compliance-off/skills/git/references/tracker/_contract.md +33 -0
  45. package/dist/compliance-off/skills/git/references/tracker/_mcp.md +153 -0
  46. package/dist/compliance-off/skills/git/references/tracker/github/create-release.md +35 -0
  47. package/dist/compliance-off/skills/git/references/tracker/github/ensure-pr-ready.md +100 -0
  48. package/dist/compliance-off/skills/git/references/tracker/github/ensure-traceable-issue.md +74 -0
  49. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issue.md +69 -0
  50. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issues-batch.md +65 -0
  51. package/dist/compliance-off/skills/git/references/tracker/github/gather-release-evidence.md +48 -0
  52. package/dist/compliance-off/skills/git/references/tracker/github/setup-task.md +77 -0
  53. package/dist/compliance-off/skills/git/references/tracker/jira/create-release.md +35 -0
  54. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-pr-ready.md +100 -0
  55. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-traceable-issue.md +61 -0
  56. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issue.md +51 -0
  57. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issues-batch.md +63 -0
  58. package/dist/compliance-off/skills/git/references/tracker/jira/gather-release-evidence.md +47 -0
  59. package/dist/compliance-off/skills/git/references/tracker/jira/setup-task.md +82 -0
  60. package/dist/compliance-off/skills/git/references/tracker/linear/create-release.md +35 -0
  61. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-pr-ready.md +100 -0
  62. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-traceable-issue.md +61 -0
  63. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issue.md +51 -0
  64. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issues-batch.md +63 -0
  65. package/dist/compliance-off/skills/git/references/tracker/linear/gather-release-evidence.md +47 -0
  66. package/dist/compliance-off/skills/git/references/tracker/linear/setup-task.md +83 -0
  67. package/dist/compliance-off/skills/git/references/trust-rule.md +7 -0
  68. package/dist/core/agent-models.js +19 -4
  69. package/dist/core/assets.js +126 -17
  70. package/dist/core/compliance-off-files.js +27 -0
  71. package/dist/core/compliance.js +14 -0
  72. package/dist/core/curation-variants.js +460 -112
  73. package/dist/core/flags.js +2 -2
  74. package/dist/core/fs-atomic.js +5 -1
  75. package/dist/core/installed-variants.js +63 -0
  76. package/dist/core/manifest.js +48 -5
  77. package/dist/core/mds-variants.js +700 -3
  78. package/dist/core/orphan-sweep.js +29 -2
  79. package/dist/core/path-set.js +15 -0
  80. package/dist/core/plugins.js +68 -10
  81. package/dist/core/reference-sweep.js +42 -25
  82. package/dist/core/retired-shipped-names.js +278 -0
  83. package/dist/curation-compliance-off/agents/triage.md +176 -0
  84. package/dist/curation-compliance-off/commands/bug-analysis.md +349 -0
  85. package/dist/curation-compliance-off/commands/code-review.md +481 -0
  86. package/dist/curation-compliance-off/commands/dynamic-build.md +1211 -0
  87. package/dist/curation-compliance-off/commands/dynamic-tickets.md +634 -0
  88. package/dist/curation-compliance-off/commands/implement.md +689 -0
  89. package/dist/curation-compliance-off/commands/plan.md +631 -0
  90. package/dist/curation-compliance-off/commands/release.md +279 -0
  91. package/dist/curation-compliance-off/commands/resolve.md +692 -0
  92. package/dist/curation-off/agents/code.md +6 -6
  93. package/dist/curation-off/agents/fix.md +6 -6
  94. package/dist/curation-off/agents/harden.md +7 -6
  95. package/dist/curation-off/agents/refactor.md +6 -6
  96. package/dist/curation-off/commands/bug-analysis.md +69 -119
  97. package/dist/curation-off/commands/dynamic-build.md +23 -23
  98. package/dist/curation-off/commands/implement.md +46 -32
  99. package/dist/curation-off/commands/release.md +1 -1
  100. package/dist/curation-off/commands/resolve.md +35 -31
  101. package/dist/curation-off/commands/self-review.md +8 -7
  102. package/dist/skills/git/references/pr/resolve-review-threads.md +1 -1
  103. package/dist/targets/claude-code/behavior-install.js +23 -9
  104. package/dist/targets/claude-code/charter-render.js +374 -0
  105. package/dist/targets/claude-code/compliance-install.js +62 -17
  106. package/dist/targets/claude-code/compliance-off-files.js +249 -0
  107. package/dist/targets/claude-code/curation-install.js +632 -117
  108. package/dist/targets/claude-code/folder-swap.js +142 -0
  109. package/dist/targets/claude-code/install-backup.js +780 -0
  110. package/dist/targets/claude-code/installer.js +795 -199
  111. package/dist/targets/claude-code/language-stamp.js +6 -0
  112. package/dist/targets/claude-code/legacy-skill-hashes.js +170 -0
  113. package/dist/targets/claude-code/linked-folder.js +176 -0
  114. package/dist/targets/claude-code/reference-converge.js +131 -0
  115. package/dist/targets/claude-code/rules-folder.js +34 -0
  116. package/dist/targets/claude-code/shipped-set.js +160 -0
  117. package/dist/targets/claude-code/tracker-install.js +21 -8
  118. package/dist/targets/claude-code/tracker-servers.js +20 -6
  119. package/dist/targets/claude-code/workflow-folder-install.js +251 -0
  120. package/dist/variant-axes.json +109 -0
  121. package/package.json +1 -1
  122. package/src/assets/agents/_partials/_code.mds +6 -6
  123. package/src/assets/agents/evaluate.md +1 -1
  124. package/src/assets/agents/git.mds +32 -0
  125. package/src/assets/agents/harden.mds +7 -6
  126. package/src/assets/agents/test.md +21 -12
  127. package/src/assets/agents/triage.mds +2 -0
  128. package/src/assets/agents/validate.md +10 -10
  129. package/src/assets/commands/_partials/_compliance.mds +5 -3
  130. package/src/assets/commands/_partials/_engine.mds +9 -8
  131. package/src/assets/commands/_partials/_publication.mds +10 -1
  132. package/src/assets/commands/bug-analysis.mds +80 -126
  133. package/src/assets/commands/code-review.mds +43 -0
  134. package/src/assets/commands/dynamic-build.mds +109 -15
  135. package/src/assets/commands/dynamic-tickets.mds +13 -0
  136. package/src/assets/commands/implement.mds +145 -33
  137. package/src/assets/commands/plan.mds +19 -0
  138. package/src/assets/commands/release.mds +50 -1
  139. package/src/assets/commands/resolve.mds +217 -32
  140. package/src/assets/commands/self-review.mds +8 -7
  141. package/src/assets/mds/git/_ops.mds +23 -0
  142. package/src/assets/mds/git/_ops_steps.mds +17 -0
  143. package/src/assets/mds/git/_pr.mds +1 -1
  144. package/src/assets/mds/git/_references.mds +6 -0
  145. package/src/assets/mds/tracker/_common.mds +4 -0
  146. package/src/assets/mds/tracker/_github.mds +42 -0
  147. package/src/assets/mds/tracker/_jira.mds +43 -0
  148. package/src/assets/mds/tracker/_linear.mds +43 -0
  149. package/src/assets/rules/quality.md +2 -0
  150. package/src/assets/scripts/ci-wait.cjs +204 -126
  151. package/src/assets/scripts/hooks/assets/implement-installed +1 -0
  152. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +13 -11
  153. package/src/assets/scripts/hooks/preamble +18 -8
  154. package/src/assets/scripts/hooks/session-start-orchestrator +4 -2
  155. package/src/assets/scripts/pr-evidence.cjs +41 -2
  156. package/src/assets/scripts/verify-evidence.cjs +408 -56
  157. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +3 -3
  158. package/src/assets/skills/agent-references/references/commands/plan-levels.md +1 -1
  159. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +6 -2
  160. package/src/assets/skills/agent-references/references/validate/passed-alone.md +7 -7
  161. package/src/assets/skills/docs-framework/SKILL.md +5 -2
  162. package/src/assets/skills/git/SKILL.md +3 -3
  163. package/src/assets/skills/git/references/github-api.md +2 -139
  164. package/src/assets/skills/git/references/github-posting.md +158 -0
  165. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  166. package/src/assets/skills/review-methodology/references/patterns.md +1 -1
  167. package/src/assets/skills/review-methodology/references/report-template.md +1 -2
  168. package/src/assets/skills/testing/SKILL.md +2 -4
@@ -8,12 +8,12 @@ output-dir: dist/commands
8
8
  @import { evidence_policy } from "./_partials/_evidence_policy.mds"
9
9
  @import { issue_ref_grammar, issue_capture_contract } from "./_partials/_tracker.mds"
10
10
  @import { test_plan_line } from "./_partials/_plan_contract.mds"
11
- @import { publication_gate } from "./_partials/_publication.mds"
11
+ @import { publication_gate, publication_resolve } from "./_partials/_publication.mds"
12
12
  @import "./_partials/_compliance.mds" as compliance
13
13
  @import "./_partials/_settings.mds" as settings
14
14
  # Implement Command
15
15
 
16
- Orchestrate a single task through implementation by spawning specialized agents.
16
+ Orchestrate a single task by spawning agents.
17
17
 
18
18
  ## Usage
19
19
 
@@ -49,9 +49,17 @@ When the user explicitly asks to re-validate, re-check, or re-run quality gates
49
49
  ### Phase 1: Setup
50
50
 
51
51
  <!-- curation:on -->
52
+ <!-- compliance:on -->
52
53
  **Produces:** TASK_ID, BASE_BRANCH, BASE_REF, EXECUTION_PLAN, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, PR_DESCRIPTION_GUIDANCE, ISSUE_NUMBER, ISSUE_PR_LINK, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, PR_EXCEPTIONS, TEST_PLAN, EVIDENCE_FILE, PR_TEST_PLAN_BLOCK, REVIEW_PUBLICATION, GATE_LEVEL
54
+ <!-- compliance:off -->
55
+ **Produces:** TASK_ID, BASE_BRANCH, BASE_REF, EXECUTION_PLAN, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, PR_DESCRIPTION_GUIDANCE, ISSUE_NUMBER, ISSUE_PR_LINK, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, EVIDENCE_EXCEPTIONS, TEST_PLAN, EVIDENCE_FILE, REVIEW_PUBLICATION, GATE_LEVEL
56
+ <!-- compliance:end -->
53
57
  <!-- curation:off -->
58
+ <!-- compliance:on -->
54
59
  **Produces:** TASK_ID, BASE_BRANCH, BASE_REF, EXECUTION_PLAN, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, PR_DESCRIPTION_GUIDANCE, ISSUE_NUMBER, ISSUE_PR_LINK, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, PR_EXCEPTIONS, TEST_PLAN, EVIDENCE_FILE, PR_TEST_PLAN_BLOCK, REVIEW_PUBLICATION, GATE_LEVEL
60
+ <!-- compliance:off -->
61
+ **Produces:** TASK_ID, BASE_BRANCH, BASE_REF, EXECUTION_PLAN, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, PR_DESCRIPTION_GUIDANCE, ISSUE_NUMBER, ISSUE_PR_LINK, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, EVIDENCE_EXCEPTIONS, TEST_PLAN, EVIDENCE_FILE, REVIEW_PUBLICATION, GATE_LEVEL
62
+ <!-- compliance:end -->
55
63
  <!-- curation:end -->
56
64
 
57
65
  Record the current branch name as `BASE_BRANCH`. Stop the run unless it matches `^(?![-#]|origin\/|(?:@|(?:FETCH_|ORIG_|MERGE_)?HEAD)$)(?!.*\.\.)[A-Za-z0-9._\/+@,#-]{1,200}$` (judge the match by reading; never pass the value to a command), telling the user it allows only ASCII letters, digits and `._/+@,#-`, at most 200; no leading `-` or `#`, no `origin/` prefix, no `..`, not `@` or a HEAD name.
@@ -59,6 +67,9 @@ Record the current branch name as `BASE_BRANCH`. Stop the run unless it matches
59
67
  {{docs_root()}}
60
68
 
61
69
  {{evidence_policy()}}
70
+ <!-- compliance:off -->
71
+ When `EVIDENCE_POLICY` is `required`, record `TRACEABILITY: DEGRADED (compliance off on this machine; the repository requires evidence)` once, for the Phase 12 report.
72
+ <!-- compliance:end -->
62
73
 
63
74
  **Plan Document Handling** (when `COMMAND_INPUT` is a path ending in `.md`):
64
75
  1. Read the plan document from the path provided
@@ -73,7 +84,7 @@ If `PR_DESCRIPTION_GUIDANCE` was not set above (non-plan paths: issue input or t
73
84
 
74
85
  **Empty input.** When `COMMAND_INPUT` is empty — a plan handoff arrives this way, with the plan already in the conversation — there is no argument to name the branch from, and the Git agent sees none of this conversation. Write the description yourself: one line, taken from the plan's title or, with no plan, from the conversation. Send it as the setup-task `TASK_DESCRIPTION` below.
75
86
 
76
- Spawn Git agent to set up the task:
87
+ Spawn Git agent:
77
88
 
78
89
  ```
79
90
  Agent(subagent_type="Git"):
@@ -83,14 +94,20 @@ ISSUE_INPUT: {COMMAND_INPUT verbatim, when it is a single whitespace-delimited t
83
94
  TASK_DESCRIPTION: {COMMAND_INPUT verbatim, when it is two or more whitespace-delimited tokens; when COMMAND_INPUT is empty, the one-line description you wrote above — otherwise omit}
84
95
  ISSUE_REQUIRED: {ISSUE_REQUIRED}
85
96
  APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
97
+ <!-- compliance:on -->
86
98
  PLAN_ARTIFACT_PATH: {path to plan document if COMMAND_INPUT ends in .md, otherwise (none)}
99
+ <!-- compliance:end -->
87
100
  Derive branch name from issue or description, create feature branch, and fetch issue if specified.
88
101
  Return the branch setup summary."
89
102
  ```
90
103
 
91
104
  The issue token is forwarded **unclassified**; routing is by SHAPE alone (the token count of `COMMAND_INPUT` and a `.md` ending). Only `setup-task` has resolved a provider, so a `starts with #` test would be a github test that reclassifies `PROJ-12` and `ENG-12` as task descriptions: the branch comes from prose, no issue is fetched and nothing reports it. Token COUNT is provider-neutral: every issue spelling is one token and no free-text description is.
92
105
 
106
+ <!-- compliance:on -->
93
107
  - **Extension.** A path ending in `.md` is a plan document, never an issue reference: it goes to `PLAN_ARTIFACT_PATH` only, and `ISSUE_INPUT` carries the plan's frontmatter `issue`, never the path (Plan Document Handling step 4).
108
+ <!-- compliance:off -->
109
+ - **Extension.** A path ending in `.md` is a plan document, never an issue reference: `ISSUE_INPUT` carries the plan's frontmatter `issue`, never the path (Plan Document Handling step 4).
110
+ <!-- compliance:end -->
94
111
  - **Token count.** One token is an issue reference; two or more is prose. Forwarding the FIRST token alone would send `/implement fix the login bug` as `ISSUE_INPUT: fix` with no description, so the request is dropped.
95
112
 
96
113
  **Capture from Git agent output** (used throughout flow):
@@ -101,11 +118,39 @@ The issue token is forwarded **unclassified**; routing is by SHAPE alone (the to
101
118
 
102
119
  {{issue_capture_contract()}}
103
120
 
121
+ <!-- compliance:on -->
104
122
  **Ticket link, only when `ISSUE_REQUIRED` is `true`:** when the capture above holds no `ISSUE_PR_LINK` (absent, or `(none)`), run `d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; printf '%s\n' "$d"` in Bash, Read `<that directory>/skills/devflow:agent-references/references/commands/implement-evidence-asks.md` with the Read tool (once per run), then run its ticket link ask and **Record the exception at once** as it directs, before any Code spawn. `PR_EXCEPTIONS` is `(none)` until an exception is recorded.
123
+ <!-- compliance:off -->
124
+ **Ticket link, only when `ISSUE_REQUIRED` is `true`:** when the capture above holds no `ISSUE_PR_LINK` (absent, or `(none)`), ask with AskUserQuestion before any Code spawn — "No tracker issue is linked to this task. Record a self-attested exception, or stop?" — offering exactly these two options:
125
+ - **Record an exception** — the user gives the reason as free text. Render it with the exception grammar below, as kind `ticket-link`; when the rendered reason is empty, ask for it once more, and stop as below if it is empty again.
126
+ - **Stop** — report `BLOCKED (no ticket link)`, name the branch setup-task created (`TASK_ID`) and `BASE_BRANCH` so it can be reused or removed, and give the remedy: create or link the tracker issue and re-run `/implement` with its reference, or — for a team that does not want ticket links — commit `.devflow/project.json` as `{"version":1,"evidence":"standard"}` on the default branch. Spawn nothing further.
105
127
 
128
+ **Exception grammar.** Render each evidence exception as one line under a `## Evidence Exceptions` heading, in exactly this shape:
129
+
130
+ ```markdown
131
+ ## Evidence Exceptions
132
+ - `<kind>` self-attested by @<login> at <utc>: <reason>
133
+ ```
134
+
135
+ - `<kind>` is `ticket-link` or `test-plan` — a closed set; the section holds each kind at most once.
136
+ - `@<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 `@`.
137
+ - `<utc>` is the output of `date -u +%Y-%m-%dT%H:%M:%SZ`.
138
+ - `<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.
139
+
140
+ **Record the exception at once**, before any Code spawn: set `EVIDENCE_EXCEPTIONS` to the rendered section. The test plan step below writes it into `EVIDENCE_FILE`, its one home. `EVIDENCE_EXCEPTIONS` is `(none)` until an exception is recorded.
141
+ <!-- compliance:end -->
142
+
143
+ <!-- compliance:on -->
106
144
  **Test plan.** Before any Code spawn, give the task a test plan in the evidence file `{worktree}/.devflow/docs/evidence-{branch_slug}.md` (`EVIDENCE_FILE`) — unlike the handoff file, it stays after the PR exists. It holds up to three sections, in this order and nothing else: `## Test Plan`; `## Evidence Exceptions`, a byte copy of `PR_EXCEPTIONS` present only while that is not `(none)`; and `## Claims`, always last, so every claim is appended at the end of the file. Create the file if absent; if it exists, replace its `## Test Plan` and `## Evidence Exceptions` sections and keep `## Claims` byte-identical.
145
+ <!-- compliance:off -->
146
+ **Test plan.** Before any Code spawn, give the task a test plan in the evidence file `{worktree}/.devflow/docs/evidence-{branch_slug}.md` (`EVIDENCE_FILE`) — unlike the handoff file, it stays after the PR exists. It holds up to three sections, in this order and nothing else: `## Test Plan`; `## Evidence Exceptions`, a byte copy of `EVIDENCE_EXCEPTIONS` present only while that is not `(none)`; and `## Claims`, always last, so every claim is appended at the end of the file. Create the file if absent; if it exists, replace its `## Test Plan` and `## Evidence Exceptions` sections and keep `## Claims` byte-identical.
147
+ <!-- compliance:end -->
107
148
 
149
+ <!-- compliance:on -->
108
150
  Write the `## Test Plan` section: when `COMMAND_INPUT` is a plan document with a `## Test Plan` section, copy that section's lines verbatim; otherwise write one TP line per acceptance criterion the plan, the issue or the task text states, numbered from `TP-1`. Never invent a criterion, and word every scenario yourself in plain words: the lines reach the PR body, so a scenario holds no `#`, `@` or `/` — no issue reference, mention, closing keyword target or URL — and the files a TP covers go in its `files:` field. Each line follows the TP-line contract:
151
+ <!-- compliance:off -->
152
+ Write the `## Test Plan` section: when `COMMAND_INPUT` is a plan document with a `## Test Plan` section, copy that section's lines verbatim; otherwise write one TP line per acceptance criterion the plan, the issue or the task text states, numbered from `TP-1`. Never invent a criterion, and word every scenario yourself in plain words: a scenario holds no `#`, `@` or `/` — no issue reference, mention, closing keyword target or URL — and the files a TP covers go in its `files:` field. Each line follows the TP-line contract:
153
+ <!-- compliance:end -->
109
154
 
110
155
  {{test_plan_line()}}
111
156
 
@@ -117,12 +162,19 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" check tp "{worktree}/.devflow/
117
162
 
118
163
  `exit=0` passes. On any other result, rewrite the section once — the script names the failing line and its code on stderr — and check again. Still failing, or no line to write, means the test plan is **missing**: drop the `## Test Plan` section from the file.
119
164
 
165
+ <!-- compliance:on -->
120
166
  **Missing test plan, only when `EVIDENCE_POLICY` is `required`:** when the check above leaves the test plan missing, Read the evidence-asks reference as in the ticket link step (when this run has not) and run its missing test plan ask before any Code spawn.
167
+ <!-- compliance:off -->
168
+ **Missing test plan, only when `EVIDENCE_POLICY` is `required`:** when the check above leaves the test plan missing, ask with AskUserQuestion before any Code spawn — "No test plan could be written for this task. Record a self-attested exception, or stop?" — offering exactly these two options:
169
+ - **Record an exception** — the user gives the reason as free text. Render it with the exception grammar above, as kind `test-plan`; when the rendered reason is empty, ask for it once more, and stop as below if it is empty again. Add the rendered line to the `## Evidence Exceptions` section of `EVIDENCE_FILE` — after any `ticket-link` line, creating the section when absent — and set `EVIDENCE_EXCEPTIONS` to that section.
170
+ - **Stop** — report `BLOCKED (no test plan)`, name `TASK_ID` and `BASE_BRANCH` so the branch can be reused or removed, and give the remedy: state the acceptance criteria in the task, the issue or a `/plan` document (its `## Test Plan` section is copied) and re-run `/implement`, or — for a team that does not want test plans enforced — commit `.devflow/project.json` as `{"version":1,"evidence":"standard"}` on the default branch. Spawn nothing further.
171
+ <!-- compliance:end -->
121
172
 
122
173
  When `EVIDENCE_POLICY` is `standard`, a missing test plan is never asked about: carry `Test plan: missing` to the Phase 12 report.
123
174
 
124
175
  **Test-plan outputs**, set once before any Code spawn:
125
176
  - `TEST_PLAN` — the TP lines of the evidence file's `## Test Plan` section, or `(none)` when the test plan is missing.
177
+ <!-- compliance:on -->
126
178
  - `PR_TEST_PLAN_BLOCK` — when the test plan is present and this render ends in `exit=0`, its stdout byte for byte without that `exit=` line; `(none)` otherwise:
127
179
 
128
180
  ```bash
@@ -130,11 +182,19 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.dev
130
182
  ```
131
183
 
132
184
  - `EVIDENCE_FILE` — `{worktree}/.devflow/docs/evidence-{branch_slug}.md`, its `## Evidence Exceptions` section now a byte copy of `PR_EXCEPTIONS` (absent when that is `(none)`).
185
+ <!-- compliance:off -->
186
+ - `EVIDENCE_FILE` — `{worktree}/.devflow/docs/evidence-{branch_slug}.md`, its `## Evidence Exceptions` section now a byte copy of `EVIDENCE_EXCEPTIONS` (absent when that is `(none)`).
187
+ <!-- compliance:end -->
133
188
 
134
189
  {{settings.settings_resolve()}}
135
190
 
191
+ <!-- compliance:on -->
136
192
  {{publication_gate()}}
137
193
  Phase 11 passes the resolved value to the evidence script (`publish`), which decides what each value means for the evidence comment. From the same line: {{compliance.compliance_frameworks()}}
194
+ <!-- compliance:off -->
195
+ {{publication_resolve()}}
196
+ Phase 11 passes no publication value: the local verify posts nothing. From the same line: {{compliance.compliance_frameworks()}}
197
+ <!-- compliance:end -->
138
198
 
139
199
  {{compliance.compliance_inject()}}
140
200
 
@@ -189,7 +249,7 @@ DECISIONS_CONTEXT: {decisions_context}
189
249
 
190
250
  **SEQUENTIAL_CODE_AGENTS**:
191
251
 
192
- Spawn Code agents one at a time. Each appends its own phase section to the handoff file, and the next reads only the section before it:
252
+ Spawn Code agents one at a time:
193
253
 
194
254
  **Phase 1 Code agent:**
195
255
  ```
@@ -278,7 +338,7 @@ DECISIONS_CONTEXT: {decisions_context}
278
338
  - If the Read fails, or the file has no `## Phases` heading with the `| Phase | standard | lean |` header, or a row breaks its grammar, apply no row, keep `GATE_LEVEL` and say `level reference unreadable: no level rows applied`.
279
339
  - Validate, the CI gate, the evidence claims and the compliance directive run at every level. An enabled compliance lens keeps Harden.
280
340
 
281
- After the Code agent completes, spawn Polish agent to polish the code. The Phase 6 Validate covers its commits. `{branch_diff}` is the output of `git diff --name-only --diff-filter=d {BASE_REF}...HEAD`, run again at each spawn; a non-zero exit stops, and an empty list counts only on exit 0.
341
+ After the Code agent completes, spawn Polish agent. `{branch_diff}` is the output of `git diff --name-only --diff-filter=d {BASE_REF}...HEAD`, run again at each spawn; a non-zero exit stops, and an empty list counts only on exit 0.
282
342
 
283
343
  ```
284
344
  Agent(subagent_type="Polish"):
@@ -294,7 +354,7 @@ Commit any improvements with a conventional-commit message."
294
354
  **Produces:** HARDEN_OUTPUT
295
355
  **Requires:** BASE_REF
296
356
 
297
- After Phase 3, spawn Harden agent as the quality gate:
357
+ After Phase 3, spawn Harden agent:
298
358
 
299
359
  ```
300
360
  Agent(subagent_type="Harden"):
@@ -309,12 +369,14 @@ Evaluate 9 pillars, fix P0/P1 issues, report status"
309
369
 
310
370
  Harden agent reports `### Status: PASS | FIXED | BLOCKED`. **If BLOCKED:** report to user and halt. **If PASS or FIXED:** continue to Phase 5. A FIXED status commits fixes and starts no Validate of its own: the Phase 6 run covers them.
311
371
 
372
+ Harden never reviews a deleted file or the old path of a rename; an empty list is no review, and Harden reports `no files reviewed`.
373
+
312
374
  ### Phase 5: Alignment Check
313
375
 
314
376
  **Produces:** ALIGNMENT_RESULT
315
377
  **Requires:** BASE_REF, EXECUTION_PLAN
316
378
 
317
- After Harden agent passes, spawn Evaluate agent to validate alignment. Evaluate agent receives `FEATURE_KNOWLEDGE_RULES` as acceptance context only; pattern and anti-pattern judgments belong to Harden agent:
379
+ After Harden agent passes, spawn Evaluate agent:
318
380
 
319
381
  ```
320
382
  Agent(subagent_type="Evaluate"):
@@ -332,7 +394,7 @@ Validate alignment with request and plan. Report ALIGNED or MISALIGNED with deta
332
394
  1. Extract misalignment details from Evaluate agent output
333
395
  2. Increment `alignment_fix_count`
334
396
  3. If `alignment_fix_count <= 2`:
335
- - Spawn Fix agent to fix misalignments:
397
+ - Spawn Fix agent:
336
398
  ```
337
399
  Agent(subagent_type="Fix"):
338
400
  "OPERATION: alignment-fix
@@ -353,7 +415,9 @@ Validate alignment with request and plan. Report ALIGNED or MISALIGNED with deta
353
415
  **Produces:** VALIDATION_RESULT, VALIDATED_HEAD
354
416
  **Requires:** BASE_REF, GATE_LEVEL
355
417
 
356
- Validate takes the one full-suite slot, after every commit it must cover: Code, Polish, Harden and the alignment fixes. After Evaluate agent passes, spawn Validate agent. `FILES_CHANGED` is the branch diff:
418
+ Alignment-fix commits get no self-review: Phase 6 Validate and `/code-review` check them.
419
+
420
+ After Evaluate agent passes, spawn Validate agent:
357
421
 
358
422
  ```
359
423
  Agent(subagent_type="Validate"):
@@ -365,10 +429,9 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
365
429
  ```
366
430
 
367
431
  **If FAIL:**
368
- 1. Extract failure details from Validate agent output
369
- 2. Increment `validation_retry_count`
370
- 3. If `validation_retry_count <= 2`:
371
- - Spawn Fix agent with fix context:
432
+ 1. Increment `validation_retry_count`
433
+ 2. If `validation_retry_count <= 2`:
434
+ - Spawn Fix agent:
372
435
  ```
373
436
  Agent(subagent_type="Fix"):
374
437
  "OPERATION: validation-fix
@@ -382,10 +445,14 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
382
445
  {COMPLIANCE_DIRECTIVE}"
383
446
  ```
384
447
  - Loop back to Phase 6 (re-validate at the new HEAD, full scope)
385
- 4. If `validation_retry_count > 2`: Report failures to user and halt
448
+ 3. Else report failures to user and halt
449
+
450
+ **If BLOCKED:** report its cause and log path, then halt.
386
451
 
387
452
  **If PASS:** append a `gate:validate` claim, run `git rev-parse HEAD` and record the result as `VALIDATED_HEAD`, then continue to Phase 7.
388
453
 
454
+ Any other or missing Status: report and halt; never PASS.
455
+
389
456
  **Evidence claims** are lines appended to the `## Claims` section of `EVIDENCE_FILE` — the file's last section, created when absent. Append only: never edit or remove a claim; the last valid one per target wins. Each line takes exactly one of these shapes, where `<head>` is the 40-hex `HEAD:` the agent's report shows:
390
457
 
391
458
  ```
@@ -402,7 +469,7 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
402
469
  **Produces:** QA_RESULT
403
470
  **Requires:** BASE_REF, EXECUTION_PLAN, TEST_PLAN, VALIDATED_HEAD
404
471
 
405
- After Phase 6 passes, spawn Test agent for scenario-based acceptance testing:
472
+ After Phase 6 passes, spawn Test agent:
406
473
 
407
474
  ```
408
475
  Agent(subagent_type="Test"):
@@ -411,18 +478,17 @@ EXECUTION_PLAN: {execution plan from Phase 1}
411
478
  FILES_CHANGED: {branch_diff}
412
479
  ACCEPTANCE_CRITERIA: {extracted criteria if available}
413
480
  TEST_PLAN: {the TP lines of the evidence file's ## Test Plan section, or (none)}
414
- Design and execute scenario-based acceptance tests. Report PASS or FAIL with evidence."
481
+ Design and execute scenario-based acceptance tests. Report your Status with evidence."
415
482
  ```
416
483
 
417
- After every Test agent run — PASS or FAIL, first run or retry — append its TP claims (Phase 6's **Evidence claims**).
484
+ After every Test agent run — whatever its Status, first run or retry — append its TP claims (Phase 6's **Evidence claims**).
418
485
 
419
- **If PASS:** Continue to Phase 8
486
+ **If PASS** (first word of the Status): Continue to Phase 8
420
487
 
421
488
  **If FAIL:**
422
- 1. Extract failure details from Test agent output
423
- 2. Increment `qa_retry_count`
424
- 3. If `qa_retry_count <= 2`:
425
- - Spawn Fix agent to fix QA failures:
489
+ 1. Increment `qa_retry_count`
490
+ 2. If `qa_retry_count <= 2`:
491
+ - Spawn Fix agent:
426
492
  ```
427
493
  Agent(subagent_type="Fix"):
428
494
  "OPERATION: qa-fix
@@ -435,15 +501,17 @@ After every Test agent run — PASS or FAIL, first run or retry — append its T
435
501
  <!-- curation:end -->
436
502
  {COMPLIANCE_DIRECTIVE}"
437
503
  ```
438
- - Loop back to Phase 7 (re-run Test agent). The fix is not validated here: Phase 8 covers it.
439
- 4. If `qa_retry_count > 2`: Report QA failures to user for decision. The run stops at the report (Phase 12), so Phases 8 to 11 do not run.
504
+ - Loop back to Phase 7.
505
+ 3. If `qa_retry_count > 2`: Report QA failures to user for decision. The run stops at the report (Phase 12), so Phases 8 to 11 do not run.
506
+
507
+ **If BLOCKED, or any other or missing Status:** report its cause and log path, and stop as in step 3; no Fix agent.
440
508
 
441
509
  ### Phase 8: Re-Validate (only if a qa-fix committed)
442
510
 
443
511
  **Produces:** REVALIDATION_RESULT
444
- **Requires:** QA_RESULT, VALIDATED_HEAD
512
+ **Requires:** QA_RESULT, VALIDATED_HEAD, BASE_REF, GATE_LEVEL
445
513
 
446
- Run this phase only if a qa-fix committed (`git rev-parse HEAD` differs from `VALIDATED_HEAD`); otherwise skip it and continue to Phase 9. Spawn Validate agent over what changed since the Phase 6 run:
514
+ Run this phase only if a qa-fix committed (`git rev-parse HEAD` differs from `VALIDATED_HEAD`); else skip to Phase 9. Spawn Validate agent:
447
515
 
448
516
  ```
449
517
  Agent(subagent_type="Validate"):
@@ -452,16 +520,30 @@ VALIDATION_SCOPE: changed-only
452
520
  Verify the qa-fix commits did not break anything."
453
521
  ```
454
522
 
523
+ At `lean`, open the prompt with Phase 6's `GATE_LEVEL` and `BASE_SHA` lines; its `Lint pack:` line, or `Lint pack: UNVERIFIED` if it prints none, replaces Phase 6's in VALIDATION_RESULT.
524
+
455
525
  **If FAIL:** Report the failures to user and halt.
456
526
 
527
+ **If BLOCKED:** as in Phase 6.
528
+
457
529
  **If PASS:** append a `gate:validate` claim (Phase 6's **Evidence claims**), then continue to Phase 9.
458
530
 
531
+ Any other or missing Status: report and halt; never PASS.
532
+
459
533
  ### Phase 9: Open PR
460
534
 
461
535
  **Produces:** PR_NUMBER
536
+ <!-- compliance:on -->
462
537
  **Requires:** BASE_BRANCH, BASE_REF, TASK_ID, ISSUE_NUMBER, ISSUE_PR_LINK, PR_EXCEPTIONS, PR_TEST_PLAN_BLOCK, PR_DESCRIPTION_GUIDANCE, APPLY_CONVENTIONS, CODE_AGENT_OUTPUT
538
+ <!-- compliance:off -->
539
+ **Requires:** BASE_BRANCH, BASE_REF, TASK_ID, ISSUE_NUMBER, ISSUE_PR_LINK, PR_DESCRIPTION_GUIDANCE, APPLY_CONVENTIONS
540
+ <!-- compliance:end -->
463
541
 
542
+ <!-- compliance:on -->
464
543
  Run once, after the gates, under every strategy. No Code agent opens a PR: the Git agent does, and it pastes `ISSUE_PR_LINK`, `PR_EXCEPTIONS` and `PR_TEST_PLAN_BLOCK` through their paste gates and scrubs the body (D11) before `gh pr create`. This command renders no link line and creates no PR itself: the Git agent's Phase-1 rendering is the only one, forwarded verbatim.
544
+ <!-- compliance:off -->
545
+ Run once, after the gates, under every strategy. No Code agent opens a PR: the Git agent does, and it pastes `ISSUE_PR_LINK` through its paste gate and scrubs the body (D11) before `gh pr create`. This command renders no link line and creates no PR itself: the Git agent's Phase-1 rendering is the only one, forwarded verbatim.
546
+ <!-- compliance:end -->
465
547
 
466
548
  ```
467
549
  Agent(subagent_type="Git"):
@@ -472,9 +554,13 @@ BASE_REF: {BASE_REF}
472
554
  TASK_ID: {task-id}
473
555
  ISSUE_NUMBER: {ISSUE_ID captured in Phase 1, or (none)}
474
556
  ISSUE_PR_LINK: {ISSUE_PR_LINK captured in Phase 1, or (none)}
557
+ <!-- compliance:on -->
475
558
  PR_EXCEPTIONS: {the ## Evidence Exceptions section of {worktree}/.devflow/docs/handoff-{branch_slug}.md verbatim, or (none)}
476
559
  PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
477
560
  PR_DESCRIPTION_GUIDANCE: {pr_description_guidance from Phase 1 unless it is (none), then the Code agents' reports from CODE_AGENT_OUTPUT in spawn order — Implementation, Commits and Key Decisions, and a sequential agent's ## Phase {N} Implementation Summary, then Validate's `Lint pack:` line if UNVERIFIED, for Testing}
561
+ <!-- compliance:off -->
562
+ PR_DESCRIPTION_GUIDANCE: {pr_description_guidance from Phase 1, or (none)}
563
+ <!-- compliance:end -->
478
564
  APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
479
565
  COMMIT_UNCOMMITTED: false
480
566
  Open the pull request for this branch and return the pre-flight summary."
@@ -498,23 +584,27 @@ git push origin HEAD; echo "exit=$?"
498
584
  `exit=0` continues to the gate. Any other result, a rejected non-fast-forward push included, records `TRACEABILITY: DEGRADED (ci push failed)` for the Phase 12 report, reports "CI status unknown — verify manually before merging" and proceeds to Phase 11 without waiting.
499
585
 
500
586
  <!-- PATTERN: ci-status-gate -->
501
- 1. Wait: run `cd {worktree} && HEAD_SHA=$(git rev-parse HEAD) && node "$HOME/.devflow/scripts/ci-wait.cjs" --pr {PR_NUMBER} --head "$HEAD_SHA"` through the Bash tool with `timeout: 600000`. Each run is one wait of at most 570 seconds and prints one line, `CI <STATUS> pr=… head=… failing=… pending=… waited=…` (INDETERMINATE adds `reason=…`). A missing or unparseable line, a status outside the six below, or a non-zero exit is INDETERMINATE.
587
+ 1. Wait: run `cd {worktree} && HEAD_SHA=$(git rev-parse HEAD) && node "$HOME/.devflow/scripts/ci-wait.cjs" --pr {PR_NUMBER} --head "$HEAD_SHA"` through the Bash tool with `timeout: 600000`. Each run waits at most 570 seconds and prints one line, `CI <STATUS> pr=… head=… failing=… pending=… waited=…` (INDETERMINATE adds `reason=…`). A missing or unparseable line, an unknown status or a non-zero exit is INDETERMINATE.
502
588
  2. **If PASSING** → proceed to Phase 11.
503
589
  3. **If NO_PR or NO_CI** → skip: "No PR/CI configured, skipping CI validation." Proceed to Phase 11.
504
- 4. **If PENDING** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI still running — verify manually before merging" and proceed.
505
- 5. **If INDETERMINATE** and fewer than 3 waits have run → wait again (step 1). After the third wait → report "CI status unknown — verify manually before merging" and proceed.
590
+ 4. **If PENDING** and fewer than 3 waits have run → wait again. Otherwise → report "CI still running — verify manually before merging" and proceed.
591
+ 5. **If INDETERMINATE** and fewer than 3 waits have run → wait again, unless `waited=570` with `reason=head-mismatch` or `no-workflow-check`. Otherwise → report "CI status unknown — verify manually before merging" and proceed.
506
592
  <!-- curation:on -->
507
593
  6. **If FAILING** and fewer than 2 fixes have run → report the failing checks from the line. Spawn `Agent(subagent_type="Fix")` whose prompt opens with `OPERATION: ci-fix`, with `COMPLIANCE_DIRECTIVE` (when it is not empty), `CI_FAILURES`, `DECISIONS_CONTEXT` and `PUSH: false`; `CI_FAILURES` holds the failing-check names from the line and nothing else, because the Fix agent fetches the full names and reads the logs itself and this command reads none. After a fix, push with the command above and, if a wait remains, wait again (step 1); a failed push records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and stops waiting. After the second fix still FAILING → report the failing checks and proceed.
508
594
  <!-- curation:off -->
509
595
  6. **If FAILING** and fewer than 2 fixes have run → report the failing checks from the line. Spawn `Agent(subagent_type="Fix")` whose prompt opens with `OPERATION: ci-fix`, with `COMPLIANCE_DIRECTIVE` (when it is not empty), `CI_FAILURES` and `PUSH: false`; `CI_FAILURES` holds the failing-check names from the line and nothing else, because the Fix agent fetches the full names and reads the logs itself and this command reads none. After a fix, push with the command above and, if a wait remains, wait again (step 1); a failed push records `TRACEABILITY: DEGRADED (ci push failed)`, reports "CI status unknown — verify manually before merging" and stops waiting. After the second fix still FAILING → report the failing checks and proceed.
510
596
  <!-- curation:end -->
511
- 7. **Budget**: at most 3 waits and 2 fixes in all. When one is spent, report the current status and proceed.
597
+ 7. **Budget**: at most 3 waits and 2 fixes in all. When one is spent, report the status and proceed.
512
598
  <!-- /PATTERN: ci-status-gate -->
513
599
 
514
600
  ### Phase 11: Evidence
515
601
 
516
602
  **Produces:** EVIDENCE_RESULT
603
+ <!-- compliance:on -->
517
604
  **Requires:** PR_NUMBER, EVIDENCE_FILE, REVIEW_PUBLICATION
605
+ <!-- compliance:off -->
606
+ **Requires:** PR_NUMBER, EVIDENCE_FILE
607
+ <!-- compliance:end -->
518
608
 
519
609
  Run once, after Phase 10, under every strategy. Skip it only when Phase 9 stopped the run. A `ci` TP reads `INDETERMINATE` only when the CI gate could not tell or did not run.
520
610
 
@@ -526,6 +616,7 @@ git push origin HEAD; echo "exit=$?"
526
616
 
527
617
  `exit=0` continues to the script. Any other result, a rejected non-fast-forward push included, does not block: record `TRACEABILITY: DEGRADED (evidence push failed)` for the Phase 12 report and run the script anyway.
528
618
 
619
+ <!-- compliance:on -->
529
620
  **Then refresh, inline.** The refresh is plumbing, so no Git agent runs it: `verify-evidence.cjs publish` is the whole `update-pr-evidence` operation — verify, the scrubbed block edit with its read-back, the scrubbed evidence comment — in one call. Use the Bash tool with `timeout: 180000`:
530
621
 
531
622
  ```bash
@@ -533,16 +624,33 @@ cd "{worktree}" && node "$HOME/.devflow/scripts/verify-evidence.cjs" publish --p
533
624
  ```
534
625
 
535
626
  Drop the `--evidence` pair when that file does not exist or its path does not match `^[A-Za-z0-9._/-]{1,255}$`. `{PR_NUMBER}` is digits only, and the publication value is `auto`, `full`, `off` or `stub`. Capture its stdout as `EVIDENCE_RESULT`: the `## PR Evidence` block — its `EVIDENCE` line and its `**Body**:` / `**Comment**:` line — and any `TRACEABILITY: DEGRADED ({reason})` lines after it (exit 0), or the one line `TRACEABILITY: DEGRADED (evidence unavailable)` (exit 2). Empty stdout or any other exit is `TRACEABILITY: DEGRADED (evidence unavailable)`. It never blocks: whatever it returns, continue to Phase 12.
627
+ <!-- compliance:off -->
628
+ **Then verify, inline.** The verify is plumbing, so no Git agent runs it: `verify-evidence.cjs verify` reads the PR and the local evidence file, and writes the local result file. It writes nothing to GitHub:
629
+
630
+ ```bash
631
+ cd "{worktree}" && node "$HOME/.devflow/scripts/verify-evidence.cjs" verify --pr {PR_NUMBER} --evidence ".devflow/docs/evidence-{branch_slug}.md" --comment-out ".devflow/docs/evidence-result-{branch_slug}.md"; echo "exit=$?"
632
+ ```
633
+
634
+ Drop the `--evidence` pair when that file does not exist or its path does not match `^[A-Za-z0-9._/-]{1,255}$`. `{PR_NUMBER}` is digits only. Capture its stdout as `EVIDENCE_RESULT`: its one `EVIDENCE` line (exit 0), or the one line `TRACEABILITY: DEGRADED (evidence unavailable)` (exit 2). Empty stdout or any other exit is `TRACEABILITY: DEGRADED (evidence unavailable)`. It never blocks: whatever it returns, continue to Phase 12.
635
+ <!-- compliance:end -->
536
636
 
537
637
  ### Phase 12: Report
538
638
 
539
639
  **Requires:** VALIDATION_RESULT, ALIGNMENT_RESULT, QA_RESULT, PR_NUMBER, EVIDENCE_RESULT, GATE_LEVEL
540
640
 
541
- Display completion summary with phase status, `Gate level: {GATE_LEVEL}` with any level note, Validate's `Lint pack:` line if any, PR info, and next steps.
641
+ Display completion summary with phase status, `Gate level: {GATE_LEVEL}` with any level note, Harden's `no files reviewed` line if any, Validate's `Lint pack:` line if any, PR info, and next steps.
542
642
 
643
+ <!-- compliance:on -->
543
644
  Show the test plan's evidence from Phase 11: `Test plan: {VERIFIED-CI + ATTESTED-LOCAL}/{total} verified (VERIFIED-CI {n}, ATTESTED-LOCAL {n})`, read from the `EVIDENCE` line and never inferred, then its `**Body**:` / `**Comment**:` line verbatim. Without an `EVIDENCE` line, show `Test plan: evidence unavailable`; with no test plan, `Test plan: missing`.
645
+ <!-- compliance:off -->
646
+ Show the test plan's evidence from Phase 11: `Test plan: {VERIFIED-CI + ATTESTED-LOCAL}/{total} verified (VERIFIED-CI {n}, ATTESTED-LOCAL {n})`, read from the `EVIDENCE` line and never inferred, then `Evidence result: .devflow/docs/evidence-result-{branch_slug}.md (local; not posted)`. Without an `EVIDENCE` line, show `Test plan: evidence unavailable`; with no test plan, `Test plan: missing`.
647
+ <!-- compliance:end -->
544
648
 
649
+ <!-- compliance:on -->
545
650
  If any Git agent output emitted `TRACEABILITY: DEGRADED ({reason})` lines during the run, or the fresh base step, Phase 10's push, Phase 11's push or Phase 11's script output carried one, surface them verbatim in the report under a `### Traceability` subsection so the user can act on them.
651
+ <!-- compliance:off -->
652
+ If any Git agent output emitted `TRACEABILITY: DEGRADED ({reason})` lines during the run, or the compliance-off line of Phase 1, the fresh base step, Phase 10's push, Phase 11's push or Phase 11's script output carried one, surface them verbatim in the report under a `### Traceability` subsection so the user can act on them.
653
+ <!-- compliance:end -->
546
654
 
547
655
  If Phase 9 listed uncommitted files, show them as a `### Uncommitted files` subsection: the user commits them or discards them.
548
656
 
@@ -563,9 +671,9 @@ If Phase 1 recorded an evidence exception, show its `## Evidence Exceptions` lin
563
671
  ├─ Phase 6: Validate (the one full-suite slot)
564
672
  ├─ Phase 7: QA Testing
565
673
  ├─ Phase 8: Re-Validate (only if a qa-fix committed)
566
- ├─ Phase 9: Open PR (every strategy, outside the strategy branches)
674
+ ├─ Phase 9: Open PR (every strategy)
567
675
  ├─ Phase 10: CI Status Gate (every strategy)
568
- ├─ Phase 11: Evidence (every strategy)
676
+ ├─ Phase 11: Evidence
569
677
  ├─ Phase 12: Report
570
678
  │
571
679
  └─ Feature Knowledge Write-Back (Conditional)
@@ -573,7 +681,11 @@ If Phase 1 recorded an evidence exception, show its `## Evidence Exceptions` lin
573
681
 
574
682
  ## Principles
575
683
 
684
+ <!-- compliance:on -->
576
685
  1. **Orchestration only** - Command spawns agents, never does work itself (no tests, builds or fixes); "Spawn X" means call the Agent tool; the inline calls are the bounded plumbing the charter allows: the fresh base step's resolver calls (Phase 1, re-validation), the Phase 10 and 11 pushes, the Phase 10 ci-wait call, the Phase 11 evidence publish call and the evidence script checks
686
+ <!-- compliance:off -->
687
+ 1. **Orchestration only** - Command spawns agents, never does work itself (no tests, builds or fixes); "Spawn X" means call the Agent tool; the inline calls are the bounded plumbing the charter allows: the fresh base step's resolver calls (Phase 1, re-validation), the Phase 10 and 11 pushes, the Phase 10 ci-wait call, the Phase 11 evidence verify call and the evidence script checks
688
+ <!-- compliance:end -->
577
689
  2. **Honest reporting** - Display agent outputs directly
578
690
  3. **Loop limits** - Max 2 validation retries, max 2 alignment fix iterations, max 2 QA retries before escalating to user; the CI gate allows at most 3 waits and 2 fixes
579
691
  4. **CI awareness** - CI status is checked before merge; test-plan evidence (Phase 11) is recorded under every strategy
@@ -456,7 +456,11 @@ Required sections:
456
456
  9. **Integration Points** — entry points, services, models to connect
457
457
  10. **Design Review Results** — anti-pattern findings with mitigations
458
458
  11. **Risk Assessment** — context risk level, unresolved risks
459
+ <!-- compliance:on -->
459
460
  12. **PR Description Guidance** — problem being solved, key changes, breaking changes, Reviewer Focus Areas
461
+ <!-- compliance:off -->
462
+ 12. **PR Description Guidance** — problem being solved, key changes, breaking changes
463
+ <!-- compliance:end -->
460
464
  13. **Test Plan** — the TP lines Gate 2 confirmed, under a `## Test Plan` heading: at least one per acceptance criterion, each citing the criterion it covers
461
465
 
462
466
  ### 12. PR Description Guidance
@@ -473,9 +477,11 @@ Required sections:
473
477
  ### Breaking Changes
474
478
  {from gap analysis, or "None expected"}
475
479
 
480
+ <!-- compliance:on -->
476
481
  ### Reviewer Focus Areas
477
482
  {areas needing careful review, with reasons}
478
483
 
484
+ <!-- compliance:end -->
479
485
  ### Related Issues
480
486
  Closes {ISSUE_REF}
481
487
  ```
@@ -493,6 +499,9 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" check tp <that file>; echo "ex
493
499
  **Write the artifact now** — frontmatter `issue: {ISSUE_ID}` if an issue is already known, else `issue: pending`.
494
500
 
495
501
  {{evidence_policy()}}
502
+ <!-- compliance:off -->
503
+ When `EVIDENCE_POLICY` is `required`, record `TRACEABILITY: DEGRADED (compliance off on this machine; the repository requires evidence)` once, for the report below.
504
+ <!-- compliance:end -->
496
505
 
497
506
  **Create or enrich tracker issue:**
498
507
 
@@ -508,12 +517,18 @@ Agent(subagent_type="Git"):
508
517
  ISSUE_INPUT: {the raw candidate token from COMMAND_INPUT if /plan was invoked with an issue reference, else omit}
509
518
  TASK_DESCRIPTION: {Gate 0 confirmed scope — one-line title}
510
519
  INITIAL_REQUEST: {the Gate 0 confirmed scope statement}
520
+ <!-- compliance:on -->
511
521
  REQUIREMENTS: {discovered requirements summary from Phase 6 gap synthesis}
512
522
  PLAN_ARTIFACT_PATH: {the design artifact path written above, relative to {worktree} — never absolute}
523
+ <!-- compliance:end -->
513
524
  WORKTREE_PATH: {worktree}
514
525
  LABELS: feature
526
+ <!-- compliance:on -->
515
527
  The Git agent will create a tracker issue (or enrich an existing one) using the D3 template,
516
528
  post the design artifact as a collapsed details comment, and link it from the Implementation Plan section.
529
+ <!-- compliance:off -->
530
+ The Git agent will create a tracker issue (or enrich an existing one) using the D3 template.
531
+ <!-- compliance:end -->
517
532
  Return the issue number."
518
533
  ```
519
534
 
@@ -527,7 +542,11 @@ Surface any `TRACEABILITY: DEGRADED ({reason})` lines from the Git agent output
527
542
 
528
543
  Display completion summary:
529
544
  - Design artifact path
545
+ <!-- compliance:on -->
530
546
  - Issue URL (if created or enriched) — and any `TRACEABILITY: DEGRADED ({reason})` lines from the Git agent
547
+ <!-- compliance:off -->
548
+ - Issue URL (if created or enriched) — the fixed line recorded above when it applies, and any `TRACEABILITY: DEGRADED ({reason})` lines from the Git agent
549
+ <!-- compliance:end -->
531
550
  - Gap analysis summary (N blocking, M should-address)
532
551
  - Design review summary (N anti-patterns found, M mitigated in plan)
533
552
  - Gate level: {GATE_LEVEL}, with any level note