devflow-kit 3.2.0 → 3.4.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 (188) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/agents/code.md +330 -0
  4. package/{src/assets → dist}/agents/design.md +11 -1
  5. package/{src/assets → dist}/agents/diagnose.md +17 -13
  6. package/dist/agents/git.md +29 -56
  7. package/{src/assets → dist}/agents/knowledge.md +8 -5
  8. package/{src/assets → dist}/agents/research.md +21 -2
  9. package/{src/assets → dist}/agents/review.md +18 -7
  10. package/{src/assets → dist}/agents/scrutinize.md +35 -11
  11. package/dist/agents/skim.md +148 -0
  12. package/{src/assets → dist}/agents/triage.md +8 -2
  13. package/dist/cli/commands/init.js +62 -0
  14. package/dist/cli/commands/learning.js +63 -8
  15. package/dist/cli/commands/uninstall.js +42 -1
  16. package/dist/commands/bug-analysis.md +30 -8
  17. package/dist/commands/code-review.md +142 -61
  18. package/dist/commands/debug.md +15 -13
  19. package/dist/commands/dynamic-build.md +176 -130
  20. package/dist/commands/dynamic-plan.md +31 -19
  21. package/dist/commands/dynamic-profile.md +27 -13
  22. package/dist/commands/dynamic-tickets.md +28 -14
  23. package/dist/commands/explore.md +16 -14
  24. package/dist/commands/implement.md +163 -158
  25. package/dist/commands/plan.md +37 -24
  26. package/dist/commands/release.md +69 -4
  27. package/dist/commands/research.md +33 -11
  28. package/dist/commands/resolve.md +61 -47
  29. package/dist/commands/self-review.md +50 -32
  30. package/dist/core/agent-models.js +53 -7
  31. package/dist/core/assets.js +55 -10
  32. package/dist/core/claude-md-audit.js +190 -0
  33. package/dist/core/feature-switch.js +20 -1
  34. package/dist/core/flags.js +28 -0
  35. package/dist/core/fs-atomic.js +8 -3
  36. package/dist/core/learning-tuning-config.js +8 -0
  37. package/dist/core/learning-variants.js +213 -0
  38. package/dist/core/manifest.js +62 -0
  39. package/dist/core/mds-variants.js +38 -1
  40. package/dist/core/plugins.js +78 -11
  41. package/{src/assets → dist/learning-off}/agents/code.md +77 -28
  42. package/dist/learning-off/agents/design.md +119 -0
  43. package/dist/learning-off/agents/diagnose.md +210 -0
  44. package/dist/learning-off/agents/knowledge.md +90 -0
  45. package/dist/learning-off/agents/research.md +149 -0
  46. package/dist/learning-off/agents/review.md +228 -0
  47. package/dist/learning-off/agents/scrutinize.md +117 -0
  48. package/{src/assets → dist/learning-off}/agents/skim.md +5 -10
  49. package/dist/learning-off/agents/triage.md +163 -0
  50. package/dist/learning-off/commands/bug-analysis.md +420 -0
  51. package/dist/learning-off/commands/code-review.md +525 -0
  52. package/dist/learning-off/commands/debug.md +294 -0
  53. package/dist/learning-off/commands/dynamic-build.md +1255 -0
  54. package/dist/learning-off/commands/dynamic-plan.md +424 -0
  55. package/dist/learning-off/commands/dynamic-profile.md +214 -0
  56. package/dist/learning-off/commands/dynamic-tickets.md +632 -0
  57. package/dist/learning-off/commands/explore.md +210 -0
  58. package/dist/learning-off/commands/implement.md +808 -0
  59. package/dist/learning-off/commands/plan.md +664 -0
  60. package/dist/learning-off/commands/release.md +310 -0
  61. package/dist/learning-off/commands/research.md +222 -0
  62. package/dist/learning-off/commands/resolve.md +837 -0
  63. package/dist/learning-off/commands/self-review.md +266 -0
  64. package/dist/skills/git/references/tracker/_contract.md +33 -0
  65. package/dist/skills/git/references/tracker/github/fetch-issue.md +2 -0
  66. package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +2 -0
  67. package/dist/skills/git/references/tracker/github/gather-release-evidence.md +5 -1
  68. package/dist/skills/git/references/tracker/github/post-wave-report.md +2 -0
  69. package/dist/skills/git/references/tracker/github/setup-task.md +12 -0
  70. package/dist/skills/git/references/tracker/jira/associate-release.md +1 -1
  71. package/dist/skills/git/references/tracker/jira/fetch-issue.md +2 -0
  72. package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +2 -0
  73. package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +5 -1
  74. package/dist/skills/git/references/tracker/jira/post-wave-report.md +2 -0
  75. package/dist/skills/git/references/tracker/jira/setup-task.md +14 -2
  76. package/dist/skills/git/references/tracker/linear/associate-release.md +1 -1
  77. package/dist/skills/git/references/tracker/linear/fetch-issue.md +2 -0
  78. package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +2 -0
  79. package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +5 -1
  80. package/dist/skills/git/references/tracker/linear/post-wave-report.md +2 -0
  81. package/dist/skills/git/references/tracker/linear/setup-task.md +14 -2
  82. package/dist/targets/claude-code/installer.js +72 -36
  83. package/dist/targets/claude-code/language-stamp.js +185 -0
  84. package/dist/targets/claude-code/learning-install.js +489 -0
  85. package/package.json +1 -1
  86. package/src/assets/agents/code.mds +339 -0
  87. package/src/assets/agents/design.mds +149 -0
  88. package/src/assets/agents/diagnose.mds +225 -0
  89. package/src/assets/agents/evaluate.md +12 -25
  90. package/src/assets/agents/git.mds +29 -56
  91. package/src/assets/agents/knowledge.mds +125 -0
  92. package/src/assets/agents/learning.md +4 -6
  93. package/src/assets/agents/research.mds +176 -0
  94. package/src/assets/agents/review.mds +286 -0
  95. package/src/assets/agents/scrutinize.mds +132 -0
  96. package/src/assets/agents/simplify.md +20 -0
  97. package/src/assets/agents/skim.mds +161 -0
  98. package/src/assets/agents/synthesize.md +12 -0
  99. package/src/assets/agents/test.md +2 -2
  100. package/src/assets/agents/triage.mds +194 -0
  101. package/src/assets/agents/validate.md +15 -8
  102. package/src/assets/commands/_partials/_compliance.mds +5 -4
  103. package/src/assets/commands/_partials/_decisions.mds +31 -0
  104. package/src/assets/commands/_partials/_engine.mds +29 -24
  105. package/src/assets/commands/_partials/_knowledge.mds +26 -13
  106. package/src/assets/commands/_partials/_plan_contract.mds +1 -1
  107. package/src/assets/commands/_partials/_preamble.mds +33 -9
  108. package/src/assets/commands/_partials/_publication.mds +5 -4
  109. package/src/assets/commands/_partials/_settings.mds +13 -5
  110. package/src/assets/commands/_partials/_wave.mds +16 -6
  111. package/src/assets/commands/bug-analysis.mds +24 -2
  112. package/src/assets/commands/code-review.mds +148 -45
  113. package/src/assets/commands/debug.mds +17 -1
  114. package/src/assets/commands/dynamic-build.mds +144 -65
  115. package/src/assets/commands/dynamic-plan.mds +36 -6
  116. package/src/assets/commands/dynamic-profile.mds +9 -1
  117. package/src/assets/commands/dynamic-tickets.mds +16 -2
  118. package/src/assets/commands/explore.mds +27 -1
  119. package/src/assets/commands/implement.mds +171 -138
  120. package/src/assets/commands/plan.mds +47 -8
  121. package/src/assets/commands/{release.md → release.mds} +27 -24
  122. package/src/assets/commands/research.mds +28 -4
  123. package/src/assets/commands/resolve.mds +69 -17
  124. package/src/assets/commands/self-review.mds +43 -13
  125. package/src/assets/mds/tracker/_common.mds +1 -1
  126. package/src/assets/mds/tracker/_contract.mds +72 -0
  127. package/src/assets/mds/tracker/_github.mds +13 -2
  128. package/src/assets/mds/tracker/_jira.mds +17 -5
  129. package/src/assets/mds/tracker/_linear.mds +17 -5
  130. package/src/assets/mds/tracker/_mcp.mds +2 -2
  131. package/src/assets/mds/tracker/_steps.mds +97 -0
  132. package/src/assets/rules/context-economy.md +10 -0
  133. package/src/assets/rules/go.md +1 -0
  134. package/src/assets/rules/java.md +1 -0
  135. package/src/assets/rules/python.md +1 -0
  136. package/src/assets/rules/rust.md +1 -0
  137. package/src/assets/rules/typescript.md +1 -0
  138. package/src/assets/scripts/ci-wait.cjs +636 -0
  139. package/src/assets/scripts/claude-md-audit.cjs +611 -0
  140. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +2 -3
  141. package/src/assets/scripts/hooks/background-memory-update +290 -9
  142. package/src/assets/scripts/hooks/json-helper.cjs +13 -5
  143. package/src/assets/scripts/hooks/json-parse +34 -10
  144. package/src/assets/scripts/hooks/session-start-context +315 -7
  145. package/src/assets/scripts/release-trace.cjs +27 -10
  146. package/src/assets/skills/accessibility/SKILL.md +1 -1
  147. package/src/assets/skills/apply-decisions/SKILL.md +12 -82
  148. package/src/assets/skills/apply-feature-knowledge/SKILL.md +9 -43
  149. package/src/assets/skills/architecture/SKILL.md +1 -1
  150. package/src/assets/skills/boundary-validation/SKILL.md +1 -1
  151. package/src/assets/skills/complexity/SKILL.md +1 -1
  152. package/src/assets/skills/compliance/SKILL.md +1 -1
  153. package/src/assets/skills/consistency/SKILL.md +1 -1
  154. package/src/assets/skills/database/SKILL.md +1 -1
  155. package/src/assets/skills/dependencies/SKILL.md +1 -1
  156. package/src/assets/skills/dependency-research/SKILL.md +3 -6
  157. package/src/assets/skills/design-review/SKILL.md +1 -1
  158. package/src/assets/skills/docs-framework/SKILL.md +1 -1
  159. package/src/assets/skills/documentation/SKILL.md +1 -1
  160. package/src/assets/skills/feature-knowledge/SKILL.md +43 -12
  161. package/src/assets/skills/gap-analysis/SKILL.md +1 -1
  162. package/src/assets/skills/git/SKILL.md +1 -1
  163. package/src/assets/skills/go/SKILL.md +1 -1
  164. package/src/assets/skills/java/SKILL.md +1 -1
  165. package/src/assets/skills/patterns/SKILL.md +1 -1
  166. package/src/assets/skills/performance/SKILL.md +1 -1
  167. package/src/assets/skills/python/SKILL.md +1 -1
  168. package/src/assets/skills/qa/SKILL.md +1 -3
  169. package/src/assets/skills/quality-gates/SKILL.md +10 -13
  170. package/src/assets/skills/quality-gates/references/report-template.md +20 -20
  171. package/src/assets/skills/react/SKILL.md +1 -1
  172. package/src/assets/skills/regression/SKILL.md +1 -1
  173. package/src/assets/skills/reliability/SKILL.md +1 -1
  174. package/src/assets/skills/research-codebase/SKILL.md +1 -1
  175. package/src/assets/skills/research-competitor/SKILL.md +1 -1
  176. package/src/assets/skills/research-external/SKILL.md +1 -1
  177. package/src/assets/skills/research-technology/SKILL.md +1 -1
  178. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  179. package/src/assets/skills/rust/SKILL.md +1 -1
  180. package/src/assets/skills/security/SKILL.md +1 -1
  181. package/src/assets/skills/software-design/SKILL.md +1 -1
  182. package/src/assets/skills/test-driven-development/SKILL.md +9 -29
  183. package/src/assets/skills/testing/SKILL.md +1 -1
  184. package/src/assets/skills/typescript/SKILL.md +1 -1
  185. package/src/assets/skills/ui-design/SKILL.md +1 -1
  186. package/src/assets/skills/worktree-support/SKILL.md +3 -55
  187. package/src/assets/skills/worktree-support/references/discovery.md +48 -0
  188. package/src/assets/skills/worktree-support/references/roots.md +2 -2
