devflow-kit 3.9.0 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/README.md +1 -1
  3. package/dist/agents/code.md +6 -6
  4. package/dist/agents/fix.md +6 -6
  5. package/dist/agents/harden.md +7 -6
  6. package/dist/agents/refactor.md +6 -6
  7. package/dist/cli/commands/ambient.js +10 -2
  8. package/dist/cli/commands/backup-session.js +131 -0
  9. package/dist/cli/commands/compliance-prompts.js +9 -4
  10. package/dist/cli/commands/compliance.js +184 -24
  11. package/dist/cli/commands/curation.js +23 -10
  12. package/dist/cli/commands/gate-level-prompts.js +39 -25
  13. package/dist/cli/commands/gates.js +5 -7
  14. package/dist/cli/commands/init.js +169 -184
  15. package/dist/cli/commands/install-report.js +129 -0
  16. package/dist/cli/commands/legacy-sweep.js +159 -0
  17. package/dist/cli/commands/proxy.js +6 -1
  18. package/dist/cli/commands/rules.js +75 -21
  19. package/dist/cli/commands/skills.js +42 -9
  20. package/dist/cli/commands/tracker.js +9 -3
  21. package/dist/cli/commands/uninstall.js +339 -75
  22. package/dist/commands/bug-analysis.md +69 -120
  23. package/dist/commands/dynamic-build.md +23 -23
  24. package/dist/commands/implement.md +46 -32
  25. package/dist/commands/release.md +1 -1
  26. package/dist/commands/resolve.md +35 -31
  27. package/dist/commands/self-review.md +8 -7
  28. package/dist/compliance-off/agents/git.md +120 -0
  29. package/dist/compliance-off/agents/triage.md +180 -0
  30. package/dist/compliance-off/commands/bug-analysis.md +398 -0
  31. package/dist/compliance-off/commands/code-review.md +520 -0
  32. package/dist/compliance-off/commands/dynamic-build.md +1251 -0
  33. package/dist/compliance-off/commands/dynamic-tickets.md +676 -0
  34. package/dist/compliance-off/commands/implement.md +736 -0
  35. package/dist/compliance-off/commands/plan.md +671 -0
  36. package/dist/compliance-off/commands/release.md +309 -0
  37. package/dist/compliance-off/commands/resolve.md +742 -0
  38. package/dist/compliance-off/skills/git/references/decision-markers.md +17 -0
  39. package/dist/compliance-off/skills/git/references/learn-conventions.md +80 -0
  40. package/dist/compliance-off/skills/git/references/pr/check-ci-status.md +33 -0
  41. package/dist/compliance-off/skills/git/references/pr/check-merge-readiness.md +49 -0
  42. package/dist/compliance-off/skills/git/references/pr/fetch-review-threads.md +52 -0
  43. package/dist/compliance-off/skills/git/references/pr/validate-branch.md +47 -0
  44. package/dist/compliance-off/skills/git/references/tracker/_contract.md +33 -0
  45. package/dist/compliance-off/skills/git/references/tracker/_mcp.md +153 -0
  46. package/dist/compliance-off/skills/git/references/tracker/github/create-release.md +35 -0
  47. package/dist/compliance-off/skills/git/references/tracker/github/ensure-pr-ready.md +100 -0
  48. package/dist/compliance-off/skills/git/references/tracker/github/ensure-traceable-issue.md +74 -0
  49. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issue.md +69 -0
  50. package/dist/compliance-off/skills/git/references/tracker/github/fetch-issues-batch.md +65 -0
  51. package/dist/compliance-off/skills/git/references/tracker/github/gather-release-evidence.md +48 -0
  52. package/dist/compliance-off/skills/git/references/tracker/github/setup-task.md +77 -0
  53. package/dist/compliance-off/skills/git/references/tracker/jira/create-release.md +35 -0
  54. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-pr-ready.md +100 -0
  55. package/dist/compliance-off/skills/git/references/tracker/jira/ensure-traceable-issue.md +61 -0
  56. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issue.md +51 -0
  57. package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issues-batch.md +63 -0
  58. package/dist/compliance-off/skills/git/references/tracker/jira/gather-release-evidence.md +47 -0
  59. package/dist/compliance-off/skills/git/references/tracker/jira/setup-task.md +82 -0
  60. package/dist/compliance-off/skills/git/references/tracker/linear/create-release.md +35 -0
  61. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-pr-ready.md +100 -0
  62. package/dist/compliance-off/skills/git/references/tracker/linear/ensure-traceable-issue.md +61 -0
  63. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issue.md +51 -0
  64. package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issues-batch.md +63 -0
  65. package/dist/compliance-off/skills/git/references/tracker/linear/gather-release-evidence.md +47 -0
  66. package/dist/compliance-off/skills/git/references/tracker/linear/setup-task.md +83 -0
  67. package/dist/compliance-off/skills/git/references/trust-rule.md +7 -0
  68. package/dist/core/agent-models.js +19 -4
  69. package/dist/core/assets.js +126 -17
  70. package/dist/core/compliance-off-files.js +27 -0
  71. package/dist/core/compliance.js +14 -0
  72. package/dist/core/curation-variants.js +460 -112
  73. package/dist/core/flags.js +2 -2
  74. package/dist/core/fs-atomic.js +5 -1
  75. package/dist/core/installed-variants.js +63 -0
  76. package/dist/core/manifest.js +48 -5
  77. package/dist/core/mds-variants.js +700 -3
  78. package/dist/core/orphan-sweep.js +29 -2
  79. package/dist/core/path-set.js +15 -0
  80. package/dist/core/plugins.js +68 -10
  81. package/dist/core/reference-sweep.js +42 -25
  82. package/dist/core/retired-shipped-names.js +278 -0
  83. package/dist/curation-compliance-off/agents/triage.md +176 -0
  84. package/dist/curation-compliance-off/commands/bug-analysis.md +349 -0
  85. package/dist/curation-compliance-off/commands/code-review.md +481 -0
  86. package/dist/curation-compliance-off/commands/dynamic-build.md +1211 -0
  87. package/dist/curation-compliance-off/commands/dynamic-tickets.md +634 -0
  88. package/dist/curation-compliance-off/commands/implement.md +689 -0
  89. package/dist/curation-compliance-off/commands/plan.md +631 -0
  90. package/dist/curation-compliance-off/commands/release.md +279 -0
  91. package/dist/curation-compliance-off/commands/resolve.md +692 -0
  92. package/dist/curation-off/agents/code.md +6 -6
  93. package/dist/curation-off/agents/fix.md +6 -6
  94. package/dist/curation-off/agents/harden.md +7 -6
  95. package/dist/curation-off/agents/refactor.md +6 -6
  96. package/dist/curation-off/commands/bug-analysis.md +69 -119
  97. package/dist/curation-off/commands/dynamic-build.md +23 -23
  98. package/dist/curation-off/commands/implement.md +46 -32
  99. package/dist/curation-off/commands/release.md +1 -1
  100. package/dist/curation-off/commands/resolve.md +35 -31
  101. package/dist/curation-off/commands/self-review.md +8 -7
  102. package/dist/skills/git/references/pr/resolve-review-threads.md +1 -1
  103. package/dist/targets/claude-code/behavior-install.js +23 -9
  104. package/dist/targets/claude-code/charter-render.js +374 -0
  105. package/dist/targets/claude-code/compliance-install.js +62 -17
  106. package/dist/targets/claude-code/compliance-off-files.js +249 -0
  107. package/dist/targets/claude-code/curation-install.js +632 -117
  108. package/dist/targets/claude-code/folder-swap.js +142 -0
  109. package/dist/targets/claude-code/install-backup.js +780 -0
  110. package/dist/targets/claude-code/installer.js +795 -199
  111. package/dist/targets/claude-code/language-stamp.js +6 -0
  112. package/dist/targets/claude-code/legacy-skill-hashes.js +170 -0
  113. package/dist/targets/claude-code/linked-folder.js +176 -0
  114. package/dist/targets/claude-code/reference-converge.js +131 -0
  115. package/dist/targets/claude-code/rules-folder.js +34 -0
  116. package/dist/targets/claude-code/shipped-set.js +160 -0
  117. package/dist/targets/claude-code/tracker-install.js +21 -8
  118. package/dist/targets/claude-code/tracker-servers.js +20 -6
  119. package/dist/targets/claude-code/workflow-folder-install.js +251 -0
  120. package/dist/variant-axes.json +109 -0
  121. package/package.json +1 -1
  122. package/src/assets/agents/_partials/_code.mds +6 -6
  123. package/src/assets/agents/evaluate.md +1 -1
  124. package/src/assets/agents/git.mds +32 -0
  125. package/src/assets/agents/harden.mds +7 -6
  126. package/src/assets/agents/test.md +21 -12
  127. package/src/assets/agents/triage.mds +2 -0
  128. package/src/assets/agents/validate.md +10 -10
  129. package/src/assets/commands/_partials/_compliance.mds +5 -3
  130. package/src/assets/commands/_partials/_engine.mds +9 -8
  131. package/src/assets/commands/_partials/_publication.mds +10 -1
  132. package/src/assets/commands/bug-analysis.mds +80 -126
  133. package/src/assets/commands/code-review.mds +43 -0
  134. package/src/assets/commands/dynamic-build.mds +109 -15
  135. package/src/assets/commands/dynamic-tickets.mds +13 -0
  136. package/src/assets/commands/implement.mds +145 -33
  137. package/src/assets/commands/plan.mds +19 -0
  138. package/src/assets/commands/release.mds +50 -1
  139. package/src/assets/commands/resolve.mds +217 -32
  140. package/src/assets/commands/self-review.mds +8 -7
  141. package/src/assets/mds/git/_ops.mds +23 -0
  142. package/src/assets/mds/git/_ops_steps.mds +17 -0
  143. package/src/assets/mds/git/_pr.mds +1 -1
  144. package/src/assets/mds/git/_references.mds +6 -0
  145. package/src/assets/mds/tracker/_common.mds +4 -0
  146. package/src/assets/mds/tracker/_github.mds +42 -0
  147. package/src/assets/mds/tracker/_jira.mds +43 -0
  148. package/src/assets/mds/tracker/_linear.mds +43 -0
  149. package/src/assets/rules/quality.md +2 -0
  150. package/src/assets/scripts/ci-wait.cjs +204 -126
  151. package/src/assets/scripts/hooks/assets/implement-installed +1 -0
  152. package/src/assets/scripts/hooks/assets/orchestrator-charter.md +13 -11
  153. package/src/assets/scripts/hooks/preamble +18 -8
  154. package/src/assets/scripts/hooks/session-start-orchestrator +4 -2
  155. package/src/assets/scripts/pr-evidence.cjs +41 -2
  156. package/src/assets/scripts/verify-evidence.cjs +408 -56
  157. package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +3 -3
  158. package/src/assets/skills/agent-references/references/commands/plan-levels.md +1 -1
  159. package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +6 -2
  160. package/src/assets/skills/agent-references/references/validate/passed-alone.md +7 -7
  161. package/src/assets/skills/docs-framework/SKILL.md +5 -2
  162. package/src/assets/skills/git/SKILL.md +3 -3
  163. package/src/assets/skills/git/references/github-api.md +2 -139
  164. package/src/assets/skills/git/references/github-posting.md +158 -0
  165. package/src/assets/skills/review-methodology/SKILL.md +1 -1
  166. package/src/assets/skills/review-methodology/references/patterns.md +1 -1
  167. package/src/assets/skills/review-methodology/references/report-template.md +1 -2
  168. package/src/assets/skills/testing/SKILL.md +2 -4
