devflow-kit 3.6.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.
- package/CHANGELOG.md +438 -1
- package/README.md +15 -11
- package/dist/agents/code.md +9 -15
- package/dist/agents/design.md +1 -1
- package/dist/agents/fix.md +11 -13
- package/dist/agents/git.md +1 -1
- package/dist/agents/harden.md +1 -1
- package/dist/agents/refactor.md +7 -10
- package/dist/agents/review.md +6 -4
- package/dist/agents/skim.md +2 -2
- package/dist/agents/triage.md +2 -2
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/curation-move-io.js +102 -0
- package/dist/cli/commands/curation-move-step.js +374 -0
- package/dist/cli/commands/{learning.js → curation.js} +302 -99
- package/dist/cli/commands/gate-level-prompts.js +426 -0
- package/dist/cli/commands/gates.js +299 -0
- package/dist/cli/commands/init-seed.js +16 -5
- package/dist/cli/commands/init.js +263 -54
- package/dist/cli/commands/memory.js +20 -2
- package/dist/cli/commands/prompt-io.js +37 -0
- package/dist/cli/commands/uninstall.js +81 -9
- package/dist/cli.js +4 -2
- package/dist/commands/bug-analysis.md +25 -36
- package/dist/commands/code-review.md +77 -73
- package/dist/commands/debug.md +5 -5
- package/dist/commands/dynamic-build.md +76 -83
- package/dist/commands/dynamic-plan.md +5 -5
- package/dist/commands/dynamic-profile.md +5 -5
- package/dist/commands/dynamic-tickets.md +5 -5
- package/dist/commands/explore.md +6 -6
- package/dist/commands/implement.md +68 -102
- package/dist/commands/plan.md +19 -29
- package/dist/commands/release.md +5 -5
- package/dist/commands/research.md +6 -6
- package/dist/commands/resolve.md +29 -31
- package/dist/commands/self-review.md +5 -13
- package/dist/core/assets.js +20 -20
- package/dist/core/curate-tuning-config.js +5 -6
- package/dist/core/curation-move-notice.js +84 -0
- package/dist/core/curation-move-skip.js +36 -0
- package/dist/core/curation-move.js +35 -0
- package/dist/core/curation-queue-cleanup.js +134 -0
- package/dist/core/curation-store.js +98 -0
- package/dist/core/{learning-variants.js → curation-variants.js} +65 -41
- package/dist/core/echo-value.js +48 -0
- package/dist/core/evidence-policy.js +18 -6
- package/dist/core/feature-switch.js +95 -19
- package/dist/core/fs-atomic.js +1 -1
- package/dist/core/gate-level.js +221 -0
- package/dist/core/git.js +16 -14
- package/dist/core/ledger-root.js +82 -22
- package/dist/core/linked-path.js +4 -4
- package/dist/core/manifest-lock.js +238 -0
- package/dist/core/manifest.js +84 -24
- package/dist/core/migrations.js +1 -13
- package/dist/core/model-discovery.js +7 -1
- package/dist/core/observations.js +2 -2
- package/dist/core/plugins.js +15 -15
- package/dist/core/pool.js +26 -0
- package/dist/core/project-paths.js +103 -34
- package/dist/core/queue-drain.js +2 -2
- package/dist/core/tracked-areas.js +35 -0
- package/dist/core/tracker.js +6 -34
- package/dist/{learning-off → curation-off}/agents/code.md +9 -15
- package/dist/{learning-off → curation-off}/agents/fix.md +11 -13
- package/dist/{learning-off → curation-off}/agents/refactor.md +7 -10
- package/dist/{learning-off → curation-off}/agents/review.md +5 -3
- package/dist/{learning-off → curation-off}/agents/triage.md +1 -1
- package/dist/{learning-off → curation-off}/commands/bug-analysis.md +20 -31
- package/dist/{learning-off → curation-off}/commands/code-review.md +74 -70
- package/dist/{learning-off → curation-off}/commands/debug.md +2 -2
- package/dist/{learning-off → curation-off}/commands/dynamic-build.md +73 -80
- package/dist/{learning-off → curation-off}/commands/explore.md +2 -2
- package/dist/{learning-off → curation-off}/commands/implement.md +65 -99
- package/dist/{learning-off → curation-off}/commands/plan.md +15 -25
- package/dist/{learning-off → curation-off}/commands/resolve.md +26 -28
- package/dist/{learning-off → curation-off}/commands/self-review.md +2 -10
- package/dist/hud/components/{learning-counts.js → curation-counts.js} +36 -17
- package/dist/hud/config.js +1 -1
- package/dist/hud/index.js +6 -6
- package/dist/hud/render.js +3 -3
- package/dist/skills/git/references/pr/validate-branch.md +8 -5
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +20 -14
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +20 -20
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +20 -20
- package/dist/targets/claude-code/{learning-install.js → curation-install.js} +99 -67
- package/dist/targets/claude-code/installer.js +15 -15
- package/dist/targets/claude-code/language-stamp.js +5 -5
- package/dist/targets/claude-code/post-install.js +2 -2
- package/dist/targets/claude-code/tracker-servers.js +1 -1
- package/package.json +3 -2
- package/src/assets/agents/_partials/_code.mds +16 -17
- package/src/assets/agents/code.mds +4 -7
- package/src/assets/agents/curate.md +12 -14
- package/src/assets/agents/debug.mds +6 -6
- package/src/assets/agents/design.mds +18 -18
- package/src/assets/agents/fix.mds +6 -5
- package/src/assets/agents/git.mds +1 -1
- package/src/assets/agents/harden.mds +7 -7
- package/src/assets/agents/knowledge.mds +23 -23
- package/src/assets/agents/refactor.mds +2 -2
- package/src/assets/agents/research.mds +15 -15
- package/src/assets/agents/review.mds +45 -43
- package/src/assets/agents/skim.mds +11 -11
- package/src/assets/agents/synthesize.md +2 -2
- package/src/assets/agents/triage.mds +22 -22
- package/src/assets/agents/validate.md +13 -26
- package/src/assets/commands/_partials/_decisions.mds +13 -13
- package/src/assets/commands/_partials/_engine.mds +8 -8
- package/src/assets/commands/_partials/_knowledge.mds +29 -15
- package/src/assets/commands/_partials/_preamble.mds +4 -4
- package/src/assets/commands/_partials/_settings.mds +3 -3
- package/src/assets/commands/_partials/_wave.mds +17 -24
- package/src/assets/commands/bug-analysis.mds +37 -48
- package/src/assets/commands/code-review.mds +90 -86
- package/src/assets/commands/debug.mds +14 -14
- package/src/assets/commands/dynamic-build.mds +78 -78
- package/src/assets/commands/dynamic-plan.mds +22 -22
- package/src/assets/commands/dynamic-profile.mds +2 -2
- package/src/assets/commands/dynamic-tickets.mds +8 -8
- package/src/assets/commands/explore.mds +20 -20
- package/src/assets/commands/implement.mds +92 -118
- package/src/assets/commands/plan.mds +41 -51
- package/src/assets/commands/release.mds +12 -12
- package/src/assets/commands/research.mds +19 -19
- package/src/assets/commands/resolve.mds +56 -50
- package/src/assets/commands/self-review.mds +20 -20
- package/src/assets/mds/git/_ops.mds +3 -1
- package/src/assets/mds/git/_ops_pr.mds +1 -1
- package/src/assets/mds/git/_ops_steps.mds +13 -7
- package/src/assets/mds/git/_pr.mds +7 -4
- package/src/assets/mds/tracker/_common.mds +23 -12
- package/src/assets/mds/tracker/_github.mds +2 -9
- package/src/assets/mds/tracker/_jira.mds +2 -15
- package/src/assets/mds/tracker/_linear.mds +2 -15
- package/src/assets/rules/quality.md +1 -0
- package/src/assets/scripts/ci-wait.cjs +22 -4
- package/src/assets/scripts/claude-md-audit.cjs +66 -51
- package/src/assets/scripts/hooks/background-memory-update +406 -97
- package/src/assets/scripts/hooks/capture-prompt +12 -12
- package/src/assets/scripts/hooks/capture-question +11 -11
- package/src/assets/scripts/hooks/capture-turn +12 -12
- package/src/assets/scripts/hooks/{learning-lock → curation-lock} +2 -2
- package/src/assets/scripts/hooks/curation-move +293 -0
- package/src/assets/scripts/hooks/ensure-devflow-init +45 -13
- package/src/assets/scripts/hooks/ensure-proxy +4 -4
- package/src/assets/scripts/hooks/ensure-root-gitignore +4 -4
- package/src/assets/scripts/hooks/git-marker +81 -0
- package/src/assets/scripts/hooks/json-helper.cjs +145 -51
- package/src/assets/scripts/hooks/json-parse +19 -4
- package/src/assets/scripts/hooks/lib/curation-move.cjs +1582 -0
- package/src/assets/scripts/hooks/lib/{learning-store.cjs → curation-store.cjs} +242 -118
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +3 -3
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +24 -7
- package/src/assets/scripts/hooks/lib/project-paths.cjs +132 -39
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +34 -22
- package/src/assets/scripts/hooks/lib/tracked-areas.cjs +259 -0
- package/src/assets/scripts/hooks/memory-permission +358 -0
- package/src/assets/scripts/hooks/memory-worker +1 -1
- package/src/assets/scripts/hooks/pre-compact-memory +6 -16
- package/src/assets/scripts/hooks/queue-append +228 -103
- package/src/assets/scripts/hooks/resolve-project-root +2 -2
- package/src/assets/scripts/hooks/session-start-context +145 -71
- package/src/assets/scripts/hooks/session-start-memory +27 -46
- package/src/assets/scripts/lib/project-config.cjs +31 -9
- package/src/assets/scripts/resolve-base.cjs +1043 -0
- package/src/assets/scripts/resolve-settings.cjs +238 -46
- package/src/assets/skills/agent-references/SKILL.md +9 -2
- package/src/assets/skills/agent-references/references/commands/code-review-levels.md +19 -0
- package/src/assets/skills/agent-references/references/commands/implement-levels.md +27 -0
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +6 -4
- package/src/assets/skills/agent-references/references/commands/plan-levels.md +40 -0
- package/src/assets/skills/agent-references/references/commands/resolve-levels.md +24 -0
- package/src/assets/skills/agent-references/references/synthesize/planning.md +9 -22
- package/src/assets/skills/agent-references/references/synthesize/review.md +11 -11
- package/src/assets/skills/apply-decisions/SKILL.md +1 -1
- package/src/assets/skills/docs-framework/SKILL.md +7 -7
- package/src/assets/skills/docs-framework/references/patterns.md +3 -4
- package/src/assets/skills/quality-gates/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/references/roots.md +2 -2
- package/templates/lint-pack/.lint-pack.conf +86 -0
- package/templates/lint-pack/README.md +190 -0
- package/templates/lint-pack/lint-pack.sh +905 -0
- package/dist/core/learning-queue-cleanup.js +0 -27
- package/dist/core/learning-store.js +0 -61
- /package/dist/{learning-off → curation-off}/agents/debug.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/design.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/harden.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/knowledge.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/research.md +0 -0
- /package/dist/{learning-off → curation-off}/agents/skim.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-plan.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-profile.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/dynamic-tickets.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/release.md +0 -0
- /package/dist/{learning-off → curation-off}/commands/research.md +0 -0
|
@@ -10,7 +10,7 @@ output-dir: dist/commands
|
|
|
10
10
|
@import "./_partials/_settings.mds" as settings
|
|
11
11
|
# Code Review Command
|
|
12
12
|
|
|
13
|
-
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
13
|
+
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
@@ -34,18 +34,18 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
34
34
|
- **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
|
|
35
35
|
- **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
|
|
36
36
|
2. **If `--path` flag provided:** use only that worktree, skip discovery
|
|
37
|
-
**`--path` validation**:
|
|
38
|
-
3. **If only 1 reviewable worktree
|
|
37
|
+
**`--path` validation**: the path must be a directory in `git worktree list` output; if not, report an error and stop.
|
|
38
|
+
3. **If only 1 reviewable worktree**: proceed as single-worktree flow
|
|
39
39
|
4. **If multiple reviewable worktrees:** report "Found N worktrees with reviewable branches: {list with paths and branches}" and proceed with multi-worktree flow
|
|
40
40
|
|
|
41
|
-
#### Step 0b: Resolve the compliance lens
|
|
41
|
+
#### Step 0b: Resolve the compliance lens and gate level
|
|
42
42
|
|
|
43
|
-
**Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS
|
|
43
|
+
**Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS, GATE_LEVEL
|
|
44
44
|
|
|
45
45
|
{{settings.settings_resolve()}}
|
|
46
46
|
|
|
47
47
|
{{compliance_gate()}}
|
|
48
|
-
Keep each worktree's values for every downstream phase
|
|
48
|
+
Keep each worktree's values for every downstream phase.
|
|
49
49
|
|
|
50
50
|
#### Step 0b-ii: Resolve the evidence policy
|
|
51
51
|
|
|
@@ -84,20 +84,20 @@ PR_DESCRIPTION_GUIDANCE: {pr_description_guidance}
|
|
|
84
84
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
85
85
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
86
86
|
Validate branch, commit if needed, push, create PR if needed.
|
|
87
|
-
Return: branch, base_branch, branch-slug, PR#"
|
|
87
|
+
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
In multi-worktree mode, spawn all pre-flight agents **in a single message
|
|
90
|
+
In multi-worktree mode, spawn all pre-flight agents **in a single message**.
|
|
91
91
|
|
|
92
92
|
**If BLOCKED:** In single-worktree mode, stop and report. In multi-worktree mode, report the failure but continue with other worktrees.
|
|
93
93
|
|
|
94
|
-
**Extract from response:** `branch`, `base_branch`, `branch_slug`, `pr_number` per worktree.
|
|
94
|
+
**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.
|
|
95
95
|
|
|
96
96
|
**Fetch PR body** (after extracting `pr_number`):
|
|
97
97
|
```bash
|
|
98
98
|
PR_DESCRIPTION=$(gh pr view {pr_number} --json body --jq '.body' 2>/dev/null || echo "(none)")
|
|
99
99
|
```
|
|
100
|
-
If `pr_number` is absent
|
|
100
|
+
If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
101
101
|
|
|
102
102
|
#### Step 0d: Incremental Detection & Timestamp Setup
|
|
103
103
|
|
|
@@ -107,15 +107,16 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
107
107
|
For each worktree:
|
|
108
108
|
|
|
109
109
|
1. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
|
|
110
|
-
2.
|
|
111
|
-
3. Check if `{worktree}/.devflow/docs/reviews/{branch-slug}/.last-review-head` exists:
|
|
110
|
+
2. Check if `{gd}/devflow/reviews/{branch-slug}/.last-review-head` exists, `{gd}` being what `git -C "{worktree}" rev-parse --absolute-git-dir` prints:
|
|
112
111
|
- **If yes AND `--full` NOT set:**
|
|
113
|
-
-
|
|
114
|
-
- Verify reachable: `git -C {worktree} cat-file -t {sha}`
|
|
112
|
+
- 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
|
|
113
|
+
- Verify reachable: `git -C "{worktree}" cat-file -t {sha}` must print `commit` (else take the full-range path)
|
|
115
114
|
- Check if SHA == current HEAD → if so, skip review: "No new commits since last review. Use --full for a full re-review."
|
|
116
115
|
- Set `DIFF_RANGE` to `{last-review-sha}...HEAD`
|
|
117
|
-
- **
|
|
118
|
-
-
|
|
116
|
+
- **Full-range path (no marker, or `--full`):**
|
|
117
|
+
- Stop as for a (rejected) Base line unless `base_ref` is 40 or 64 hex.
|
|
118
|
+
- Set `DIFF_RANGE` to `{base_ref}...HEAD`
|
|
119
|
+
3. Create timestamped review directory: `mkdir -p {worktree}/.devflow/docs/reviews/{branch-slug}/{timestamp}/`
|
|
119
120
|
|
|
120
121
|
#### Step 0e-i: Load Prior Resolution and Count Cycles
|
|
121
122
|
|
|
@@ -127,7 +128,7 @@ For each worktree, perform a single pass over timestamped directories:
|
|
|
127
128
|
2. Iterate once: accumulate CYCLE_NUMBER count for each directory containing `resolution-summary.md`; capture the first (most-recent) such directory as PRIOR_DIR.
|
|
128
129
|
3. If CYCLE_NUMBER = 0: set PRIOR_RESOLUTIONS=(none), CYCLE_NUMBER=1, proceed.
|
|
129
130
|
4. Otherwise: set CYCLE_NUMBER = count + 1. Read `{PRIOR_DIR}/resolution-summary.md` as PRIOR_RESOLUTIONS.
|
|
130
|
-
5. If `--full`: still load PRIOR_RESOLUTIONS
|
|
131
|
+
5. If `--full`: still load PRIOR_RESOLUTIONS.
|
|
131
132
|
|
|
132
133
|
#### Step 0e-ii: Convergence Assessment
|
|
133
134
|
|
|
@@ -169,7 +170,7 @@ For each reviewable worktree, call:
|
|
|
169
170
|
### Phase 1: Analyze Changed Files
|
|
170
171
|
|
|
171
172
|
**Produces:** REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
172
|
-
**Requires:** DIFF_RANGE, REVIEW_DIR, COMPLIANCE_ACTIVE (from Step 0b)
|
|
173
|
+
**Requires:** DIFF_RANGE, REVIEW_DIR, COMPLIANCE_ACTIVE, GATE_LEVEL (from Step 0b)
|
|
173
174
|
|
|
174
175
|
Per worktree, in order. Each `git` command here writes to a file and prints nothing.
|
|
175
176
|
|
|
@@ -182,10 +183,11 @@ List the changed paths into `{REVIEW_DIR}/paths.txt` and print only the line cou
|
|
|
182
183
|
|
|
183
184
|
```bash
|
|
184
185
|
git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
|
|
186
|
+
echo "exit=$?"
|
|
185
187
|
wc -l < "{REVIEW_DIR}/paths.txt"
|
|
186
188
|
```
|
|
187
189
|
|
|
188
|
-
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.
|
|
190
|
+
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.
|
|
189
191
|
|
|
190
192
|
Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
|
|
191
193
|
|
|
@@ -202,7 +204,7 @@ Each reduced class runs only its focus set, every member reading `diff.patch`:
|
|
|
202
204
|
- `tests-only`: testing, reliability, consistency, security
|
|
203
205
|
- `lockfile-only`: dependencies, security
|
|
204
206
|
|
|
205
|
-
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
|
|
207
|
+
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.
|
|
206
208
|
|
|
207
209
|
#### Step 1.2: Choose the focuses
|
|
208
210
|
|
|
@@ -226,13 +228,27 @@ When `DIFF_CLASS` is `code`, read the file types from the paths in `paths.txt` t
|
|
|
226
228
|
| Docs or significant code | documentation |
|
|
227
229
|
| COMPLIANCE_ACTIVE AND diff touches regulated surface | compliance |
|
|
228
230
|
|
|
229
|
-
If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention):
|
|
231
|
+
If `COMPLIANCE_ACTIVE` AND the diff touches regulated surface (data models, auth flows, logging/observability, payments, IaC, retention): on a `code` diff, add `compliance`.
|
|
230
232
|
|
|
231
233
|
**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`:
|
|
232
234
|
|
|
233
235
|
Installed language focuses: (none)
|
|
234
236
|
|
|
235
|
-
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.
|
|
237
|
+
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.
|
|
238
|
+
|
|
239
|
+
#### Step 1.2b: Narrow by gate level
|
|
240
|
+
|
|
241
|
+
**Produces:** REVIEW_FOCUS_LIST, GATE_LEVEL
|
|
242
|
+
**Requires:** REVIEW_FOCUS_LIST, DIFF_CLASS, CHANGED_PATHS, GATE_LEVEL
|
|
243
|
+
|
|
244
|
+
**Gate level.** Narrow REVIEW_FOCUS_LIST, for every class, by this worktree's `GATE_LEVEL`. `full` keeps it and reads nothing.
|
|
245
|
+
|
|
246
|
+
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.
|
|
247
|
+
|
|
248
|
+
- Apply each class's row to that class's own set, then take the union of the results. A row only removes focuses.
|
|
249
|
+
- 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`.
|
|
250
|
+
- Security runs at every level and in every class.
|
|
251
|
+
- Compliance keeps the trigger above at every level.
|
|
236
252
|
|
|
237
253
|
#### Step 1.3: Write the diff files
|
|
238
254
|
|
|
@@ -245,7 +261,7 @@ Write `diff.patch` once per worktree, by redirect:
|
|
|
245
261
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
|
|
246
262
|
```
|
|
247
263
|
|
|
248
|
-
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:
|
|
264
|
+
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:
|
|
249
265
|
|
|
250
266
|
```bash
|
|
251
267
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
|
|
@@ -263,43 +279,43 @@ git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE
|
|
|
263
279
|
|
|
264
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.
|
|
265
281
|
|
|
266
|
-
<!--
|
|
282
|
+
<!-- curation:on -->
|
|
267
283
|
### Phase 1b: Load Decisions Index
|
|
268
|
-
<!--
|
|
284
|
+
<!-- curation:off -->
|
|
269
285
|
### Phase 1b: Load Context
|
|
270
|
-
<!--
|
|
286
|
+
<!-- curation:end -->
|
|
271
287
|
|
|
272
|
-
<!--
|
|
288
|
+
<!-- curation:on -->
|
|
273
289
|
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
|
|
274
|
-
<!--
|
|
290
|
+
<!-- curation:off -->
|
|
275
291
|
**Produces:** FEATURE_KNOWLEDGE, FEATURE_KNOWLEDGE_RULES, COMPLIANCE_FRAMEWORKS (carried from Step 0b)
|
|
276
|
-
<!--
|
|
292
|
+
<!-- curation:end -->
|
|
277
293
|
|
|
278
294
|
{{decisions_load()}}
|
|
279
|
-
<!--
|
|
295
|
+
<!-- curation:on -->
|
|
280
296
|
This produces a compact index of active ADR/PF entries. Pass `DECISIONS_CONTEXT` to all Review agents as one shared slice, cut over the diff's files. Review agents use `devflow:apply-decisions` to Read full entry bodies on demand.
|
|
281
297
|
|
|
282
|
-
<!--
|
|
298
|
+
<!-- curation:end -->
|
|
283
299
|
{{knowledge_load()}}
|
|
284
300
|
|
|
285
|
-
<!--
|
|
301
|
+
<!-- curation:on -->
|
|
286
302
|
Pass `FEATURE_KNOWLEDGE` to all Review agents alongside `DECISIONS_CONTEXT`.
|
|
287
|
-
<!--
|
|
303
|
+
<!-- curation:off -->
|
|
288
304
|
Pass `FEATURE_KNOWLEDGE` to all Review agents.
|
|
289
|
-
<!--
|
|
305
|
+
<!-- curation:end -->
|
|
290
306
|
|
|
291
307
|
### Phase 2: Run Reviews (Parallel)
|
|
292
308
|
|
|
293
309
|
**Produces:** REVIEW_FOCUS_OUTPUTS
|
|
294
|
-
<!--
|
|
310
|
+
<!-- curation:on -->
|
|
295
311
|
**Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
296
|
-
<!--
|
|
312
|
+
<!-- curation:off -->
|
|
297
313
|
**Requires:** DIFF_RANGE, REVIEW_DIR, TIMESTAMP, FEATURE_KNOWLEDGE, PR_DESCRIPTION, PRIOR_RESOLUTIONS, REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
298
|
-
<!--
|
|
314
|
+
<!-- curation:end -->
|
|
299
315
|
|
|
300
|
-
Spawn Review agents **in a single message**,
|
|
316
|
+
Spawn Review agents **in a single message**, one per focus in REVIEW_FOCUS_LIST (max 20 per worktree):
|
|
301
317
|
|
|
302
|
-
- `code`: the 8 core reviews on the full `diff.patch
|
|
318
|
+
- `code`: the 8 core reviews on the full `diff.patch` (lean keeps 3), plus the language and conditional focuses Phase 1 added.
|
|
303
319
|
- `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.
|
|
304
320
|
|
|
305
321
|
| Focus | Runs | Pattern Skill | DIFF_FILE |
|
|
@@ -325,7 +341,7 @@ Spawn Review agents **in a single message**, for the focus set `DIFF_CLASS` sele
|
|
|
325
341
|
| documentation | conditional | devflow:documentation | diff.patch |
|
|
326
342
|
| compliance | diff-driven | devflow:compliance | diff.patch |
|
|
327
343
|
|
|
328
|
-
Review agent count: `code` runs 8 core
|
|
344
|
+
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.
|
|
329
345
|
|
|
330
346
|
{{compliance_focus_inject()}}
|
|
331
347
|
|
|
@@ -338,31 +354,31 @@ PR: #{pr_number}, Base: {base_branch}
|
|
|
338
354
|
WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
339
355
|
DIFF_FILE: {diff_file} (absolute: {REVIEW_DIR}/diff.patch, or {REVIEW_DIR}/diff-{focus}.patch for a language focus, per the table)
|
|
340
356
|
DIFF_RANGE: {DIFF_RANGE} (information only)
|
|
341
|
-
<!--
|
|
357
|
+
<!-- curation:on -->
|
|
342
358
|
DECISIONS_CONTEXT: {decisions_context}
|
|
343
|
-
<!--
|
|
359
|
+
<!-- curation:end -->
|
|
344
360
|
FEATURE_KNOWLEDGE: {feature_knowledge}
|
|
345
361
|
PR_DESCRIPTION: <pr-description>{pr_description}</pr-description>
|
|
346
362
|
PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
|
|
347
363
|
{COMPLIANCE_FOCUS_DIRECTIVE} (compliance focus only)
|
|
348
364
|
If PRIOR_RESOLUTIONS is not (none), follow Cross-Cycle Awareness in review.md.
|
|
349
|
-
<!--
|
|
365
|
+
<!-- curation:on -->
|
|
350
366
|
Follow devflow:apply-decisions to scan the index and Read full ADR/PF bodies on demand.
|
|
351
|
-
<!--
|
|
367
|
+
<!-- curation:end -->
|
|
352
368
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specific patterns and anti-patterns inform findings.
|
|
353
369
|
IMPORTANT: Write report to {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/{focus}.md using Write tool"
|
|
354
370
|
```
|
|
355
371
|
|
|
356
|
-
In multi-worktree mode, process worktrees **sequentially
|
|
372
|
+
In multi-worktree mode, process worktrees **sequentially**: Phases 1-4 for one worktree, then the next.
|
|
357
373
|
|
|
358
374
|
### Phase 3: Synthesis → Review Comment (Sequential)
|
|
359
375
|
|
|
360
376
|
**Produces:** REVIEW_SUMMARY, PR_COMMENT
|
|
361
|
-
**Requires:** REVIEW_FOCUS_OUTPUTS, REVIEW_DIR, PR_INFO
|
|
377
|
+
**Requires:** REVIEW_FOCUS_OUTPUTS, REVIEW_DIR, PR_INFO, GATE_LEVEL, REVIEW_FOCUS_LIST
|
|
362
378
|
|
|
363
379
|
**WAIT** for Phase 2. For each worktree, run steps 3a and 3b in sequence:
|
|
364
380
|
|
|
365
|
-
**Step 3a — Synthesize agent** per worktree
|
|
381
|
+
**Step 3a — Synthesize agent** per worktree:
|
|
366
382
|
```
|
|
367
383
|
Agent(subagent_type="Synthesize", run_in_background=false):
|
|
368
384
|
"Mode: review
|
|
@@ -370,6 +386,8 @@ WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
|
370
386
|
REVIEW_BASE_DIR: {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}
|
|
371
387
|
TIMESTAMP: {timestamp}
|
|
372
388
|
CYCLE_NUMBER: {cycle_number}
|
|
389
|
+
GATE_LEVEL: {GATE_LEVEL}
|
|
390
|
+
FOCUSES: {REVIEW_FOCUS_LIST}
|
|
373
391
|
PRIOR_RESOLUTIONS: <prior-resolution-summary>{prior_resolutions}</prior-resolution-summary>
|
|
374
392
|
Include Convergence Status section in review-summary.md.
|
|
375
393
|
Aggregate findings, determine merge recommendation.
|
|
@@ -394,46 +412,37 @@ Posts the consolidated review-summary comment (marker-deduped by the operation o
|
|
|
394
412
|
**Requires:** BRANCH_INFO, REVIEW_DIR
|
|
395
413
|
|
|
396
414
|
Per worktree, after successful completion:
|
|
397
|
-
1.
|
|
415
|
+
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.
|
|
398
416
|
2. Display results from all agents:
|
|
399
417
|
- Merge recommendation (from Synthesize agent)
|
|
400
418
|
- Issue counts by category (🔴 blocking / ⚠️ should-fix / ℹ️ pre-existing)
|
|
401
419
|
- Review comment status: POSTED / POSTED+TRUNCATED (body exceeded 60k after redaction) / SKIPPED (D7 dedup) / DEGRADED (from Git)
|
|
402
420
|
- Publication status: FULL (private repo) | FULL (config override) | STUB (public repository) | OFF (publication disabled by config) | STUB (visibility undeterminable) | STUB (evidence policy) (from Git agent)
|
|
421
|
+
- Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned
|
|
403
422
|
- Artifact paths
|
|
404
423
|
|
|
405
|
-
In multi-worktree mode, report results per worktree.
|
|
406
|
-
|
|
407
424
|
## Architecture
|
|
408
425
|
|
|
409
426
|
```
|
|
410
|
-
/code-review
|
|
427
|
+
/code-review
|
|
411
428
|
│
|
|
412
|
-
├─ Phase 0: Worktree Discovery & Pre-flight
|
|
413
|
-
│ ├─ Step
|
|
414
|
-
│ ├─ Step 0b: Resolve the compliance lens
|
|
415
|
-
│ ├─ Step 0c: Git agent (ensure-pr-ready) per worktree [parallel]
|
|
416
|
-
│ ├─ Step 0d: Incremental detection + timestamp setup per worktree
|
|
417
|
-
│ ├─ Step 0e-i: Load prior resolution-summary.md
|
|
418
|
-
│ ├─ Step 0e-ii: Convergence assessment (warn if FP ratio > 70%)
|
|
419
|
-
│ └─ Step 0f: Resolve REVIEW_PUBLICATION per worktree (publication gate)
|
|
429
|
+
├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0f (Git agent per worktree, parallel)
|
|
430
|
+
│ ├─ Step 0b: Resolve the compliance lens and gate level
|
|
420
431
|
│
|
|
421
|
-
├─ Per worktree (SEQUENTIAL
|
|
432
|
+
├─ Per worktree (SEQUENTIAL):
|
|
422
433
|
│ │
|
|
423
434
|
│ ├─ Phase 1: Analyze changed files
|
|
424
435
|
│ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
|
|
425
|
-
│ │ ├─ Choose the focuses
|
|
426
|
-
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
436
|
+
│ │ ├─ Choose the focuses
|
|
437
|
+
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
427
438
|
│ │
|
|
428
|
-
│ ├─ Phase 2: Reviews (PARALLEL within worktree)
|
|
429
|
-
│ │ ├─ code:
|
|
430
|
-
│ │ │ consistency, regression, testing, reliability (diff.patch)
|
|
431
|
-
│ │ ├─ code: + language (diff-{focus}.patch) and conditional Review agents
|
|
439
|
+
│ ├─ Phase 2: Reviews (PARALLEL within worktree), one per REVIEW_FOCUS_LIST focus
|
|
440
|
+
│ │ ├─ code: core (diff.patch), language (diff-{focus}.patch), conditional
|
|
432
441
|
│ │ └─ docs-only / tests-only / lockfile-only: the reduced set (diff.patch)
|
|
433
442
|
│ │
|
|
434
443
|
│ ├─ Phase 3: Synthesis → Review Comment (SEQUENTIAL within worktree)
|
|
435
444
|
│ │ ├─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
|
|
436
|
-
│ │ └─ Step 3b: Git agent (post-review-summary
|
|
445
|
+
│ │ └─ Step 3b: Git agent (post-review-summary)
|
|
437
446
|
│ │
|
|
438
447
|
│ └─ Phase 4: Write .last-review-head + display results
|
|
439
448
|
```
|
|
@@ -442,31 +451,26 @@ In multi-worktree mode, report results per worktree.
|
|
|
442
451
|
|
|
443
452
|
| Case | Handling |
|
|
444
453
|
|------|----------|
|
|
445
|
-
| `--full` in multi-worktree mode | Applies to all worktrees (global modifier) |
|
|
446
|
-
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7); a re-review in the same cycle (different timestamp) posts its own comment. The marker's format belongs to the operation
|
|
447
|
-
|
|
|
448
|
-
|
|
|
449
|
-
|
|
|
450
|
-
|
|
|
451
|
-
|
|
|
452
|
-
| A
|
|
453
|
-
|
|
|
454
|
-
| Path listing above about 40 lines | The count is printed; `paths.txt` is read in ranges of about 40 lines |
|
|
454
|
+
| `--full` in multi-worktree mode | Applies to all worktrees (global modifier). It sets the diff range, never the gate level |
|
|
455
|
+
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7); a re-review in the same cycle (different timestamp) posts its own comment. The marker's format belongs to the operation |
|
|
456
|
+
| Docs-only diff | Its Step 1.1 set, narrowed by level |
|
|
457
|
+
| Tests-only diff | Its Step 1.1 set, narrowed by level |
|
|
458
|
+
| Lockfile-only diff | Its Step 1.1 set, narrowed by level |
|
|
459
|
+
| Mixed non-code diff | The union of the matching sets |
|
|
460
|
+
| A path matching no class pattern, or an empty path list | `code` (fail-safe) |
|
|
461
|
+
| A file moved across classes | `--no-renames` lists both paths, so a code path makes the diff `code` |
|
|
462
|
+
| Path listing above about 40 lines | Read in ranges (Step 1.1) |
|
|
455
463
|
| Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
|
|
456
|
-
| Public repo (`auto` mode) | Git agent probes visibility, posts counts-only STUB comment; full report stays local |
|
|
457
464
|
| `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 |
|
|
458
465
|
|
|
459
466
|
## Backwards Compatibility
|
|
460
467
|
|
|
461
|
-
- **
|
|
462
|
-
- **Legacy flat layout**: If `{worktree}/.devflow/docs/reviews/{branch-slug}/` contains flat `*.md` files (no timestamped subdirectories), new runs create timestamped subdirectories. Old flat files remain untouched.
|
|
468
|
+
- **Gate level**: `full` runs the sets named here; the default `standard` and `lean` narrow them. `devflow gates --set full` keeps them.
|
|
463
469
|
|
|
464
470
|
## Principles
|
|
465
471
|
|
|
466
|
-
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
|
|
472
|
+
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
|
|
467
473
|
2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
|
|
468
|
-
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1;
|
|
469
|
-
4. **
|
|
470
|
-
5. **
|
|
471
|
-
6. **Incremental by default** - Only review new changes unless `--full` specified
|
|
472
|
-
7. **Auto-discover worktrees** - One command handles all reviewable branches
|
|
474
|
+
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; its writes print nothing
|
|
475
|
+
4. **Honest reporting** - Display agent outputs directly
|
|
476
|
+
5. **Incremental by default** - Only review new changes unless `--full` specified
|
|
@@ -34,16 +34,16 @@ $ARGUMENTS
|
|
|
34
34
|
|
|
35
35
|
## Phases
|
|
36
36
|
|
|
37
|
-
<!--
|
|
37
|
+
<!-- curation:on -->
|
|
38
38
|
### Phase 1: Load Decisions Index (Orchestrator-Local)
|
|
39
|
-
<!--
|
|
39
|
+
<!-- curation:off -->
|
|
40
40
|
### Phase 1: Resolve Settings
|
|
41
|
-
<!--
|
|
41
|
+
<!-- curation:end -->
|
|
42
42
|
|
|
43
|
-
<!--
|
|
43
|
+
<!-- curation:on -->
|
|
44
44
|
**Produces:** DECISIONS_CONTEXT
|
|
45
45
|
|
|
46
|
-
<!--
|
|
46
|
+
<!-- curation:end -->
|
|
47
47
|
{{settings.settings_resolve()}}
|
|
48
48
|
|
|
49
49
|
From the same line: {{compliance.compliance_frameworks()}}
|
|
@@ -53,18 +53,18 @@ From the same line: {{compliance.compliance_frameworks()}}
|
|
|
53
53
|
Phase 7 passes `COMPLIANCE_DIRECTIVE` to the Code agent that implements the fix, on a line of its own.
|
|
54
54
|
|
|
55
55
|
{{decisions_load()}}
|
|
56
|
-
<!--
|
|
56
|
+
<!-- curation:on -->
|
|
57
57
|
The orchestrator uses `DECISIONS_CONTEXT` locally when generating hypotheses (Phase 2) — prior pitfalls and decisions can suggest specific root causes to investigate. Follow `devflow:apply-decisions` to Read full entry bodies on demand. **Do NOT pass `DECISIONS_CONTEXT` to Explore investigators** — decisions context stays in the orchestrator; investigators examine code directly.
|
|
58
58
|
|
|
59
|
-
<!--
|
|
59
|
+
<!-- curation:end -->
|
|
60
60
|
**No up-front feature knowledge load** — debug investigation workers read code directly to avoid confirmation bias. Feature knowledge is only written back at the end if the investigation surfaced durable, cross-cutting knowledge.
|
|
61
61
|
|
|
62
62
|
### Phase 2: Context Gathering
|
|
63
63
|
|
|
64
64
|
**Produces:** HYPOTHESES, BUG_CONTEXT
|
|
65
|
-
<!--
|
|
65
|
+
<!-- curation:on -->
|
|
66
66
|
**Requires:** DECISIONS_CONTEXT
|
|
67
|
-
<!--
|
|
67
|
+
<!-- curation:end -->
|
|
68
68
|
|
|
69
69
|
If `COMMAND_INPUT` opens with a candidate issue reference, fetch the issue:
|
|
70
70
|
|
|
@@ -211,9 +211,9 @@ Ask user via AskUserQuestion: "Want me to implement this fix?"
|
|
|
211
211
|
TASK_DESCRIPTION: Implement the fix for this root cause: {bug description}
|
|
212
212
|
EXECUTION_PLAN: {Root Cause, Key Findings and Recommended Fix from Phase 6, with their file:line references}
|
|
213
213
|
PUSH: false
|
|
214
|
-
<!--
|
|
214
|
+
<!-- curation:on -->
|
|
215
215
|
DECISIONS_CONTEXT: {decisions_context}
|
|
216
|
-
<!--
|
|
216
|
+
<!-- curation:end -->
|
|
217
217
|
FEATURE_KNOWLEDGE: (none)
|
|
218
218
|
{COMPLIANCE_DIRECTIVE}"
|
|
219
219
|
```
|
|
@@ -227,11 +227,11 @@ Ask user via AskUserQuestion: "Want me to implement this fix?"
|
|
|
227
227
|
```
|
|
228
228
|
/debug (orchestrator)
|
|
229
229
|
│
|
|
230
|
-
<!--
|
|
230
|
+
<!-- curation:on -->
|
|
231
231
|
├─ Phase 1: Load Decisions Index (Orchestrator-Local)
|
|
232
|
-
<!--
|
|
232
|
+
<!-- curation:off -->
|
|
233
233
|
├─ Phase 1: Resolve Settings
|
|
234
|
-
<!--
|
|
234
|
+
<!-- curation:end -->
|
|
235
235
|
│ └─ No up-front feature knowledge load (avoids confirmation bias in investigators)
|
|
236
236
|
│
|
|
237
237
|
├─ Phase 2: Context gathering
|