@@ -24,7 +24,7 @@ Run a comprehensive code review of the current branch by spawning parallel revie
24
24
 
25
25
  1. **Discover reviewable worktrees** using the `devflow:worktree-support` skill discovery algorithm:
26
26
  - Run `git worktree list --porcelain` → parse, filter (skip protected/detached/mid-rebase), dedup by branch, sort by recent commit
27
- - See the `devflow:worktree-support` skill for the full 7-step algorithm and canonical protected branch list
27
+ - Invoke the `devflow:worktree-support` skill, then Read its `references/discovery.md` from the skill's base directory for the full 7-step algorithm; the canonical protected branch list stays in the skill
28
28
  2. **If `--path` flag provided:** use only that worktree, skip discovery
29
29
  **`--path` validation**: Before proceeding, verify the path exists as a directory and appears in `git worktree list` output. If not: report error and stop.
30
30
  3. **If only 1 reviewable worktree** (the common case): proceed as single-worktree flow — zero behavior change
@@ -34,8 +34,6 @@ Run a comprehensive code review of the current branch by spawning parallel revie
34
34
 
35
35
  **Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS
36
36
 
37
- **Resolve the compliance lens** for each worktree root, from its settings line (every framework reference is installed on every machine, so no file check decides it):
38
-
39
37
  **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:
40
38
 
41
39
  ```bash
@@ -46,6 +44,8 @@ Accept the output only when it is exactly two lines: `exit=0` last and, before i
46
44
 
47
45
  The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
48
46
 
47
+ **Resolve the compliance lens** for each worktree root, from its settings line — the line resolved above for that root, by the settings block when this run has not yet resolved it (every framework reference is installed on every machine, so no file check decides it).
48
+
49
49
  **Set the compliance lens** from that line: `COMPLIANCE_FRAMEWORKS` is the settings line's `COMPLIANCE` with `generic` written `none`: `off`, `none`, or the framework ids the machine and this repository declare.
50
50
 
51
51
  `COMPLIANCE_ACTIVE` is `true` unless `COMPLIANCE_FRAMEWORKS` is `off`.
@@ -176,28 +176,56 @@ MAX_REVIEW_CYCLES = 10
176
176
 
177
177
  For each reviewable worktree, call:
178
178
 
179
- **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:
179
+ **Resolve `REVIEW_PUBLICATION` per worktree:** take `REVIEW_PUBLICATION` from that worktree's settings line — the line resolved above for `{root}`, the worktree's root, by the settings block when this run has not yet resolved that root; multi-worktree repos may resolve different values per worktree. The line already caps the personal choice at the team's (D-PUBLICATION-CEILING), so it is `off`, `auto` or `full`, and `off` when the line was unresolvable.
180
+
181
+ **Evidence stub:** only when `EVIDENCE_POLICY` is `required`, a resolved `off` becomes `stub`, so a counts-only record still reaches the PR. `stub` is never a config value: the settings line never carries it.
182
+
183
+ Note: `auto` is NOT fail-open — under `auto`, the Git agent probes the repository visibility and treats any error or unrecognised value as PUBLIC (mode STUB). What each value does is decided by the Git agent's publication gate (`references/publication-gate.md` step 2); this partial only resolves the value.
184
+
185
+ ### Phase 1: Analyze Changed Files
186
+
187
+ **Produces:** REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
188
+ **Requires:** DIFF_RANGE, REVIEW_DIR, COMPLIANCE_ACTIVE (from Step 0b)
189
+
190
+ Per worktree, in order. Each `git` command here writes to a file and prints nothing.
191
+
192
+ #### Step 1.1: Classify the diff
193
+
194
+ **Produces:** DIFF_CLASS, CHANGED_PATHS, REVIEW_FOCUS_LIST (reduced classes)
195
+ **Requires:** DIFF_RANGE, REVIEW_DIR
196
+
197
+ List the changed paths into `{REVIEW_DIR}/paths.txt` and print only the line count (drop `-C "{WORKTREE_PATH}"` when there is no `WORKTREE_PATH`):
180
198
 
181
199
  ```bash
