devflow-kit 3.7.0 → 3.8.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 (184) hide show
  1. package/CHANGELOG.md +359 -1
  2. package/README.md +11 -11
  3. package/dist/agents/code.md +2 -4
  4. package/dist/agents/design.md +1 -1
  5. package/dist/agents/fix.md +6 -7
  6. package/dist/agents/git.md +1 -1
  7. package/dist/agents/harden.md +1 -1
  8. package/dist/agents/refactor.md +2 -4
  9. package/dist/agents/review.md +4 -4
  10. package/dist/agents/skim.md +2 -2
  11. package/dist/agents/triage.md +2 -2
  12. package/dist/cli/commands/capture.js +1 -1
  13. package/dist/cli/commands/curation-move-io.js +102 -0
  14. package/dist/cli/commands/curation-move-step.js +374 -0
  15. package/dist/cli/commands/{learning.js → curation.js} +302 -99
  16. package/dist/cli/commands/gate-level-prompts.js +426 -0
  17. package/dist/cli/commands/gates.js +34 -11
  18. package/dist/cli/commands/init-seed.js +11 -8
  19. package/dist/cli/commands/init.js +240 -54
  20. package/dist/cli/commands/memory.js +2 -2
  21. package/dist/cli/commands/prompt-io.js +37 -0
  22. package/dist/cli/commands/uninstall.js +81 -9
  23. package/dist/cli.js +2 -2
  24. package/dist/commands/bug-analysis.md +24 -35
  25. package/dist/commands/code-review.md +32 -36
  26. package/dist/commands/debug.md +4 -4
  27. package/dist/commands/dynamic-build.md +25 -24
  28. package/dist/commands/dynamic-plan.md +4 -4
  29. package/dist/commands/dynamic-profile.md +4 -4
  30. package/dist/commands/dynamic-tickets.md +4 -4
  31. package/dist/commands/explore.md +5 -5
  32. package/dist/commands/implement.md +52 -81
  33. package/dist/commands/plan.md +5 -5
  34. package/dist/commands/release.md +4 -4
  35. package/dist/commands/research.md +5 -5
  36. package/dist/commands/resolve.md +28 -30
  37. package/dist/commands/self-review.md +4 -12
  38. package/dist/core/assets.js +20 -20
  39. package/dist/core/curate-tuning-config.js +5 -6
  40. package/dist/core/curation-move-notice.js +84 -0
  41. package/dist/core/curation-move-skip.js +36 -0
  42. package/dist/core/curation-move.js +35 -0
  43. package/dist/core/curation-queue-cleanup.js +134 -0
  44. package/dist/core/curation-store.js +98 -0
  45. package/dist/core/{learning-variants.js → curation-variants.js} +65 -41
  46. package/dist/core/echo-value.js +11 -5
  47. package/dist/core/evidence-policy.js +1 -1
  48. package/dist/core/feature-switch.js +95 -19
  49. package/dist/core/fs-atomic.js +1 -1
  50. package/dist/core/gate-level.js +10 -2
  51. package/dist/core/git.js +16 -14
  52. package/dist/core/ledger-root.js +82 -22
  53. package/dist/core/linked-path.js +4 -4
  54. package/dist/core/manifest-lock.js +238 -0
  55. package/dist/core/manifest.js +58 -14
  56. package/dist/core/migrations.js +1 -13
  57. package/dist/core/observations.js +2 -2
  58. package/dist/core/plugins.js +15 -15
  59. package/dist/core/pool.js +26 -0
  60. package/dist/core/project-paths.js +103 -34
  61. package/dist/core/queue-drain.js +2 -2
  62. package/dist/core/tracked-areas.js +35 -0
  63. package/dist/core/tracker.js +1 -1
  64. package/dist/{learning-off → curation-off}/agents/code.md +2 -4
  65. package/dist/{learning-off → curation-off}/agents/fix.md +6 -7
  66. package/dist/{learning-off → curation-off}/agents/refactor.md +2 -4
  67. package/dist/{learning-off → curation-off}/agents/review.md +3 -3
  68. package/dist/{learning-off → curation-off}/agents/triage.md +1 -1
  69. package/dist/{learning-off → curation-off}/commands/bug-analysis.md +20 -31
  70. package/dist/{learning-off → curation-off}/commands/code-review.md +29 -33
  71. package/dist/{learning-off → curation-off}/commands/debug.md +1 -1
  72. package/dist/{learning-off → curation-off}/commands/dynamic-build.md +22 -21
  73. package/dist/{learning-off → curation-off}/commands/explore.md +1 -1
  74. package/dist/{learning-off → curation-off}/commands/implement.md +49 -78
  75. package/dist/{learning-off → curation-off}/commands/plan.md +1 -1
  76. package/dist/{learning-off → curation-off}/commands/resolve.md +25 -27
  77. package/dist/{learning-off → curation-off}/commands/self-review.md +1 -9
  78. package/dist/hud/components/{learning-counts.js → curation-counts.js} +36 -17
  79. package/dist/hud/config.js +1 -1
  80. package/dist/hud/index.js +6 -6
  81. package/dist/hud/render.js +3 -3
  82. package/dist/skills/git/references/pr/validate-branch.md +8 -5
  83. package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +13 -5
  84. package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +13 -5
  85. package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +13 -5
  86. package/dist/targets/claude-code/{learning-install.js → curation-install.js} +85 -65
  87. package/dist/targets/claude-code/installer.js +15 -15
  88. package/dist/targets/claude-code/language-stamp.js +5 -5
  89. package/dist/targets/claude-code/post-install.js +2 -2
  90. package/dist/targets/claude-code/tracker-servers.js +1 -1
  91. package/package.json +3 -2
  92. package/src/assets/agents/_partials/_code.mds +11 -11
  93. package/src/assets/agents/code.mds +2 -2
  94. package/src/assets/agents/curate.md +8 -8
  95. package/src/assets/agents/debug.mds +6 -6
  96. package/src/assets/agents/design.mds +18 -18
  97. package/src/assets/agents/fix.mds +6 -5
  98. package/src/assets/agents/git.mds +1 -1
  99. package/src/assets/agents/harden.mds +7 -7
  100. package/src/assets/agents/knowledge.mds +23 -23
  101. package/src/assets/agents/refactor.mds +2 -2
  102. package/src/assets/agents/research.mds +15 -15
  103. package/src/assets/agents/review.mds +43 -43
  104. package/src/assets/agents/skim.mds +11 -11
  105. package/src/assets/agents/triage.mds +22 -22
  106. package/src/assets/agents/validate.md +13 -26
  107. package/src/assets/commands/_partials/_decisions.mds +13 -13
  108. package/src/assets/commands/_partials/_engine.mds +8 -8
  109. package/src/assets/commands/_partials/_knowledge.mds +29 -15
  110. package/src/assets/commands/_partials/_preamble.mds +4 -4
  111. package/src/assets/commands/_partials/_settings.mds +2 -2
  112. package/src/assets/commands/_partials/_wave.mds +7 -7
  113. package/src/assets/commands/bug-analysis.mds +37 -48
  114. package/src/assets/commands/code-review.mds +46 -50
  115. package/src/assets/commands/debug.mds +14 -14
  116. package/src/assets/commands/dynamic-build.mds +38 -37
  117. package/src/assets/commands/dynamic-plan.mds +22 -22
  118. package/src/assets/commands/dynamic-profile.mds +2 -2
  119. package/src/assets/commands/dynamic-tickets.mds +8 -8
  120. package/src/assets/commands/explore.mds +20 -20
  121. package/src/assets/commands/implement.mds +77 -98
  122. package/src/assets/commands/plan.mds +27 -27
  123. package/src/assets/commands/release.mds +12 -12
  124. package/src/assets/commands/research.mds +19 -19
  125. package/src/assets/commands/resolve.mds +56 -50
  126. package/src/assets/commands/self-review.mds +20 -20
  127. package/src/assets/mds/git/_ops.mds +3 -1
  128. package/src/assets/mds/git/_ops_pr.mds +1 -1
  129. package/src/assets/mds/git/_ops_steps.mds +10 -4
  130. package/src/assets/mds/git/_pr.mds +7 -4
  131. package/src/assets/rules/quality.md +1 -0
  132. package/src/assets/scripts/hooks/background-memory-update +2 -2
  133. package/src/assets/scripts/hooks/capture-prompt +12 -12
  134. package/src/assets/scripts/hooks/capture-question +11 -11
  135. package/src/assets/scripts/hooks/capture-turn +12 -12
  136. package/src/assets/scripts/hooks/{learning-lock → curation-lock} +2 -2
  137. package/src/assets/scripts/hooks/curation-move +293 -0
  138. package/src/assets/scripts/hooks/ensure-devflow-init +45 -13
  139. package/src/assets/scripts/hooks/ensure-proxy +4 -4
  140. package/src/assets/scripts/hooks/ensure-root-gitignore +4 -4
  141. package/src/assets/scripts/hooks/git-marker +81 -0
  142. package/src/assets/scripts/hooks/json-helper.cjs +134 -51
  143. package/src/assets/scripts/hooks/json-parse +1 -1
  144. package/src/assets/scripts/hooks/lib/curation-move.cjs +1582 -0
  145. package/src/assets/scripts/hooks/lib/{learning-store.cjs → curation-store.cjs} +242 -118
  146. package/src/assets/scripts/hooks/lib/decisions-format.cjs +3 -3
  147. package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +24 -7
  148. package/src/assets/scripts/hooks/lib/project-paths.cjs +132 -39
  149. package/src/assets/scripts/hooks/lib/render-decisions.cjs +34 -22
  150. package/src/assets/scripts/hooks/lib/tracked-areas.cjs +259 -0
  151. package/src/assets/scripts/hooks/memory-worker +1 -1
  152. package/src/assets/scripts/hooks/pre-compact-memory +6 -16
  153. package/src/assets/scripts/hooks/queue-append +228 -103
  154. package/src/assets/scripts/hooks/resolve-project-root +2 -2
  155. package/src/assets/scripts/hooks/session-start-context +143 -69
  156. package/src/assets/scripts/hooks/session-start-memory +3 -43
  157. package/src/assets/scripts/lib/project-config.cjs +12 -5
  158. package/src/assets/scripts/resolve-base.cjs +1043 -0
  159. package/src/assets/scripts/resolve-settings.cjs +42 -18
  160. package/src/assets/skills/agent-references/SKILL.md +5 -2
  161. package/src/assets/skills/agent-references/references/commands/implement-levels.md +27 -0
  162. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +6 -4
  163. package/src/assets/skills/agent-references/references/commands/resolve-levels.md +24 -0
  164. package/src/assets/skills/apply-decisions/SKILL.md +1 -1
  165. package/src/assets/skills/docs-framework/SKILL.md +7 -7
  166. package/src/assets/skills/docs-framework/references/patterns.md +3 -4
  167. package/src/assets/skills/quality-gates/SKILL.md +1 -1
  168. package/src/assets/skills/worktree-support/references/roots.md +2 -2
  169. package/templates/lint-pack/.lint-pack.conf +86 -0
  170. package/templates/lint-pack/README.md +190 -0
  171. package/templates/lint-pack/lint-pack.sh +905 -0
  172. package/dist/core/learning-queue-cleanup.js +0 -27
  173. package/dist/core/learning-store.js +0 -61
  174. /package/dist/{learning-off → curation-off}/agents/debug.md +0 -0
  175. /package/dist/{learning-off → curation-off}/agents/design.md +0 -0
  176. /package/dist/{learning-off → curation-off}/agents/harden.md +0 -0
  177. /package/dist/{learning-off → curation-off}/agents/knowledge.md +0 -0
  178. /package/dist/{learning-off → curation-off}/agents/research.md +0 -0
  179. /package/dist/{learning-off → curation-off}/agents/skim.md +0 -0
  180. /package/dist/{learning-off → curation-off}/commands/dynamic-plan.md +0 -0
  181. /package/dist/{learning-off → curation-off}/commands/dynamic-profile.md +0 -0
  182. /package/dist/{learning-off → curation-off}/commands/dynamic-tickets.md +0 -0
  183. /package/dist/{learning-off → curation-off}/commands/release.md +0 -0
  184. /package/dist/{learning-off → curation-off}/commands/research.md +0 -0