@@ -0,0 +1,520 @@
1
+ ---
2
+ description: Comprehensive branch review using specialized sub-agents for PR readiness
3
+ ---
4
+ # Code Review Command
5
+
6
+ Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into a local review summary.
7
+
8
+ ## Usage
9
+
10
+ ```
11
+ /code-review (review current branch — or all worktrees if multiple found)
12
+ /code-review #42 (review specific PR)
13
+ /code-review --full (force full-branch review, ignore previous review state)
14
+ /code-review --path /path/to/worktree (review a specific worktree only)
15
+ ```
16
+
17
+ ## Phases
18
+
19
+ ### Phase 0: Worktree Discovery & Pre-Flight
20
+
21
+ #### Step 0a: Discover Worktrees
22
+
23
+ **Produces:** WORKTREES
24
+
25
+ 1. **Discover reviewable worktrees**:
26
+ - Run `git worktree list --porcelain` and count the worktrees it lists
27
+ - **More than one listed:** 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. Parse the list, filter (skip protected/detached/mid-rebase), dedup by branch, sort by recent commit
28
+ - **Exactly one listed:** load neither the skill nor the reference — that worktree is the only candidate, and Step 0c's Git agent validates its branch
29
+ 2. **If `--path` flag provided:** use only that worktree, skip discovery
30
+ **`--path` validation**: the path must be a directory in `git worktree list` output; if not, report an error and stop.
31
+ 3. **If only 1 reviewable worktree**: proceed as single-worktree flow
32
+ 4. **If multiple reviewable worktrees:** report "Found N worktrees with reviewable branches: {list with paths and branches}" and proceed with multi-worktree flow
33
+
34
+ #### Step 0b: Resolve the compliance lens and gate level
35
+
36
+ **Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS, GATE_LEVEL
37
+
38
+ **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 in a one-worktree run:
39
+
40
+ ```bash
41
+ node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
42
+ ```
43
+
44
+ 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=off CURATION=off KNOWLEDGE=off GATE_LEVEL=full` instead.
45
+
46
+ The accepted line is the only source of these values.
47
+
48
+ **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).
49
+
50
+ **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.
51
+
52
+ `COMPLIANCE_ACTIVE` is `true` unless `COMPLIANCE_FRAMEWORKS` is `off`.
53
+ Keep each worktree's values for every downstream phase.
54
+
55
+ #### Step 0b-ii: Resolve the evidence policy
56
+
57
+ **Produces:** EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL
58
+
59
+ **Resolve the evidence policy once per run**, from the repository root, before any step reads the values:
60
+
61
+ ```bash
62
+ node "$HOME/.devflow/scripts/resolve-evidence-policy.cjs" 2>/dev/null; echo "exit=$?"
63
+ ```
64
+
65
+ Accept the output only when it is exactly two lines: `exit=0` last and, before it, one line of the form `EVIDENCE_POLICY=<required|standard> SOURCE=<file|worktree|default|invalid|error> REF=<branch|none>[ WARN=<remote-unavailable|invalid-file|raised-by-compliance|pr-changes-policy>[,…]] ISSUE_REQUIRED=<true|false> APPLY_CONVENTIONS=<true|false> REQUIRE_NON_AUTHOR_APPROVAL=<true|false>` — these fields, in this order, nothing else, where `<branch>` is a branch name such as `main`. **Anything else** (a non-zero exit, no line, extra text, or a missing, reordered or unlisted field or value) ⇒ use `EVIDENCE_POLICY=required SOURCE=error REF=none ISSUE_REQUIRED=true APPLY_CONVENTIONS=true REQUIRE_NON_AUTHOR_APPROVAL=true` instead.
66
+
67
+ Set `EVIDENCE_POLICY`, `ISSUE_REQUIRED`, `APPLY_CONVENTIONS` and `REQUIRE_NON_AUTHOR_APPROVAL` from the accepted line. Pass agents only the three mechanism inputs, never `EVIDENCE_POLICY`. Report `Evidence policy: {EVIDENCE_POLICY} (source: {SOURCE})`, plus any `WARN` tokens as advisory, once in the final report.
68
+ When `EVIDENCE_POLICY` is `required`, record `TRACEABILITY: DEGRADED (compliance off on this machine; the repository requires evidence)` once, for the Phase 4 report.
69
+
70
+ #### Step 0c: Per-Worktree Pre-Flight (Git Agent)
71
+
72
+ **Produces:** BRANCH_INFO, PR_INFO, PR_DESCRIPTION, PR_DESCRIPTION_GUIDANCE
73
+ **Requires:** WORKTREES
74
+
75
+ Discover PR description guidance from plan artifact (per worktree):
76
+ 1. List the design plans: `{worktree}/.devflow/docs/design/*.md` (a `/plan` artifact) and `{worktree}/.devflow/docs/design/*/*/*-plan.md` (a `/dynamic-plan` per-ticket plan)
77
+ 2. Sort by timestamp, newest first, and scan the 10 most recent. A `/plan` artifact's timestamp is the `YYYY-MM-DD_HHMM` before its `.md`; a per-ticket plan's is the name of its parent directory. Never sort by file name, which starts with an issue ID or a ticket slug. A per-ticket plan counts only when its `{ticket-slug}` (its file name without `-plan.md`) appears in the worktree's branch name
78
+ 3. Read the most recent file that carries the section, extract `## PR Description Guidance` section
79
+ 4. If no plan files exist or section not found, set `PR_DESCRIPTION_GUIDANCE` to `(none)`
80
+
81
+ For each reviewable worktree, spawn Git agent:
82
+
83
+ ```
84
+ Agent(subagent_type="Git", run_in_background=false):
85
+ "OPERATION: ensure-pr-ready
86
+ WORKTREE_PATH: {worktree_path} (omit if cwd)
87
+ PR_DESCRIPTION_GUIDANCE: {pr_description_guidance}
88
+ APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
89
+ Validate branch, commit if needed, push, create PR if needed.
90
+ Return: branch, base_branch, base_ref, branch-slug, PR#"
91
+ ```
92
+
93
+ In multi-worktree mode, spawn all pre-flight agents **in a single message**.
94
+
95
+ **If BLOCKED:** In single-worktree mode, stop and report. In multi-worktree mode, report the failure but continue with other worktrees.
96
+
97
+ **Extract from response:** `branch`, `base_branch`, `base_ref`, `branch_slug`, `pr_number` per worktree. Stop with cause and fix when the Base line reads (rejected) or `branch_slug` does not match the slug pattern above; name the Git agent's fix, never your own, and for the slug the allowed characters, never its value. In multi-worktree mode this blocks only that worktree.
98
+
99
+ **Fetch PR body** (after extracting `pr_number`):
100
+ ```bash
101
+ PR_DESCRIPTION=$(gh pr view {pr_number} --json body --jq '.body' 2>/dev/null || echo "(none)")
102
+ ```
103
+ If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
104
+
105
+ #### Step 0d: Incremental Detection & Timestamp Setup
106
+
107
+ **Produces:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP
108
+ **Requires:** BRANCH_INFO
109
+
110
+ For each worktree:
111
+
112
+ 1. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
113
+ 2. Check if `{gd}/devflow/reviews/{branch-slug}/.last-review-head` exists, `{gd}` being what `git -C "{worktree}" rev-parse --absolute-git-dir` prints:
114
+ - **If yes AND `--full` NOT set:**
115
+ - The stored review head is checked as a commit ID: use it only when it is exactly 40 or 64 lowercase hex, else take the full-range path
116
+ - Verify reachable: `git -C "{worktree}" cat-file -t {sha}` must print `commit` (else take the full-range path)
117
+ - Check if SHA == current HEAD → if so, skip review: "No new commits since last review. Use --full for a full re-review."
118
+ - Set `DIFF_RANGE` to `{last-review-sha}...HEAD`
119
+ - **Full-range path (no marker, or `--full`):**
120
+ - Stop as for a (rejected) Base line unless `base_ref` is 40 or 64 hex.
121
+ - Set `DIFF_RANGE` to `{base_ref}...HEAD`
122
+ 3. Create timestamped review directory: `mkdir -p {worktree}/.devflow/docs/reviews/{branch-slug}/{timestamp}/`
123
+
124
+ #### Step 0e-i: Load Prior Resolution and Count Cycles
125
+
126
+ **Produces:** PRIOR_RESOLUTIONS, CYCLE_NUMBER
127
+ **Requires:** BRANCH_INFO
128
+
129
+ For each worktree:
130
+ 1. List the timestamped directories: `ls -1d {worktree}/.devflow/docs/reviews/{branch-slug}/20* 2>/dev/null | sort -r`
131
+ 2. Iterate once: count each directory containing `resolution-summary.md` as CYCLE_NUMBER; capture the first (newest) as PRIOR_DIR.
132
+ 3. If CYCLE_NUMBER = 0: set PRIOR_RESOLUTIONS=(none), CYCLE_NUMBER=1, proceed.
133
+ 4. Otherwise: set CYCLE_NUMBER = count + 1. Read `{PRIOR_DIR}/resolution-summary.md` as PRIOR_RESOLUTIONS minus each section from a heading line (fenced or not) with the word `Private` (any case) not followed by a letter or digit, to the next unfenced heading with as many `#` as its start or fewer, else at end of file. Close any fence it leaves open. When unsure, cut more; if the cut fails, PRIOR_RESOLUTIONS=(none).
134
+ 5. If `--full`: still load PRIOR_RESOLUTIONS.
135
+
136
+ #### Step 0e-ii: Convergence Assessment
137
+
138
+ **Produces:** (refines CYCLE_NUMBER)
139
+ **Requires:** PRIOR_RESOLUTIONS, BRANCH_INFO
140
+
141
+ MAX_REVIEW_CYCLES = 10
142
+
143
+ 1. If CYCLE_NUMBER > MAX_REVIEW_CYCLES:
144
+ Warn in output: "⚠️ Review pipeline has run {CYCLE_NUMBER-1} cycles (exceeds MAX_REVIEW_CYCLES=10). Consider merging or manual inspection."
145
+ Continue with review.
146
+ 2. Parse Statistics table from PRIOR_RESOLUTIONS:
147
+ - Extract False Positive, Fixed, Deferred counts
148
+ - `deferred_count` = the Deferred row value (= FIX_SEPARATE + TECH_DEBT); By Design and Escalated are excluded from the fp_ratio denominator
149
+ - fp_ratio = fp_count / (fp_count + fixed_count + deferred_count)
150
+ - If denominator = 0: fp_ratio = 0, skip warning
151
+ - If parsing fails: fp_ratio = 0, skip warning; note in output: "Warning: Could not parse Statistics table. Convergence tracking degraded."
152
+ 3. If fp_ratio > 0.7 AND CYCLE_NUMBER >= 3:
153
+ Warn in output: "⚠️ Convergence: {ratio}% false positives in cycle {N-1}. Consider merging or manual inspection."
154
+ Continue with review.
155
+
156
+ **Decision table — Step 0e-ii paths:**
157
+
158
+ | Condition | Outcome |
159
+ |-----------|---------|
160
+ | CYCLE_NUMBER > MAX_REVIEW_CYCLES | Warn in output, continue |
161
+ | denominator = 0 OR parsing failed | fp_ratio = 0, skip warning (degraded note on parse failure) |
162
+ | fp_ratio > 0.7 AND CYCLE_NUMBER >= 3 | Warn in output, continue |
163
+
164
+ ### Phase 1: Analyze Changed Files
165
+
166
+ **Produces:** REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
167
+ **Requires:** DIFF_RANGE, REVIEW_DIR, COMPLIANCE_ACTIVE, GATE_LEVEL (from Step 0b)
168
+
169
+ Per worktree, in order. Each `git` command here writes to a file and prints nothing.
170
+
171
+ #### Step 1.1: Classify the diff
172
+
173
+ **Produces:** DIFF_CLASS, CHANGED_PATHS, REVIEW_FOCUS_LIST (reduced classes)
174
+ **Requires:** DIFF_RANGE, REVIEW_DIR
175
+
176
+ 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`):
177
+
178
+ ```bash
179
+ git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
180
+ echo "exit=$?"
181
+ wc -l < "{REVIEW_DIR}/paths.txt"
182
+ ```
183
+
184
+ The `exit=` line is the diff's. A non-zero diff exit stops. 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.
185
+
186
+ Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
187
+
188
+ 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`.
189
+ 2. **`docs-only`.** Every changed path matches `*.md`, `*.mdx`, `*.rst`, `*.txt`, `docs/**` or `CHANGELOG*`.
190
+ 3. **`tests-only`.** Every changed path matches `tests/**`, `**/__tests__/**`, `*.test.*`, `*.spec.*`, `*_test.go`, `test_*.py` or `*_test.py`.
191
+ 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`.
192
+ 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.
193
+ 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`.
194
+
195
+ Each reduced class runs only its focus set, every member reading `diff.patch`:
196
+
197
+ - `docs-only`: documentation, consistency, security
198
+ - `tests-only`: testing, reliability, consistency, security
199
+ - `lockfile-only`: dependencies, security
200
+
201
+ 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.
202
+
203
+ #### Step 1.2: Choose the focuses
204
+
205
+ **Produces:** REVIEW_FOCUS_LIST (code class)
206
+ **Requires:** DIFF_CLASS, CHANGED_PATHS, COMPLIANCE_ACTIVE
207
+
208
+ When `DIFF_CLASS` is `code`, read the file types from the paths in `paths.txt` to determine conditional reviews:
209
+
210
+ | Condition | Adds Review |
211
+ |-----------|-------------|
212
+ | Any .ts or .tsx files | typescript |
213
+ | .tsx or .jsx files (React components) | react |
214
+ | .tsx or .jsx files (React components) | accessibility |
215
+ | .tsx/.jsx/.css/.scss files | ui-design |
216
+ | .go files | go |
217
+ | .java files | java |
218
+ | .py files | python |
219
+ | .rs files | rust |
220
+ | DB/migration files | database |
221
+ | Dependency files changed | dependencies |
222
+ | Docs or significant code | documentation |
223
+ | COMPLIANCE_ACTIVE AND diff touches regulated surface | compliance |
224
+
225
+ If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention): on a `code` diff, add `compliance`.
226
+
227
+ **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`:
228
+
229
+ Installed language focuses: (none)
230
+
231
+ 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. On a `code` diff, REVIEW_FOCUS_LIST starts with the eight core focuses. Step 1.2b may narrow them; they are never stamp-gated.
232
+
233
+ #### Step 1.2b: Narrow by gate level
234
+
235
+ **Produces:** REVIEW_FOCUS_LIST, GATE_LEVEL
236
+ **Requires:** REVIEW_FOCUS_LIST, DIFF_CLASS, CHANGED_PATHS, GATE_LEVEL
237
+
238
+ **Gate level.** Narrow REVIEW_FOCUS_LIST, for every class, by this worktree's `GATE_LEVEL`. `full` keeps it and reads nothing.
239
+
240
+ 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/code-review-levels.md` with the Read tool.
241
+
242
+ - Apply each class's row to that class's own set, then take the union of the results. A row only removes focuses.
243
+ - If the Read fails, or a row is missing or malformed, set `GATE_LEVEL` to `full` for every worktree of this run and say `level reference unreadable: full sets applied`.
244
+ - Security runs at every level and in every class.
245
+ - Compliance keeps the trigger above at every level.
246
+
247
+ #### Step 1.3: Write the diff files
248
+
249
+ **Produces:** DIFF_FILES
250
+ **Requires:** DIFF_RANGE, REVIEW_DIR, REVIEW_FOCUS_LIST
251
+
252
+ Write `diff.patch` once per worktree, by redirect:
253
+
254
+ ```bash
255
+ git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
256
+ ```
257
+
258
+ It holds the whole diff of `DIFF_RANGE`. A non-zero exit of any patch write stops. 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:
259
+
260
+ ```bash
261
+ git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
262
+ ```
263
+
264
+ | Focus | Pathspecs |
265
+ |-------|-----------|
266
+ | typescript | `'*.ts' '*.tsx'` |
267
+ | react, accessibility | `'*.tsx' '*.jsx'` |
268
+ | ui-design | `'*.tsx' '*.jsx' '*.css' '*.scss'` |
269
+ | go | `'*.go'` |
270
+ | java | `'*.java'` |
271
+ | python | `'*.py'` |
272
+ | rust | `'*.rs'` |
273
+
274
+ 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.
275
+
276
+ ### Phase 1b: Load Decisions Index
277
+
278
+ **Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
279
+
280
+ ### Load DECISIONS_CONTEXT
281
+
282
+ When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
283
+
284
+ The decisions ledger belongs to the repository, not to one checkout: a linked worktree reads the main worktree's copy, a subdirectory session the repository root's. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
285
+
286
+ ```bash
287
+ git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
288
+ ```
289
+
290
+ Line 1 is the checkout's toplevel, line 2 the common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first that applies:
291
+
292
+ 1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
293
+ 2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
294
+ 3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
295
+
296
+ This is the rule the curation hooks apply, so you read the index the Curate agent writes.
297
+
298
+ **Step 1 — Read the pre-rendered index:**
299
+
300
+ Attempt to read `{ledger}/.devflow/curation/index.md`.
301
+
302
+ - If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
303
+ - If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
304
+
305
+ The index is one direct file read, written at render time by `render-decisions.cjs` — no `.cjs` script runs here.
306
+
307
+ **Step 2 — Slice the index, then hand it on:**
308
+
309
+ When `DECISIONS_CONTEXT` is not `(none)`, hand it only to the agents whose contract declares it.
310
+
311
+ Hand each agent that takes `DECISIONS_CONTEXT` a slice, not the whole index: the index lines whose title, scope or area touch the files and task it works on, verbatim, led by `(slice: N of M entries — full index: <absolute index path>)` and closed by the index footer. When unsure, include the line. Siblings over one diff share ONE slice.
312
+
313
+ Those agents follow `devflow:apply-decisions`. A host that uses the index in its own thread says so in its own step.
314
+
315
+ This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT` to all Review agents as one shared slice, cut over the diff's files. Review agents use `devflow:apply-decisions` to Read full entry bodies on demand.
316
+
317
+ ### Load Feature Knowledge
318
+
319
+ 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
320
+
321
+ ```bash
322
+ git -C "{start}" rev-parse --show-toplevel
323
+ ```
324
+
325
+ 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}`.
326
+
327
+ **Step 1 — Read the index cache:**
328
+
329
+ Attempt to read `{worktree}/.devflow/features/index.md`. Each line follows the format:
330
+
331
+ ```
332
+ - **{slug}** — {areas} — {Use-when description}
333
+ ```
334
+
335
+ If `index.md` exists and contains at least one entry line, use it for relevance matching.
336
+
337
+ **Step 2 — Fallback: glob frontmatter (if `index.md` is absent or empty):**
338
+
339
+ Glob `{worktree}/.devflow/features/*/KNOWLEDGE.md`. For each file found, read only its YAML frontmatter block (between the opening and closing `---` delimiters).
340
+
341
+ **Step 3 — Pick relevant KBs:**
342
+
343
+ 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.
344
+
345
+ **Step 4 — Read each selected KB's Rules:**
346
+
347
+ For each selected entry, `{kb}` is `{worktree}/.devflow/features/{slug}/KNOWLEDGE.md`:
348
+
349
+ 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.
350
+ 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.
351
+ 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.
352
+
353
+ 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.
354
+
355
+ **Step 5 — Set FEATURE_KNOWLEDGE and FEATURE_KNOWLEDGE_RULES:**
356
+
357
+ 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.
358
+
359
+ ```
360
+ --- Feature knowledge: {slug} ---
361
+ KB: .devflow/features/{slug}/KNOWLEDGE.md
362
+ Rules:
363
+ - **KB-AP-2** {bullet text, verbatim}
364
+ - **KB-INV-1** {bullet text, verbatim}
365
+ Headings: L5 Rules · L40 Overview · L62 Anti-Patterns · L118 Key Files
366
+ ```
367
+
368
+ 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)`.
369
+
370
+ **One git call, then direct reads — no `.cjs` script.**
371
+
372
+ Pass `FEATURE_KNOWLEDGE` to all Review agents alongside `DECISIONS_CONTEXT`.
373
+
374
+ ### Phase 2: Run Reviews (Parallel)
375
+
376
+ **Produces:** REVIEW_FOCUS_OUTPUTS
377
+ **Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
378
+
379
+ Spawn Review agents **in a single message**, one per focus in REVIEW_FOCUS_LIST (max 20 per worktree):
380
+
381
+ - `code`: the 8 core reviews on the full `diff.patch` (lean keeps 3), plus the language and conditional focuses Phase 1 added.
382
+ - `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.
383
+
384
+ | Focus | Runs | Pattern Skill | DIFF_FILE |
385
+ |-------|------|---------------|-----------|
386
+ | security | ✓ | devflow:security | diff.patch |
387
+ | architecture | ✓ | devflow:architecture | diff.patch |
388
+ | performance | ✓ | devflow:performance | diff.patch |
389
+ | complexity | ✓ | devflow:complexity | diff.patch |
390
+ | consistency | ✓ | devflow:consistency | diff.patch |
391
+ | regression | ✓ | devflow:regression | diff.patch |
392
+ | testing | ✓ | devflow:testing | diff.patch |
393
+ | reliability | ✓ | devflow:reliability | diff.patch |
394
+ | typescript | stamp-gated | devflow:typescript | diff-typescript.patch |
395
+ | react | stamp-gated | devflow:react | diff-react.patch |
396
+ | accessibility | stamp-gated | devflow:accessibility | diff-accessibility.patch |
397
+ | ui-design | stamp-gated | devflow:ui-design | diff-ui-design.patch |
398
+ | go | stamp-gated | devflow:go | diff-go.patch |
399
+ | java | stamp-gated | devflow:java | diff-java.patch |
400
+ | python | stamp-gated | devflow:python | diff-python.patch |
401
+ | rust | stamp-gated | devflow:rust | diff-rust.patch |
402
+ | database | conditional | devflow:database | diff.patch |
403
+ | dependencies | conditional | devflow:dependencies | diff.patch |
404
+ | documentation | conditional | devflow:documentation | diff.patch |
405
+ | compliance | diff-driven | devflow:compliance | diff.patch |
406
+
407
+ Review agent count: `code` runs 8 core +1-12 at `full`, up to 2 fewer at `standard`, 3-4 at lean; a reduced class or a mix runs 2-6.
408
+
409
+ **Set the compliance focus directive** from `COMPLIANCE_FRAMEWORKS`. `COMPLIANCE_FOCUS_DIRECTIVE` is this one line, with `<ids>` replaced by the value of `COMPLIANCE_FRAMEWORKS`; only the compliance focus's spawn carries it:
410
+
411
+ > For this compliance focus, invoke Skill(skill="devflow:compliance") and load references/{id}.md only for the ids in <ids> (none: generic controls only); never fabricate guidance for a framework you were not given.
412
+
413
+ Each Review agent invocation (all in one message, **NOT background**):
414
+ ```
415
+ Agent(subagent_type="Review", run_in_background=false):
416
+ "Review focusing on {focus}. Load the pattern skill via the Skill tool: Skill(skill="devflow:{focus}").
417
+ Follow 6-step process from devflow:review-methodology.
418
+ PR: #{pr_number}, Base: {base_branch}
419
+ WORKTREE_PATH: {worktree_path} (omit if cwd)
420
+ DIFF_FILE: {diff_file} (absolute: {REVIEW_DIR}/diff.patch, or {REVIEW_DIR}/diff-{focus}.patch for a language focus, per the table)
421
+ DIFF_RANGE: {DIFF_RANGE} (information only)
422
+ DECISIONS_CONTEXT: {decisions_context}
423
+ FEATURE_KNOWLEDGE: {feature_knowledge}
424
+ PR_DESCRIPTION: <pr-description>{pr_description}</pr-description>
425
+ PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
426
+ {COMPLIANCE_FOCUS_DIRECTIVE} (compliance focus only)
427
+ If PRIOR_RESOLUTIONS is not (none), follow Cross-Cycle Awareness in review.md.
428
+ Follow devflow:apply-decisions to scan the index and Read full ADR/PF bodies on demand.
429
+ Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specific patterns and anti-patterns inform findings.
430
+ IMPORTANT: Write report to {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/{focus}.md using Write tool"
431
+ ```
432
+
433
+ In multi-worktree mode, process worktrees **sequentially**: Phases 1-4 for each.
434
+
435
+ ### Phase 3: Synthesis → Review Summary (Sequential)
436
+
437
+ **Produces:** REVIEW_SUMMARY
438
+ **Requires:** REVIEW_FOCUS_OUTPUTS, REVIEW_DIR, PR_INFO, GATE_LEVEL, REVIEW_FOCUS_LIST
439
+
440
+ **WAIT** for Phase 2. For each worktree, run step 3a:
441
+
442
+ **Step 3a — Synthesize agent** per worktree:
443
+ ```
444
+ Agent(subagent_type="Synthesize", run_in_background=false):
445
+ "Mode: review
446
+ WORKTREE_PATH: {worktree_path} (omit if cwd)
447
+ REVIEW_BASE_DIR: {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}
448
+ TIMESTAMP: {timestamp}
449
+ CYCLE_NUMBER: {cycle_number}
450
+ GATE_LEVEL: {GATE_LEVEL}
451
+ FOCUSES: {REVIEW_FOCUS_LIST}
452
+ PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
453
+ Include Convergence Status section in review-summary.md.
454
+ Aggregate findings, determine merge recommendation.
455
+ Output: {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/review-summary.md"
456
+ ```
457
+
458
+ ### Phase 4: Write Review Head Marker & Report
459
+
460
+ **Requires:** BRANCH_INFO, REVIEW_DIR
461
+
462
+ Per worktree, after successful completion:
463
+ 1. In one Bash call run `M="$(git -C "{worktree_path}" rev-parse --absolute-git-dir)/devflow/reviews/{branch-slug}" && mkdir -p "$M" && git -C "{worktree_path}" rev-parse HEAD > "$M/.last-review-head"`. A failed or refused write never stops the run and is not retried another way.
464
+ 2. Display results from all agents:
465
+ - Merge recommendation (from Synthesize agent)
466
+ - Issue counts by category (🔴 blocking / ⚠️ should-fix / ℹ️ pre-existing)
467
+ - Review summary: `.devflow/docs/reviews/{branch-slug}/{timestamp}/review-summary.md` (local; not posted)
468
+ - Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned, and the compliance-off line of Step 0b-ii
469
+ - Artifact paths
470
+
471
+ ## Architecture
472
+
473
+ ```
474
+ /code-review
475
+ │
476
+ ├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0e (Git agent per worktree, parallel)
477
+ │ ├─ Step 0b: Resolve the compliance lens and gate level
478
+ │
479
+ ├─ Per worktree (SEQUENTIAL):
480
+ │ │
481
+ │ ├─ Phase 1: Analyze changed files
482
+ │ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
483
+ │ │ ├─ Choose the focuses
484
+ │ │ └─ Write diff.patch and diff-{focus}.patch
485
+ │ │
486
+ │ ├─ Phase 2: Reviews (PARALLEL within worktree), one per REVIEW_FOCUS_LIST focus
487
+ │ │ ├─ code: core (diff.patch), language (diff-{focus}.patch), conditional
488
+ │ │ └─ docs-only / tests-only / lockfile-only: the reduced set (diff.patch)
489
+ │ │
490
+ │ ├─ Phase 3: Synthesis → Review Summary (SEQUENTIAL within worktree)
491
+ │ │ └─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
492
+ │ │
493
+ │ └─ Phase 4: Write .last-review-head + display results
494
+ ```
495
+
496
+ ## Edge Cases
497
+
498
+ | Case | Handling |
499
+ |------|----------|
500
+ | `--full` in multi-worktree mode | Applies to all worktrees (global modifier). It sets the diff range, never the gate level |
501
+ | Docs-only diff | Its Step 1.1 set, narrowed by level |
502
+ | Tests-only diff | Its Step 1.1 set, narrowed by level |
503
+ | Lockfile-only diff | Its Step 1.1 set, narrowed by level |
504
+ | Mixed non-code diff | The union of the matching sets |
505
+ | A path matching no class pattern, or an empty path list | `code` (fail-safe) |
506
+ | A file moved across classes | `--no-renames` lists both paths, so a code path makes the diff `code` |
507
+ | Path listing above about 40 lines | Read in ranges (Step 1.1) |
508
+ | Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
509
+
510
+ ## Backwards Compatibility
511
+
512
+ - **Gate level**: `full` runs the sets named here; the default `standard` and `lean` narrow them. `devflow gates --set full` keeps them.
513
+
514
+ ## Principles
515
+
516
+ 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`, `git -C ... rev-parse`), the bounded Phase 1 path listing and the writes (`diff.patch`, `diff-{focus}.patch`, the marker and its `mkdir -p`). These writes print nothing
517
+ 2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
518
+ 3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; its writes print nothing
519
+ 4. **Honest reporting** - Display agent outputs directly
520
+ 5. **Incremental by default** - Only review new changes unless `--full` specified