182
- node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
200
+ git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
201
+ wc -l < "{REVIEW_DIR}/paths.txt"
183
202
  ```
184
203
 
185
- 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>` — 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` instead.
204
+ Read `paths.txt` once when the count is about 40 or fewer, and in ranges of about 40 lines (Read with offset and limit) when it is more. `--no-renames` lists a moved file under its old path and its new one, so a move cannot take a file out of its own class.
186
205
 
187
- The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
206
+ Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
188
207
 
189
- **Resolve `REVIEW_PUBLICATION` per worktree:** take `REVIEW_PUBLICATION` from that worktree's settings line, with `{root}` the worktree's root — multi-worktree repos may resolve different values per worktree. The line already caps the personal choice at the team's (D-PUBLICATION-CEILING), so it is `off`, `auto` or `full`, and `off` when the line was unresolvable.
208
+ 1. **Instruction and config paths are `code`.** Any changed path that is `CLAUDE.md`, `AGENTS.md`, under `.claude/` or `src/assets/`, a `*.mds` file, under a plugin's `agents/`, `skills/` or `commands/` directory, `.devflow/project.json`, `.devflow/conventions.md`, or a manifest or build file (`package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`, `requirements*.txt`, `CMakeLists.txt`). This rule runs first, so a diff made only of such files is `code` and never `docs-only`.
209
+ 2. **`docs-only`.** Every changed path matches `*.md`, `*.mdx`, `*.rst`, `*.txt`, `docs/**` or `CHANGELOG*`.
210
+ 3. **`tests-only`.** Every changed path matches `tests/**`, `**/__tests__/**`, `*.test.*`, `*.spec.*`, `*_test.go`, `test_*.py` or `*_test.py`.
211
+ 4. **`lockfile-only`.** Every changed path is `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, `bun.lockb`, `Cargo.lock`, `go.sum`, `poetry.lock`, `uv.lock`, `Gemfile.lock` or `composer.lock`.
212
+ 5. **Mixed non-code.** Every changed path matches the docs, tests or lockfile patterns, but no single rule above holds (docs with tests, tests with a lockfile): `DIFF_CLASS` names each class involved.
213
+ 6. **Fail-safe is `code`.** A changed path that matches no class pattern makes the diff `code`, and so does an empty path list. A manifest change is `code` and never `lockfile-only`.
190
214
 
191
- **Evidence stub:** only when `EVIDENCE_POLICY` is `required`, a resolved `off` becomes `stub`, so a counts-only record still reaches the PR. `stub` is never a config value: the settings line never carries it.
215
+ Each reduced class runs only its focus set, every member reading `diff.patch`:
192
216
 
193
- Note: `auto` is NOT fail-open — under `auto`, the Git agent probes the repository visibility and treats any error or unrecognised value as PUBLIC (mode STUB). What each value does is decided by the Git agent's publication gate (`references/publication-gate.md` step 2); this partial only resolves the value.
217
+ - `docs-only`: documentation, consistency, security
218
+ - `tests-only`: testing, reliability, consistency, security
219
+ - `lockfile-only`: dependencies, security
194
220
 
195
- ### Phase 1: Analyze Changed Files
221
+ A mixed non-code diff runs the union of the sets of the classes it holds. Language and conditional triggers inside a reduced class are suppressed: they add no focus, and Step 1.2 applies to the `code` class only.
196
222
 
197
- **Produces:** REVIEW_FOCUS_LIST
198
- **Requires:** DIFF_RANGE, COMPLIANCE_ACTIVE (from Step 0b)
223
+ #### Step 1.2: Choose the focuses
199
224
 
200
- Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditional reviews.
225
+ **Produces:** REVIEW_FOCUS_LIST (code class)
226
+ **Requires:** DIFF_CLASS, CHANGED_PATHS, COMPLIANCE_ACTIVE
227
+
228
+ When `DIFF_CLASS` is `code`, read the file types from the paths in `paths.txt` to determine conditional reviews:
201
229
 
202
230
  | Condition | Adds Review |
203
231
  |-----------|-------------|
@@ -216,20 +244,49 @@ Per worktree, detect file types in diff using `DIFF_RANGE` to determine conditio
216
244
 
217
245
  If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention): add `compliance` to REVIEW_FOCUS_LIST for this worktree.
218
246
 
219
- **Language focus presence gate.** The eight language focuses — `typescript`, `react`, `accessibility`, `ui-design`, `go`, `java`, `python`, `rust` — ship with optional plugins, so their pattern skills are installed only when the user selected that plugin. Gate them by presence: for each language focus the table above would add, check whether `{claude_dir}/skills/devflow:{focus}/SKILL.md` exists, `{claude_dir}` being Claude Code's directory as the installer resolves it — `CLAUDE_CONFIG_DIR` when that is set to an absolute path, else `$HOME/.claude` (D-CLAUDE-DIR-PROMPTS). Run one read-only, silent check per candidate focus:
247
+ **Language focus stamp.** The eight language focuses — `typescript`, `react`, `accessibility`, `ui-design`, `go`, `java`, `python`, `rust` — ship with optional plugins, and the installer stamps the ones installed on this machine onto this line, rewriting it on every install and on `uninstall --plugin`:
248
+
249
+ Installed language focuses: (none)
250
+
251
+ A language focus is spawned only when its file-type condition above fires AND its name appears in that stamped line. A focus missing from the line is never spawned, even when its trigger fires. The eight core focuses are unconditional and are never stamp-gated.
252
+
253
+ #### Step 1.3: Write the diff files
254
+
255
+ **Produces:** DIFF_FILES
256
+ **Requires:** DIFF_RANGE, REVIEW_DIR, REVIEW_FOCUS_LIST
257
+
258
+ Write `diff.patch` once per worktree, by redirect:
220
259
 
221
260
  ```bash
222
- d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; test -f "$d/skills/devflow:{focus}/SKILL.md"; echo "exit=$?"
261
+ git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
223
262
  ```
224
263
 
225
- Only `exit=0` means the skill is installed. On any other result, do NOT add that focus to `REVIEW_FOCUS_LIST` and do NOT spawn a Review agent for it — the file-type condition alone never spawns a language focus. The eight core focuses are unconditional and are never presence-gated.
264
+ It holds the whole diff of `DIFF_RANGE`. On a `code` diff, add one patch for each language focus in REVIEW_FOCUS_LIST, by the same command with quoted pathspecs from this table:
265
+
266
+ ```bash
267
+ git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
268
+ ```
269
+
270
+ | Focus | Pathspecs |
271
+ |-------|-----------|
272
+ | typescript | `'*.ts' '*.tsx'` |
273
+ | react, accessibility | `'*.tsx' '*.jsx'` |
274
+ | ui-design | `'*.tsx' '*.jsx' '*.css' '*.scss'` |
275
+ | go | `'*.go'` |
276
+ | java | `'*.java'` |
277
+ | python | `'*.py'` |
278
+ | rust | `'*.rs'` |
279
+
280
+ The core, database, dependencies, documentation and compliance focuses, and every reduced-class focus, read `diff.patch`. A language focus sees only its own extensions and reaches anything else through `DIFF_RANGE`. Set `DIFF_FILES` to the files written. They live in `REVIEW_DIR`, under the gitignored `.devflow/` tree, with `paths.txt`: never committed, posted or passed to the Git agent.
226
281
 
227
282
  ### Phase 1b: Load Decisions Index
228
283
 
229
- **Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
284
+ **Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
230
285
 
231
286
  ### Load DECISIONS_CONTEXT
232
287
 
288
+ When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
289
+
233
290
  The decisions ledger belongs to the repository, not to one checkout: in a linked worktree it lives in the main worktree, and a session started in a subdirectory reads the copy at the repository root. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
234
291
 
235
292
  ```bash
@@ -287,56 +344,69 @@ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read on
287
344
 
288
345
  Match the current task area and description against each index line (or frontmatter `description` + `directories` on fallback). Select entries whose documented area overlaps the current task. This is a relevance judgment — prefer specificity over breadth.
289
346
 
290
- **Step 4 — Read selected KBs:**
347
+ **Step 4 — Read each selected KB's Rules:**
348
+
349
+ For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
350
+
351
+ 1. List its `##` headings with line numbers through Bash: `command grep -n '^## ' "{kb}"`. This only locates sections; the text of a KB comes from the Read view alone.
352
+ 2. Read the `## Rules` range (its line to the next heading) with the Read tool, using `offset` and `limit`, and choose the one to three bullets most relevant to the current task. The choice is yours, made per KB.
353
+ 3. If the KB has no `## Rules` section, choose one to three entries from its `## Anti-Patterns` or `## Gotchas` range the same way, and label them by that section's name instead of an ID.
291
354
 
292
- For each selected entry, read `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md` in full. When the KB content contradicts the current code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind.
355
+ When a KB contradicts the code you observe, **trust the code** — the code is the freshness mechanism; the KB may lag behind. A missing Rules section, a missing heading list and `(none)` are legitimate states, not errors.
293
356
 
294
- **Step 5 — Set FEATURE_KNOWLEDGE:**
357
+ **Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
295
358
 
296
- Concatenate the selected KNOWLEDGE.md files under slug headers:
359
+ Write one block per selected KB. Paste each bullet verbatim from the Read view, never from a shell view. The path is relative to the checkout root; an agent resolves it under `WORKTREE_PATH` when one is provided.
297
360
 
298
361
  ```
299
362
  --- Feature knowledge: {slug} ---
300
- {full KNOWLEDGE.md content}
363
+ KB: .devflow/features/{slug}/KNOWLEDGE.md
364
+ Rules:
365
+ - **KB-AP-2** {bullet text, verbatim}
366
+ - **KB-INV-1** {bullet text, verbatim}
367
+ Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
301
368
  ```
302
369
 
303
- If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set `FEATURE_KNOWLEDGE` to `(none)`.
370
+ A KB with no Rules section labels its entries `Rules ({section name}):` and gives them no ID. `FEATURE_KNOWLEDGE` is these blocks; `FEATURE_KNOWLEDGE_RULES` is the same blocks without the `Headings:` line. Both come from this one selection, and each spawn names the variable its recipient takes. If no KBs exist, no KBs are relevant, or `.devflow/features/` is absent, set both to `(none)`.
304
371
 
305
- **One git call, then direct file reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), bounded by KB count.
372
+ **One git call, then direct reads — no `.cjs` script.** After resolving `{worktree}`, this step is 1 index read (or N frontmatter reads on fallback), plus one heading listing and one Rules read per selected KB, bounded by KB count.
306
373
 
307
374
  Pass `FEATURE_KNOWLEDGE` to all Review agents alongside `DECISIONS_CONTEXT`.
308
375
 
309
376
  ### Phase 2: Run Reviews (Parallel)
310
377
 
311
378
  **Produces:** REVIEW_FOCUS_OUTPUTS
312
- **Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST
313
-
314
- Spawn Review agents **in a single message**. Always run 8 core reviews; conditionally add more based on changed file types (max 20 per worktree):
315
-
316
- | Focus | Always | Pattern Skill |
317
- |-------|--------|---------------|
318
- | security | ✓ | devflow:security |
319
- | architecture | ✓ | devflow:architecture |
320
- | performance | ✓ | devflow:performance |
321
- | complexity | ✓ | devflow:complexity |
322
- | consistency | ✓ | devflow:consistency |
323
- | regression | ✓ | devflow:regression |
324
- | testing | ✓ | devflow:testing |
325
- | reliability | ✓ | devflow:reliability |
326
- | typescript | presence-gated | devflow:typescript |
327
- | react | presence-gated | devflow:react |
328
- | accessibility | presence-gated | devflow:accessibility |
329
- | ui-design | presence-gated | devflow:ui-design |
330
- | go | presence-gated | devflow:go |
331
- | java | presence-gated | devflow:java |
332
- | python | presence-gated | devflow:python |
333
- | rust | presence-gated | devflow:rust |
334
- | database | conditional | devflow:database |
335
- | dependencies | conditional | devflow:dependencies |
336
- | documentation | conditional | devflow:documentation |
337
- | compliance | diff-driven | devflow:compliance |
338
-
339
- Review agent count: 8 always-active, +1-12 diff-driven conditional (max 20 total per worktree).
379
+ **Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
380
+
381
+ Spawn Review agents **in a single message**, for the focus set `DIFF_CLASS` selects (max 20 per worktree):
382
+
383
+ - `code`: the 8 core reviews on the full `diff.patch`, plus the language and conditional focuses Phase 1 added.
384
+ - `docs-only`, `tests-only`, `lockfile-only`: only the reduced set Phase 1 names, each reading `diff.patch`; a mixed non-code diff runs the union. No language or conditional focus is spawned, whatever its trigger.
385
+
386
+ | Focus | Runs | Pattern Skill | DIFF_FILE |
387
+ |-------|------|---------------|-----------|
388
+ | security | ✓ | devflow:security | diff.patch |
389
+ | architecture | ✓ | devflow:architecture | diff.patch |
390
+ | performance | ✓ | devflow:performance | diff.patch |
391
+ | complexity | ✓ | devflow:complexity | diff.patch |
392
+ | consistency | ✓ | devflow:consistency | diff.patch |
393
+ | regression | ✓ | devflow:regression | diff.patch |
394
+ | testing | ✓ | devflow:testing | diff.patch |
395
+ | reliability | ✓ | devflow:reliability | diff.patch |
396
+ | typescript | stamp-gated | devflow:typescript | diff-typescript.patch |
397
+ | react | stamp-gated | devflow:react | diff-react.patch |
398
+ | accessibility | stamp-gated | devflow:accessibility | diff-accessibility.patch |
399
+ | ui-design | stamp-gated | devflow:ui-design | diff-ui-design.patch |
400
+ | go | stamp-gated | devflow:go | diff-go.patch |
401
+ | java | stamp-gated | devflow:java | diff-java.patch |
402
+ | python | stamp-gated | devflow:python | diff-python.patch |
403
+ | rust | stamp-gated | devflow:rust | diff-rust.patch |
404
+ | database | conditional | devflow:database | diff.patch |
405
+ | dependencies | conditional | devflow:dependencies | diff.patch |
406
+ | documentation | conditional | devflow:documentation | diff.patch |
407
+ | compliance | diff-driven | devflow:compliance | diff.patch |
408
+
409
+ Review agent count: `code` runs 8 core, +1-12 added by Phase 1 (max 20 total per worktree); a reduced class or a mix runs 2-6.
340
410
 
341
411
  Each Review agent invocation (all in one message, **NOT background**):
342
412
  ```
@@ -345,7 +415,8 @@ Agent(subagent_type="Review", run_in_background=false):
345
415
  Follow 6-step process from devflow:review-methodology.
346
416
  PR: #{pr_number}, Base: {base_branch}
347
417
  WORKTREE_PATH: {worktree_path} (omit if cwd)
348
- DIFF_COMMAND: git -C {WORKTREE_PATH} diff {DIFF_RANGE} (omit -C flag if no WORKTREE_PATH)
418
+ DIFF_FILE: {diff_file} (absolute: {REVIEW_DIR}/diff.patch, or {REVIEW_DIR}/diff-{focus}.patch for a language focus, per the table)
419
+ DIFF_RANGE: {DIFF_RANGE} (information only)
349
420
  DECISIONS_CONTEXT: {decisions_context}
350
421
  FEATURE_KNOWLEDGE: {feature_knowledge}
351
422
  PR_DESCRIPTION: <pr-description>{pr_description}</pr-description>
@@ -425,13 +496,15 @@ In multi-worktree mode, report results per worktree.
425
496
  ├─ Per worktree (SEQUENTIAL — one worktree at a time):
426
497
  │ │
427
498
  │ ├─ Phase 1: Analyze changed files
428
- │ │ └─ Detect file types for conditional reviews
499
+ │ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
500
+ │ │ ├─ Choose the focuses (code class: file types + the language stamp)
501
+ │ │ └─ Write diff.patch and diff-{focus}.patch, by redirect
429
502
  │ │
430
503
  │ ├─ Phase 2: Reviews (PARALLEL within worktree)
431
- │ │ ├─ Review agent: security
432
- │ │ ├─ Review agent: architecture, performance, complexity
433
- │ │ ├─ Review agent: consistency, regression, testing
434
- │ │ └─ Review agent: [conditional]
504
+ │ │ ├─ code: Review agents security, architecture, performance, complexity,
505
+ │ │ │ consistency, regression, testing, reliability (diff.patch)
506
+ │ │ ├─ code: + language (diff-{focus}.patch) and conditional Review agents
507
+ │ │ └─ docs-only / tests-only / lockfile-only: the reduced set (diff.patch)
435
508
  │ │
436
509
  │ ├─ Phase 3: Synthesis → Review Comment (SEQUENTIAL within worktree)
437
510
  │ │ ├─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
@@ -460,6 +533,14 @@ In multi-worktree mode, report results per worktree.
460
533
  | `--full` flag | Bypass incremental detection (Step 0d), still load PRIOR_RESOLUTIONS for cross-cycle awareness |
461
534
  | Parsing failure on resolution-summary.md | fp_ratio = 0, convergence tracking degraded (see Step 0e-ii) |
462
535
  | Concurrent sessions | Advisory only, each session computes independently |
536
+ | Docs-only diff | `docs-only`: documentation, consistency, security on `diff.patch`; no language or conditional focus |
537
+ | Tests-only diff | `tests-only`: testing, reliability, consistency, security on `diff.patch`; no language or conditional focus |
538
+ | Lockfile-only diff | `lockfile-only`: dependencies, security on `diff.patch` |
539
+ | Mixed non-code diff (docs with tests, tests with a lockfile) | The union of the matching sets, on `diff.patch` |
540
+ | A path matching no class pattern, or an empty path list | `code` (fail-safe): the 8 core focuses on the full diff |
541
+ | A file moved across classes | `--no-renames` lists the old and the new path, so a code path makes the diff `code` |
542
+ | Path listing above about 40 lines | The count is printed; `paths.txt` is read in ranges of about 40 lines |
543
+ | Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
463
544
  | Public repo (`auto` mode) | Git agent probes visibility, posts counts-only STUB comment; full report stays local |
464
545
  | `reviewPublication: off` | Git agent skips posting the review comment (OFF) — except that, only when `EVIDENCE_POLICY` is `required`, Step 0f passes `stub` and a counts-only STUB comment posts |
465
546
 
@@ -470,9 +551,9 @@ In multi-worktree mode, report results per worktree.
470
551
 
471
552
  ## Principles
472
553
 
473
- 1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself
554
+ 1. **Orchestration only** - Command spawns agents, doesn't do git/review work itself. The exceptions are the read-only Phase 0 probes (`git worktree list`, `git -C ... branch --show-current`, `git -C ... cat-file -t`), the bounded Phase 1 path listing (a redirect into `paths.txt`, a `wc -l` count and ranged reads) and the redirect-only patch writes (`diff.patch`, `diff-{focus}.patch`). Redirect-only writes print nothing, so no diff content reaches this thread
474
555
  2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
475
- 3. **Git agent for git work** - All git operations go through Git agent
556
+ 3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; redirect-only writes print nothing
476
557
  4. **Clear ownership** - Each agent owns its output completely
477
558
  5. **Honest reporting** - Display agent outputs directly
478
559
  6. **Incremental by default** - Only review new changes unless `--full` specified
@@ -32,8 +32,20 @@ $ARGUMENTS
32
32
 
33
33
  **Produces:** DECISIONS_CONTEXT
34
34
 
35
+ **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:
36
+
37
+ ```bash
38
+ node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
39
+ ```
40
+
41
+ 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>` — 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` instead.
42
+
43
+ The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
44
+
35
45
  ### Load DECISIONS_CONTEXT
36
46
 
47
+ When the settings line says `LEARNING=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
48
+
37
49
  The decisions ledger belongs to the repository, not to one checkout: in a linked worktree it lives in the main worktree, and a session started in a subdirectory reads the copy at the repository root. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
38
50
 
39
51
  ```bash
@@ -227,24 +239,14 @@ git -C "{start}" rev-parse --show-toplevel
227
239
 
228
240
  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}`.
229
241
 
230
- **Step 1 — Check the opt-out gate, with `{root}` = `{worktree}`:**
231
-
232
- **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:
233
-
234
- ```bash
235
- node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
236
- ```
237
-
238
- 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>` — 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` instead.
239
-
240
- The accepted line is the only source of these values: the script alone folds the committed `.devflow/project.json`, the personal `.devflow/config.json` and the machine manifest.
242
+ **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.
241
243
 
242
244
  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.
243
245
 
244
246
  **Step 2 — Evaluate whether write-back is warranted:**
245
247
 
246
248
  Only proceed if **at least one** of these is true:
247
- - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed).
249
+ - This workflow changed files in a directory that is documented by an existing feature knowledge base (a documented area changed). Knowledge bases are written through at that point, never on a background schedule.
248
250
  - This workflow surfaced durable, cross-cutting knowledge about a codebase area that would help future agents working in the same area — patterns, anti-patterns, integration points, gotchas not visible from a single file read.
249
251
 
250
252
  **Never spawn unconditionally.** If neither condition is met, skip write-back silently.
@@ -267,7 +269,7 @@ Write the knowledge base to:
267
269
  Then update the index cache by performing a read-modify-write on:
268
270
  {worktree}/.devflow/features/index.md
269
271
 
270
- Index line format: `- **{slug}** — {areas} — {Use-when description}`
272
+ Index line format: `- **{slug}** — {areas} — {Use-when description}` — at most 300 characters, the description at most 220; reword a longer one, never cut it.
271
273
 
272
274
  If the line for this slug already exists in index.md, replace it. If it does not exist, append it. If index.md does not exist, create it with just this line.
273
275