@@ -3,7 +3,7 @@ description: Execute a single task through implementation, quality gates, and PR
3
3
  ---
4
4
  # Implement Command
5
5
 
6
- Orchestrate a single task through implementation by spawning specialized agents. The orchestrator only spawns agents and passes context - all work is done by agents.
6
+ Orchestrate a single task through implementation by spawning specialized agents.
7
7
 
8
8
  ## Usage
9
9
 
@@ -34,8 +34,6 @@ $ARGUMENTS
34
34
 
35
35
  Note: a bare digit run is a reference **only** under `github`, and that adjudication belongs to the Git agent, never to this command — the command layer holds no provider knowledge, so deciding it here would be a guess dressed as a rule.
36
36
 
37
- > **Tip**: For best results, run `/plan` first to produce a design artifact, then pass it to `/implement`.
38
-
39
37
  ## Phases
40
38
 
41
39
  ### Re-validation Continuation Path
@@ -44,9 +42,9 @@ When the user explicitly asks to re-validate, re-check, or re-run quality gates
44
42
 
45
43
  ### Phase 1: Setup
46
44
 
47
- **Produces:** TASK_ID, BASE_BRANCH, 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
45
+ **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
48
46
 
49
- Record the current branch name as `BASE_BRANCH`. Stop the run unless it matches `^[A-Za-z0-9._/+@,#-]{1,200}$`, telling the user it allows only ASCII letters, digits and `._/+@,#-`, at most 200.
47
+ 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.
50
48
 
51
49
  **Docs root (D-DOCS-ROOT).** Every `.devflow/docs/` path this command reads or writes lives at the checkout's toplevel, never under the directory the session started in. Resolve `{worktree}` from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — by running
52
50
 
@@ -79,7 +77,7 @@ If `PR_DESCRIPTION_GUIDANCE` was not set above (non-plan paths: issue input or t
79
77
 
80
78
  **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.
81
79
 
82
- Spawn Git agent to set up task environment. The Git agent derives the branch name automatically from the issue or task description:
80
+ Spawn Git agent to set up the task:
83
81
 
84
82
  ```
85
83
  Agent(subagent_type="Git"):
@@ -94,33 +92,14 @@ Derive branch name from issue or description, create feature branch, and fetch i
94
92
  Return the branch setup summary."
95
93
  ```
96
94
 
97
- The issue token is forwarded **unclassified**, and the routing is decided by
98
- SHAPE alone — how many tokens `COMMAND_INPUT` has, and whether it ends in `.md`.
99
-
100
- `setup-task` is the one step that has resolved a provider, and therefore the only
101
- one that knows what an issue reference looks like on this machine: `#123`,
102
- `PROJ-12` and `ENG-12` are three providers' spellings of the same thing. A
103
- `starts with #` test here would be a github test wearing a neutral name — it
104
- reclassifies every other provider's reference as a task description, so the
105
- branch is derived from prose and no issue is ever fetched, with nothing reporting
106
- a problem. Token COUNT is the gate that stays provider-neutral: every one of
107
- those spellings is a single token, and no free-text task description is.
95
+ 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.
108
96
 
109
- The two tests this command does make are its own under every provider:
110
-
111
- - **Extension.** A path ending in `.md` is a plan document, never an issue
112
- reference — it goes to `PLAN_ARTIFACT_PATH` and neither of the other two keys.
113
- `ISSUE_INPUT` then carries the plan's frontmatter `issue` instead, never the
114
- path (Plan Document Handling step 4).
115
- - **Token count.** A single token is an issue reference. Two or more is prose:
116
- forwarding only its FIRST token would send `/implement fix the login bug` to
117
- the Git agent as `ISSUE_INPUT: fix` with no description at all, and
118
- `setup-task` fetches whatever it is handed — so the command would derive a
119
- branch from a failed lookup and drop the request on the floor.
97
+ - **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).
98
+ - **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.
120
99
 
121
100
  **Capture from Git agent output** (used throughout flow):
122
101
  - `TASK_ID`: The branch name created by Git agent (use as TASK_ID for rest of flow)
123
- - `BASE_BRANCH`: Branch this feature was created from (for PR target)
102
+ - `BASE_BRANCH`: Branch this feature was created from (for PR target); stop unless it passes the setup check
124
103
  - `ISSUE_NUMBER`: the provider-canonical issue identifier for this task — the same value the Git agent emits as `ISSUE_ID` (if provided, or created by the Git agent's issue-first step in setup-task)
125
104
  - `branch_slug`: `TASK_ID` with every `/` replaced by `-`. It names `handoff-{branch_slug}.md` and `evidence-{branch_slug}.md` only when it matches `^[A-Za-z0-9._-]{1,200}$`; any other branch name stops the run here, telling the user it cannot name those files.
126
105
 
@@ -171,7 +150,7 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.dev
171
150
  node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
172
151
  ```
173
152
 
174
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off GATE_LEVEL=full` instead.
153
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
175
154
 
176
155
  The accepted line is the only source of these values.
177
156
 
@@ -243,12 +222,14 @@ A KB with no Rules section labels its entries `Rules ({section name}):` and give
243
222
 
244
223
  **One git call, then direct reads — no `.cjs` script.**
245
224
 
225
+ **Fresh base.** Before Phase 2, write `BASE_BRANCH` with the Write tool to the file that `F="$(mktemp)" && echo "F=$F"` prints, after one Read of it. If the Write tool fails, treat the value as missing; never write it with a shell command. Then run `F="{name file}"; trap 'rm -- "$F"' EXIT; cd "{worktree}" && node "$HOME/.devflow/scripts/resolve-base.cjs" local --name-stdin < "$F"; echo "exit=$?"`. Output other than one `BASE_REF=` line (40 or 64 hex, or `none`) with `exit=0` counts as `NOTE=stop`, `REASON=resolver-unavailable`. Record `BASE_REF`. By `NOTE`: `none` continues; `info` prints one plain line; `degraded` records `TRACEABILITY: DEGRADED (base {REASON}; fix: {fix})`; `stop` (`BASE_REF=none`) stops the run, naming REASON and its fix. Fix by REASON: no-merge-base `git fetch --unshallow`; no-ref or timeout `git fetch origin <base>` (`<base>` stays as written); resolver-unavailable `re-run; if it repeats, run devflow init`; invalid-name the allowed set, never the name; any other REASON none, and `; fix: {fix}` is left out.
226
+
246
227
  ### Phase 2: Implement
247
228
 
248
229
  **Produces:** CODE_AGENT_OUTPUT, FILES_CHANGED
249
230
  **Requires:** TASK_ID, BASE_BRANCH, EXECUTION_PLAN
250
231
 
251
- Based on Setup context (plan document, issue body, or conversation context), use the three-strategy framework:
232
+ Setup context is the plan document, issue body or conversation.
252
233
 
253
234
  **Strategy Selection**:
254
235
  - If plan document provided: use `execution-strategy` from frontmatter (if absent, use the table below)
@@ -262,7 +243,7 @@ Based on Setup context (plan document, issue body, or conversation context), use
262
243
 
263
244
  ---
264
245
 
265
- **SINGLE_CODE_AGENT** (default):
246
+ **SINGLE_CODE_AGENT**:
266
247
 
267
248
  ```
268
249
  Agent(subagent_type="Code"):
@@ -278,7 +259,7 @@ FEATURE_KNOWLEDGE: {feature_knowledge}
278
259
 
279
260
  ---
280
261
 
281
- **SEQUENTIAL_CODE_AGENTS** (>= 10 files or >= 7 steps):
262
+ **SEQUENTIAL_CODE_AGENTS**:
282
263
 
283
264
  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:
284
265
 
@@ -314,11 +295,11 @@ HANDOFF_REQUIRED: {true if not last phase}
314
295
  HANDOFF_FILE: {worktree}/.devflow/docs/handoff-{branch_slug}.md"
315
296
  ```
316
297
 
317
- **Handoff Protocol**: Each sequential Code agent receives the prior Code agent's implementation summary via PRIOR_PHASE_SUMMARY and FILES_FROM_PRIOR_PHASE. The Code agent's built-in branch orientation step handles git log scanning, file reading, and pattern discovery automatically. Each Code agent with HANDOFF_REQUIRED=true appends its own `## Phase {N} Implementation Summary` section, at most 8,192 bytes, to `{worktree}/.devflow/docs/handoff-{branch_slug}.md` (survives context compaction), never rewriting an earlier section and keeping any `## Evidence Exceptions` section byte-identical; the next Code agent reads only the section of the phase immediately before its own through HANDOFF_FILE. The orchestrator writes no phase section. Delete `{worktree}/.devflow/docs/handoff-{branch_slug}.md` once the PR exists — after Phase 9 (cleanup).
298
+ **Handoff Protocol**: Each Code agent with HANDOFF_REQUIRED=true appends its own `## Phase {N} Implementation Summary` section, at most 8,192 bytes, to `{worktree}/.devflow/docs/handoff-{branch_slug}.md`, never rewriting an earlier section and keeping any `## Evidence Exceptions` section byte-identical; the next Code agent reads only the section of the phase immediately before its own through HANDOFF_FILE. The orchestrator writes no phase section. Delete `{worktree}/.devflow/docs/handoff-{branch_slug}.md` once the PR exists — after Phase 9 (cleanup).
318
299
 
319
300
  ---
320
301
 
321
- **PARALLEL_CODE_AGENTS** (rare - truly independent artifacts):
302
+ **PARALLEL_CODE_AGENTS**:
322
303
 
323
304
  Spawn multiple Code agents **in a single message**, each with independent subtask:
324
305
 
@@ -344,18 +325,20 @@ FEATURE_KNOWLEDGE: {feature_knowledge}
344
325
  {COMPLIANCE_DIRECTIVE}"
345
326
  ```
346
327
 
347
- **Independence criteria** (all must be true for PARALLEL_CODE_AGENTS):
348
- - No shared contracts or interfaces
349
- - No integration points between subtasks
350
- - Different files/modules with no imports between them
351
- - Each subtask is self-contained
328
+ **Independence criteria** (all must be true for PARALLEL_CODE_AGENTS): no shared contracts, interfaces or integration points between subtasks; different files/modules with no imports between them.
352
329
 
353
330
  ### Phase 3: Polish
354
331
 
355
332
  **Produces:** POLISH_OUTPUT
356
- **Requires:** BASE_BRANCH
333
+ **Requires:** BASE_REF, GATE_LEVEL
357
334
 
358
- 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_BRANCH}...HEAD`, run again at each spawn.
335
+ **Gate level.** At `standard` or `lean`, once per run, run `d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; printf '%s\n' "$d"` in Bash and Read `<that directory>/skills/devflow:agent-references/references/commands/implement-levels.md` with the Read tool, and apply each row to the phase it names.
336
+
337
+ - No row or rule overrides the next two lines.
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`.
339
+ - Validate, the CI gate, the evidence claims and the compliance directive run at every level. An enabled compliance lens keeps Harden.
340
+
341
+ 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.
359
342
 
360
343
  ```
361
344
  Agent(subagent_type="Polish"):
@@ -369,9 +352,9 @@ Commit any improvements with a conventional-commit message."
369
352
  ### Phase 4: Self-Review
370
353
 
371
354
  **Produces:** HARDEN_OUTPUT
372
- **Requires:** BASE_BRANCH
355
+ **Requires:** BASE_REF
373
356
 
374
- After Polish agent completes, spawn Harden agent as the quality gate:
357
+ After Phase 3, spawn Harden agent as the quality gate:
375
358
 
376
359
  ```
377
360
  Agent(subagent_type="Harden"):
@@ -386,7 +369,7 @@ Harden agent reports `### Status: PASS | FIXED | BLOCKED`. **If BLOCKED:** repor
386
369
  ### Phase 5: Alignment Check
387
370
 
388
371
  **Produces:** ALIGNMENT_RESULT
389
- **Requires:** BASE_BRANCH, EXECUTION_PLAN
372
+ **Requires:** BASE_REF, EXECUTION_PLAN
390
373
 
391
374
  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:
392
375
 
@@ -422,13 +405,15 @@ Validate alignment with request and plan. Report ALIGNED or MISALIGNED with deta
422
405
  ### Phase 6: Validate
423
406
 
424
407
  **Produces:** VALIDATION_RESULT, VALIDATED_HEAD
425
- **Requires:** BASE_BRANCH
408
+ **Requires:** BASE_REF, GATE_LEVEL
426
409
 
427
410
  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:
428
411
 
429
412
  ```
430
413
  Agent(subagent_type="Validate"):
431
- "FILES_CHANGED: {branch_diff}
414
+ "GATE_LEVEL: {GATE_LEVEL}
415
+ BASE_SHA: {BASE_REF}
416
+ FILES_CHANGED: {branch_diff}
432
417
  VALIDATION_SCOPE: full
433
418
  Run build, typecheck, lint, test. Report pass/fail with failure details."
434
419
  ```
@@ -466,7 +451,7 @@ Run build, typecheck, lint, test. Report pass/fail with failure details."
466
451
  ### Phase 7: QA Testing
467
452
 
468
453
  **Produces:** QA_RESULT
469
- **Requires:** BASE_BRANCH, EXECUTION_PLAN, TEST_PLAN, VALIDATED_HEAD
454
+ **Requires:** BASE_REF, EXECUTION_PLAN, TEST_PLAN, VALIDATED_HEAD
470
455
 
471
456
  After Phase 6 passes, spawn Test agent for scenario-based acceptance testing:
472
457
 
@@ -522,21 +507,22 @@ Verify the qa-fix commits did not break anything."
522
507
  ### Phase 9: Open PR
523
508
 
524
509
  **Produces:** PR_NUMBER
525
- **Requires:** BASE_BRANCH, TASK_ID, ISSUE_NUMBER, ISSUE_PR_LINK, PR_EXCEPTIONS, PR_TEST_PLAN_BLOCK, PR_DESCRIPTION_GUIDANCE, APPLY_CONVENTIONS, CODE_AGENT_OUTPUT
510
+ **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
526
511
 
527
- Run once, after the gates, under every strategy. This phase sits outside the strategy branches, so no run reaches the end with commits and no PR. 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.
512
+ 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.
528
513
 
529
514
  ```
530
515
  Agent(subagent_type="Git"):
531
516
  "OPERATION: ensure-pr-ready
532
517
  WORKTREE_PATH: {worktree}
533
518
  BASE_BRANCH: {base branch}
519
+ BASE_REF: {BASE_REF}
534
520
  TASK_ID: {task-id}
535
521
  ISSUE_NUMBER: {ISSUE_ID captured in Phase 1, or (none)}
536
522
  ISSUE_PR_LINK: {ISSUE_PR_LINK captured in Phase 1, or (none)}
537
523
  PR_EXCEPTIONS: {the ## Evidence Exceptions section of {worktree}/.devflow/docs/handoff-{branch_slug}.md verbatim, or (none)}
538
524
  PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
539
- 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}
525
+ 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}
540
526
  APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
541
527
  COMMIT_UNCOMMITTED: false
542
528
  Open the pull request for this branch and return the pre-flight summary."
@@ -574,7 +560,7 @@ git push origin HEAD; echo "exit=$?"
574
560
  **Produces:** EVIDENCE_RESULT
575
561
  **Requires:** PR_NUMBER, EVIDENCE_FILE, REVIEW_PUBLICATION
576
562
 
577
- Run once, after Phase 10, under every strategy: the PR exists by now, opened in Phase 9. The re-validation path has no CI gate and runs this phase straight after Phase 9. 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.
563
+ 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.
578
564
 
579
565
  **Push first.** Every claim is keyed to the HEAD an agent reported, and a Harden or Fix agent may have committed without pushing; a claim whose SHA is not in the PR reads `UNVERIFIED`. So push the branch once before the script — never force, and no retry:
580
566
 
@@ -594,13 +580,13 @@ Drop the `--evidence` pair when that file does not exist or its path does not ma
594
580
 
595
581
  ### Phase 12: Report
596
582
 
597
- **Requires:** VALIDATION_RESULT, ALIGNMENT_RESULT, QA_RESULT, PR_NUMBER, EVIDENCE_RESULT
583
+ **Requires:** VALIDATION_RESULT, ALIGNMENT_RESULT, QA_RESULT, PR_NUMBER, EVIDENCE_RESULT, GATE_LEVEL
598
584
 
599
- Display completion summary with phase status, PR info, and next steps.
585
+ 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.
600
586
 
601
587
  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`.
602
588
 
603
- If any Git agent output emitted `TRACEABILITY: DEGRADED ({reason})` lines during the run, or 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.
589
+ 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.
604
590
 
605
591
  If Phase 9 listed uncommitted files, show them as a `### Uncommitted files` subsection: the user commits them or discards them.
606
592
 
@@ -608,14 +594,6 @@ If Phase 1 recorded an evidence exception, show its `## Evidence Exceptions` lin
608
594
 
609
595
  ### Feature Knowledge Write-Back (Conditional)
610
596
 
611
- Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
612
-
613
- ```bash
614
- git -C "{start}" rev-parse --show-toplevel
615
- ```
616
-
617
- and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
618
-
619
597
  **Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:** take the settings line resolved above for that root, resolving it with the settings block when this run has not yet.
620
598
 
621
599
  If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine switch (`devflow knowledge --disable`), the repository and the personal settings can each turn knowledge off, and none can turn it back on (D-FEATURES-NARROW-ONLY). The fail-closed line says `KNOWLEDGE=off` too, so an unresolvable line skips write-back.
@@ -659,13 +637,10 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
659
637
  ## Architecture
660
638
 
661
639
  ```
662
- /implement (orchestrator - spawns agents only)
663
- │
664
- ├─ Re-validation Path (when user says "re-validate"/"re-check"/"re-run gates")
665
- │ └─ Branch safety → skip Phase 2 → record BASE_BRANCH → Phases 3-8 → Phase 9, 11, 12
640
+ /implement
666
641
  │
667
642
  ├─ Phase 1: Setup
668
- ├─ Phase 2: Implement (3-strategy framework)
643
+ ├─ Phase 2: Implement
669
644
  ├─ Phase 3: Polish
670
645
  ├─ Phase 4: Self-Review
671
646
  ├─ Phase 5: Alignment Check
@@ -674,7 +649,7 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
674
649
  ├─ Phase 8: Re-Validate (only if a qa-fix committed)
675
650
  ├─ Phase 9: Open PR (every strategy, outside the strategy branches)
676
651
  ├─ Phase 10: CI Status Gate (every strategy)
677
- ├─ Phase 11: Evidence (every strategy, once the PR exists)
652
+ ├─ Phase 11: Evidence (every strategy)
678
653
  ├─ Phase 12: Report
679
654
  │
680
655
  └─ Feature Knowledge Write-Back (Conditional)
@@ -682,15 +657,11 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
682
657
 
683
658
  ## Principles
684
659
 
685
- 1. **Orchestration only** - Command spawns agents, never does work itself; the inline calls are the bounded plumbing the charter allows: the Phase 10 and Phase 11 pushes, the Phase 10 ci-wait call, the Phase 11 evidence publish call and the evidence script checks
686
- 2. **Agent ownership** - Each agent owns its output completely
687
- 3. **Honest reporting** - Display agent outputs directly
688
- 4. **Strict delegation** - Never perform agent work in main session. "Spawn X" means call Agent tool with X, not do X's work yourself
689
- 5. **Validate agent owns validation** - Never run `npm test`, `npm run build`, or similar in main session; always delegate to Validate agent
690
- 6. **Fix agent owns fixes** - Never implement fixes in main session; spawn Fix agent for validation failures and alignment fixes
691
- 7. **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
692
- 8. **CI awareness** - CI status is checked before merge under every strategy, once Phase 9 has opened the PR; test-plan evidence (Phase 11) is recorded under every strategy once the PR exists
660
+ 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
661
+ 2. **Honest reporting** - Display agent outputs directly
662
+ 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
663
+ 4. **CI awareness** - CI status is checked before merge; test-plan evidence (Phase 11) is recorded under every strategy
693
664
 
694
665
  ## Error Handling
695
666
 
696
- If any agent fails, report the phase, agent type, and error. Offer options: retry phase, investigate systematically, or escalate to user.
667
+ If any agent fails, report the phase, agent type and error. Offer: retry the phase, investigate, or escalate to user.
@@ -114,7 +114,7 @@ If the user says "skip" or "just proceed" — skip remaining questions, present
114
114
  node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
115
115
  ```
116
116
 
117
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off GATE_LEVEL=full` instead.
117
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
118
118
 
119
119
  The accepted line is the only source of these values.
120
120
 
@@ -86,7 +86,7 @@ Set `TARGET_DIR` to the selected review or bug-analysis directory path, and `TAR
86
86
 
87
87
  #### Step 0d: Load Project Context
88
88
 
89
- **Produces:** FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, REVIEW_PUBLICATION, RESOLUTION_TS
89
+ **Produces:** FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, REVIEW_PUBLICATION, RESOLUTION_TS, GATE_LEVEL
90
90
 
91
91
  **Resolve the settings line** once per worktree root, reusing a line this run already resolved for the same root. `{root}` is the worktree the values are for — the repository root when the run has one worktree:
92
92
 
@@ -94,7 +94,7 @@ Set `TARGET_DIR` to the selected review or bug-analysis directory path, and `TAR
94
94
  node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
95
95
  ```
96
96
 
97
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off GATE_LEVEL=full` instead.
97
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
98
98
 
99
99
  The accepted line is the only source of these values.
100
100
 
@@ -179,6 +179,12 @@ Resolve this per worktree — unlike the evidence policy above, the settings lin
179
179
 
180
180
  Set it per worktree, from that worktree's lens, and pass that worktree's `COMPLIANCE_DIRECTIVE` to each of its Code and Fix spawns, on a line of its own.
181
181
 
182
+ **Gate level.** Each worktree keeps its own `GATE_LEVEL`. When any is `standard` or `lean`, once per run, run `d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; printf '%s\n' "$d"` in Bash and Read `<that directory>/skills/devflow:agent-references/references/commands/resolve-levels.md` with the Read tool, and apply each row to the phase it names, as the reference says.
183
+
184
+ - No row or rule overrides the next two lines.
185
+ - 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 in any worktree, keep every `GATE_LEVEL` and say `level reference unreadable: no level rows applied`.
186
+ - No level changes the Triage security gate or the ESCALATED route. The Verification Gate, the CI gate and the compliance directive run at every level.
187
+
182
188
  **Mint `RESOLUTION_TS` once per run:** `date -u +%Y-%m-%dT%H:%M:%SZ`. Every worktree reuses it — the resolution comment's dedup marker is searched per PR, so one run key keeps a retry of this run deduplicated while the next /resolve on the same PR posts. Phase 5 writes it as the summary's `**Date**:` and Phase 9b-2 passes it, so the local file and the posted marker agree.
183
189
 
184
190
  ### Phase 1: Parse Issues
@@ -268,10 +274,10 @@ Wait for Triage agent to complete before proceeding. Parse verdict ledger from T
268
274
  **Produces:** BATCHES
269
275
  **Requires:** TRIAGE_RESULTS
270
276
 
271
- If FIX_NOW list is empty: skip to Phase 5 — write full summary (Phase 5), run manage-debt (Phase 9) if FIX_SEPARATE/TECH_DEBT exist, run thread resolution + resolution comment (Phase 9b), run merge readiness (Phase 9c), display results (Phase 10).
277
+ If FIX_NOW list is empty: skip to Phase 5, then run Phases 9, 9b, 9c and 10.
272
278
 
273
279
  Otherwise, batch FIX_NOW issues for Code agent execution. **DUPLICATE issues are never dispatched** — they inherit the primary's outcome:
274
- - **Same-file issues** → one batch (one Code agent per file, sequential for same-file pairs)
280
+ - **Same-file issues** → one batch (one Code agent per file)
275
281
  - **Distinct-file issues** → parallel Code agents
276
282
  - **Max 5 issues per batch** — chunk large sets
277
283
 
@@ -306,9 +312,9 @@ Collect from each Code agent:
306
312
  ### Phase 5: Write resolution-summary.md
307
313
 
308
314
  **Produces:** RESOLUTION_FILE (early write for compaction safety)
309
- **Requires:** TRIAGE_RESULTS, CODE_AGENT_RESULTS, TARGET_DIR, TARGET_DIR_REL, BRANCH_INFO, RESOLUTION_TS
315
+ **Requires:** TRIAGE_RESULTS, CODE_AGENT_RESULTS, TARGET_DIR, TARGET_DIR_REL, BRANCH_INFO, RESOLUTION_TS, GATE_LEVEL
310
316
 
311
- **Immediately write `resolution-summary.md`** to `{TARGET_DIR}` using the Write tool. Do this now — not in Phase 9 — while results are fresh in context. This ensures the record is persisted even if later phases (Polish, Verification Gate, CI gate, Tech Debt) trigger context compaction.
317
+ **Immediately write `resolution-summary.md`** to `{TARGET_DIR}` using the Write tool. Do this now — not in Phase 9 — while results are fresh in context.
312
318
 
313
319
  Set `Tracked` for FIX_SEPARATE and TECH_DEBT items to `(pending)` — to be backfilled after Phase 9 manage-debt (or `TRACEABILITY: DEGRADED ({reason})` if manage-debt degrades).
314
320
 
@@ -319,7 +325,7 @@ Use the template from the Output Artifact section below.
319
325
  ### Phase 6: Polish
320
326
 
321
327
  **Produces:** POLISH_RESULT
322
- **Requires:** CODE_AGENT_RESULTS
328
+ **Requires:** CODE_AGENT_RESULTS, GATE_LEVEL
323
329
 
324
330
  If any fixes were made, spawn Polish agent to refine the changed code:
325
331
 
@@ -380,7 +386,7 @@ git -C {worktree} push
380
386
 
381
387
  **If `fork_no_push` is set:** do not push. Record `Push: skipped — cannot push to fork` under `## Verification`, and skip Phase 8 — no pushed commit exists for CI to check.
382
388
 
383
- **Route after push:** VERIFICATION_STATUS = PASS → continue to Phase 8 (CI gate). VERIFICATION_STATUS = FAILED → skip Phase 8; proceed directly to Phase 9 (manage-debt), then Phase 9b (thread resolution + resolution comment), then Phase 9c (merge readiness), then Phase 10 (report). VERIFICATION_STATUS = SKIPPED → skip Phase 8 (no fixes applied); proceed to Phase 9 (manage-debt), then Phase 9b (thread resolution + resolution comment), then Phase 9c (merge readiness, when non-author approval is required), then Phase 10 (report).
389
+ **Route after push:** VERIFICATION_STATUS = PASS → continue to Phase 8 (CI gate). FAILED or SKIPPED → skip Phase 8 and continue with Phase 9 and the later phases in order.
384
390
 
385
391
  ### Phase 8: CI Status Gate (Conditional)
386
392
 
@@ -550,7 +556,7 @@ If the script prints a `TRACEABILITY: DEGRADED` line: warn, proceed to Phase 10.
550
556
 
551
557
  ### Phase 10: Report
552
558
 
553
- **Requires:** BRANCH_INFO, TARGET_DIR, PR_COMMENT, THREAD_RESOLUTION_RESULT
559
+ **Requires:** BRANCH_INFO, TARGET_DIR, PR_COMMENT, THREAD_RESOLUTION_RESULT, GATE_LEVEL
554
560
 
555
561
  The resolution summary was already written to `{TARGET_DIR}/resolution-summary.md` in Phase 5 (updated by Phase 7, Phase 9 and Phase 9b-1). Display results to the user:
556
562
 
@@ -560,6 +566,7 @@ The resolution summary was already written to `{TARGET_DIR}/resolution-summary.m
560
566
  **Branch**: {branch}
561
567
  **Reviews Processed**: {n} reports from {TARGET_DIR}
562
568
  **Total Issues**: {n}
569
+ **Gate level**: {GATE_LEVEL, with any level note}
563
570
 
564
571
  ### Results
565
572
  | Outcome | Count |
@@ -605,14 +612,6 @@ In multi-worktree mode, report results per worktree with aggregate summary.
605
612
 
606
613
  ### Feature Knowledge Write-Back (Conditional)
607
614
 
608
- Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
609
-
610
- ```bash
611
- git -C "{start}" rev-parse --show-toplevel
612
- ```
613
-
614
- and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
615
-
616
615
  **Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:** take the settings line resolved above for that root, resolving it with the settings block when this run has not yet.
617
616
 
618
617
  If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine switch (`devflow knowledge --disable`), the repository and the personal settings can each turn knowledge off, and none can turn it back on (D-FEATURES-NARROW-ONLY). The fail-closed line says `KNOWLEDGE=off` too, so an unresolvable line skips write-back.
@@ -659,15 +658,15 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
659
658
  /resolve (orchestrator - spawns agents only)
660
659
  │
661
660
  ├─ Phase 0: Worktree Discovery & Pre-flight
662
- ├─ Phase 1: Parse issues from TARGET_DIR + extract confidence %
661
+ ├─ Phase 1: Parse issues from TARGET_DIR
663
662
  ├─ Phase 1b: Fetch external threads (evidence policy required)
664
663
  ├─ Phase 2: Global Triage [Triage agent, opus, single agent]
665
- ├─ Phase 3: Batch FIX_NOW issues (skip if empty; DUPLICATE issues never dispatched)
666
- ├─ Phase 4: Fix [Code agent × N, OPERATION: issue-fix, PUSH: false]
664
+ ├─ Phase 3: Batch FIX_NOW issues
665
+ ├─ Phase 4: Fix [Code agent × N]
667
666
  ├─ Phase 5: Write resolution-summary.md (compaction safety; Tracked = "(pending)" or "(pending — TRACEABILITY: DEGRADED)" if manage-debt degrades)
668
- ├─ Phase 6: Polish [Polish agent]
667
+ ├─ Phase 6: Polish
669
668
  ├─ Phase 7: Verification Gate [Validate agent, haiku] + push + Fix agent validation-fix loop ≤2
670
- ├─ Phase 8: CI Status Gate (conditional — skipped if no fixes or verification FAILED)
669
+ ├─ Phase 8: CI Status Gate (conditional)
671
670
  ├─ Phase 9: Git agent (manage-debt) — FIX_SEPARATE + TECH_DEBT → backfill Tracked={ISSUE_REF} (or TRACEABILITY: DEGRADED on failure)
672
671
  │
673
672
  ├─ Phase 9b: Thread resolution + resolution comment
@@ -686,10 +685,9 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
686
685
  | Case | Handling |
687
686
  |------|----------|
688
687
  | No reviews exist | Check bug-analysis fallback (Step 0c-5b); if also absent, error and suggest `/code-review` or `/bug-analysis` |
689
- | All false positives | Normal completion, report shows 0 fixes |
690
688
  | Fix attempt fails | Revert changes, mark BLOCKED, continue others |
691
689
  | Issue dependencies | Sequential chain, skip dependents if predecessor blocked |
692
- | No actionable issues | Report "No issues to resolve" |
690
+ | No issues parsed | Report "No issues to resolve" |
693
691
  | Latest review already resolved | Check bug-analysis fallback (Step 0c-5b); if also absent, skip worktree and suggest `/code-review` or `/bug-analysis` |
694
692
  | `--review {timestamp}` in multi-worktree mode | Not supported — use `--path` + `--review` to target specific worktree + review |
695
693
  | gh/GitHub absent | manage-debt degrades (`TRACEABILITY: DEGRADED ({reason})`); Tracked stays `(pending — TRACEABILITY: DEGRADED ({reason}))` — recorded, not dropped |
@@ -704,9 +702,8 @@ When the Knowledge agent reports `KB_COMMIT: skipped (detached HEAD)`, the files
704
702
  ## Principles
705
703
 
706
704
  1. **Orchestration only** - Command spawns agents, doesn't do git/resolve work itself
707
- 2. **No agent grades its own homework** - Triage agent validates, Code agents fix, Validate agent verifies
708
- 3. **Git agent for git work** - All git operations go through Git agent; the CI wait, the evidence refresh and the merge-readiness check are inline scripts (plumbing, no model work)
709
- 4. **Traceability-aware** - Policy-gated ops (thread fetch/resolve, merge readiness) are skipped cleanly when the evidence policy does not ask for them; resolution comment (Phase 9b-2) is always-on; test-plan evidence is re-verified (≤1 Test agent) and refreshed only when this run moved the head (Steps 9b-0, 9b-3)
705
+ 2. **Git agent for git work** - All git operations go through Git agent; the CI wait, the evidence refresh and the merge-readiness check are inline scripts (plumbing, no model work)
706
+ 3. **Traceability-aware** - Policy-gated ops (thread fetch/resolve, merge readiness) are skipped cleanly when the evidence policy does not ask for them; resolution comment (Phase 9b-2) is always-on; test-plan evidence is re-verified (≤1 Test agent) and refreshed only when this run moved the head (Steps 9b-0, 9b-3)
710
707
 
711
708
  ## Output Artifact
712
709
 
@@ -719,6 +716,7 @@ Written in Phase 5 (Collect Results) to `{TARGET_DIR}/resolution-summary.md`:
719
716
  **Date**: {RESOLUTION_TS}
720
717
  **Review**: {TARGET_DIR_REL}
721
718
  **Command**: /resolve
719
+ **Gate level**: {GATE_LEVEL}
722
720
 
723
721
  ## Statistics
724
722
  | Metric | Value |
@@ -30,7 +30,7 @@ Detect changed files and build context:
30
30
  node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
31
31
  ```
32
32
 
33
- Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> LEARNING=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on LEARNING=on KNOWLEDGE=off GATE_LEVEL=full` instead.
33
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `TRACKER=<github|jira|linear> TRACKER_SOURCE=<project|personal|machine|default> TRACKER_WARN=<none|mismatch|invalid> SITE=<none|https://<host>> KEY=<none|<key>> REVIEW_PUBLICATION=<off|auto|full> COMPLIANCE=<off|generic|<id>[,<id>…]> MEMORY=<on|off> CURATION=<on|off> KNOWLEDGE=<on|off> GATE_LEVEL=<full|standard|lean>` — these fields, in this order, nothing else, where `<host>` is a lowercase dotted host name alone, `<key>` is 2–10 of `A-Z`, `0-9` and `_` starting with a letter, and each `<id>` is one of `gdpr`, `hipaa`, `pci-dss`, `soc2`, `iso-27001`, `sox`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `TRACKER=github TRACKER_SOURCE=default TRACKER_WARN=invalid SITE=none KEY=none REVIEW_PUBLICATION=off COMPLIANCE=generic MEMORY=on CURATION=on KNOWLEDGE=off GATE_LEVEL=full` instead.
34
34
 
35
35
  The accepted line is the only source of these values.
36
36
 
@@ -175,14 +175,6 @@ Display summary:
175
175
 
176
176
  ### Feature Knowledge Write-Back (Conditional)
177
177
 
178
- Resolve `{worktree}` as the checkout's toplevel, because feature knowledge bases are committed with the branch (D-PROMPT-ROOT): from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`) — run
179
-
180
- ```bash
181
- git -C "{start}" rev-parse --show-toplevel
182
- ```
183
-
184
- and use its one-line output. If the command fails (outside a git repository), `{worktree}` is the start directory itself. All paths below are relative to `{worktree}`.
185
-
186
178
  **Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:** take the settings line resolved above for that root, resolving it with the settings block when this run has not yet.
187
179
 
188
180
  If the settings line says `KNOWLEDGE=off`, skip write-back entirely. The machine switch (`devflow knowledge --disable`), the repository and the personal settings can each turn knowledge off, and none can turn it back on (D-FEATURES-NARROW-ONLY). The fail-closed line says `KNOWLEDGE=off` too, so an unresolvable line skips write-back.
@@ -1,10 +1,11 @@
1
1
  import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
2
3
  import { dim } from '../colors.js';
3
4
  import { getDecisionsLedgerPath } from '../../core/project-paths.js';
4
- import { getLedgerRoot } from '../../core/ledger-root.js';
5
+ import { formatMoveNotice, gatherMoveNotice } from '../../core/curation-move-notice.js';
6
+ import { isMoveSkipReason } from '../../core/curation-move-skip.js';
7
+ import { getLedgerRoot, LEDGER_ROOT_TIMEOUT_MS } from '../../core/ledger-root.js';
5
8
  import { isActiveDecisionsStatus } from '../../core/observations.js';
6
- /** The HUD's per-git-command budget (src/hud/git.ts GIT_TIMEOUT). */
7
- const LEDGER_ROOT_TIMEOUT_MS = 1000;
8
9
  /**
9
10
  * The largest ledger the statusline reads: 8 MiB, far above the roughly 0.5 MB
10
11
  * real ledgers reach.
@@ -65,12 +66,12 @@ function isLedgerCountRow(val) {
65
66
  return o.decisions_status === undefined || typeof o.decisions_status === 'string';
66
67
  }
67
68
  /**
68
- * Read .devflow/learning/decisions-ledger.jsonl and count active anchored
69
+ * Read .devflow/curation/decisions-ledger.jsonl and count active anchored
69
70
  * rows by type. Returns null if the ledger is missing, is refused by
70
71
  * D-HUD-LEDGER-BOUNDED, or holds no valid rows (graceful fallback). Exported for
71
72
  * use by the main HUD entry point.
72
73
  */
73
- export function gatherLearningCounts(cwd) {
74
+ export function gatherCurationCounts(cwd) {
74
75
  const content = readBoundedLedger(getDecisionsLedgerPath(cwd));
75
76
  if (content === null)
76
77
  return null;
@@ -105,34 +106,52 @@ export function gatherLearningCounts(cwd) {
105
106
  * root (getLedgerRoot — the main checkout in a linked worktree, the repository
106
107
  * root from a subdirectory), or `cwd` itself outside a git work tree. One git
107
108
  * call, bounded by the HUD's per-command budget; run it alongside the git
108
- * status gather, not after it (D-LEDGER-MAIN-WORKTREE).
109
+ * status gather, not after it (D-LEDGER-MAIN-WORKTREE). Where the old ledger folder
110
+ * still stands it adds the move notice (gatherMoveNotice): any notice when both counts
111
+ * are zero, a skip notice only when a count is above zero.
109
112
  */
110
- export async function gatherLedgerLearningCounts(cwd, options = {}) {
113
+ export async function gatherLedgerCurationCounts(cwd, options = {}) {
111
114
  const root = await getLedgerRoot(cwd, { ...options, timeoutMs: LEDGER_ROOT_TIMEOUT_MS });
112
- return gatherLearningCounts(root ?? cwd);
115
+ const ledgerRoot = root ?? cwd;
116
+ const counts = gatherCurationCounts(ledgerRoot);
117
+ const move = gatherMoveNotice(ledgerRoot, options.home ?? os.homedir());
118
+ if (counts !== null && counts.decisions + counts.pitfalls > 0) {
119
+ return isMoveSkipReason(move) ? { ...counts, move } : counts;
120
+ }
121
+ if (move === null)
122
+ return counts;
123
+ return { decisions: counts?.decisions ?? 0, pitfalls: counts?.pitfalls ?? 0, move };
113
124
  }
114
125
  /**
115
126
  * HUD component: decisions/pitfalls counts.
116
- * Shows how many active ADR/PF entries the project has accumulated.
117
- * Returns null when no ledger exists or every entry is retired.
127
+ * Shows how many active ADR/PF entries the project has accumulated. When there are
128
+ * none and the ledger folder still has its old name, it shows the pointer, the refused
129
+ * line or the skip line instead. When the move was skipped (git tracks files in a data
130
+ * folder, or git did not answer), the skip line also follows the counts. Returns null
131
+ * when no ledger exists or every entry is retired.
118
132
  */
119
- export default async function learningCounts(ctx) {
120
- const data = ctx.learningCounts;
133
+ export default async function curationCounts(ctx) {
134
+ const data = ctx.curationCounts;
121
135
  if (!data)
122
136
  return null;
123
137
  const { decisions, pitfalls } = data;
124
- if (decisions + pitfalls === 0)
125
- return null;
138
+ if (decisions + pitfalls === 0) {
139
+ if (data.move === undefined)
140
+ return null;
141
+ const notice = formatMoveNotice(data.move);
142
+ return { text: dim(notice), raw: notice };
143
+ }
126
144
  const parts = [];
127
145
  if (decisions > 0)
128
146
  parts.push(`${decisions} decision${decisions !== 1 ? 's' : ''}`);
129
147
  if (pitfalls > 0)
130
148
  parts.push(`${pitfalls} pitfall${pitfalls !== 1 ? 's' : ''}`);
131
149
  // Intentionally one dimmed clause (unlike config-counts, which dims each
132
- // part and joins with a middot for a list of independent facts): "Learning:
150
+ // part and joins with a middot for a list of independent facts): "Curation:
133
151
  // N decisions, M pitfalls" reads as a single sentence, so the whole string
134
152
  // is dimmed once and parts are comma-joined rather than middot-separated.
135
- const raw = `Learning: ${parts.join(', ')}`;
153
+ const counts = parts.join(', ');
154
+ const raw = isMoveSkipReason(data.move) ? formatMoveNotice(data.move, counts) : `Curation: ${counts}`;
136
155
  return { text: dim(raw), raw };
137
156
  }
138
- //# sourceMappingURL=learning-counts.js.map
157
+ //# sourceMappingURL=curation-counts.js.map