devflow-kit 3.7.0 → 3.9.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 +479 -1
- package/README.md +15 -15
- package/dist/agents/code.md +6 -8
- package/dist/agents/design.md +1 -1
- package/dist/agents/fix.md +7 -8
- package/dist/agents/git.md +3 -3
- package/dist/agents/harden.md +1 -1
- package/dist/agents/refactor.md +2 -4
- package/dist/agents/review.md +4 -4
- package/dist/agents/skim.md +2 -2
- package/dist/agents/triage.md +9 -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/curation.js +808 -0
- package/dist/cli/commands/gate-level-prompts.js +428 -0
- package/dist/cli/commands/gates.js +35 -11
- package/dist/cli/commands/init-seed.js +11 -8
- package/dist/cli/commands/init.js +244 -57
- package/dist/cli/commands/memory.js +60 -13
- package/dist/cli/commands/prompt-io.js +37 -0
- package/dist/cli/commands/uninstall.js +157 -17
- package/dist/cli.js +2 -2
- package/dist/commands/bug-analysis.md +25 -36
- package/dist/commands/code-review.md +40 -44
- package/dist/commands/debug.md +5 -5
- package/dist/commands/dynamic-build.md +26 -25
- 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 +53 -82
- package/dist/commands/plan.md +6 -6
- package/dist/commands/release.md +5 -5
- package/dist/commands/research.md +6 -6
- package/dist/commands/resolve.md +39 -41
- package/dist/commands/self-review.md +5 -13
- package/dist/core/area-pause-notice.js +44 -0
- 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 +35 -0
- package/dist/core/curation-move.js +35 -0
- package/dist/core/curation-queue-cleanup.js +135 -0
- package/dist/core/curation-store.js +99 -0
- package/dist/core/{learning-variants.js → curation-variants.js} +65 -41
- package/dist/core/echo-value.js +11 -5
- package/dist/core/evidence-policy.js +11 -9
- package/dist/core/feature-switch.js +95 -19
- package/dist/core/fs-atomic.js +1 -1
- package/dist/core/gate-level.js +10 -2
- 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 +58 -14
- package/dist/core/migrations.js +1 -13
- package/dist/core/observations.js +2 -2
- package/dist/core/plugins.js +19 -19
- 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 +159 -0
- package/dist/core/tracker.js +1 -1
- package/dist/{learning-off → curation-off}/agents/code.md +6 -8
- package/dist/{learning-off → curation-off}/agents/fix.md +7 -8
- package/dist/{learning-off → curation-off}/agents/refactor.md +2 -4
- package/dist/{learning-off → curation-off}/agents/review.md +3 -3
- package/dist/{learning-off → curation-off}/agents/triage.md +8 -1
- package/dist/{learning-off → curation-off}/commands/bug-analysis.md +20 -31
- package/dist/{learning-off → curation-off}/commands/code-review.md +37 -41
- package/dist/{learning-off → curation-off}/commands/debug.md +2 -2
- package/dist/{learning-off → curation-off}/commands/dynamic-build.md +23 -22
- package/dist/{learning-off → curation-off}/commands/explore.md +2 -2
- package/dist/{learning-off → curation-off}/commands/implement.md +50 -79
- package/dist/{learning-off → curation-off}/commands/plan.md +2 -2
- package/dist/{learning-off → curation-off}/commands/resolve.md +36 -38
- package/dist/{learning-off → curation-off}/commands/self-review.md +2 -10
- package/dist/hud/components/{learning-counts.js → curation-counts.js} +63 -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/post-resolution-summary.md +12 -11
- package/dist/skills/git/references/pr/post-review-summary.md +12 -11
- package/dist/skills/git/references/pr/update-pr-evidence.md +2 -2
- package/dist/skills/git/references/pr/validate-branch.md +8 -5
- package/dist/skills/git/references/publication-gate.md +6 -7
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/github/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/jira/manage-debt.md +6 -2
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +13 -5
- package/dist/skills/git/references/tracker/linear/manage-debt.md +6 -2
- package/dist/targets/claude-code/{learning-install.js → curation-install.js} +85 -65
- 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 +11 -11
- package/src/assets/agents/code.mds +6 -6
- package/src/assets/agents/curate.md +8 -8
- package/src/assets/agents/debug.mds +6 -6
- package/src/assets/agents/design.mds +18 -18
- package/src/assets/agents/evaluate.md +6 -12
- package/src/assets/agents/fix.mds +7 -6
- package/src/assets/agents/git.mds +3 -3
- 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 +43 -43
- package/src/assets/agents/skim.mds +11 -11
- package/src/assets/agents/triage.mds +29 -22
- package/src/assets/agents/validate.md +30 -50
- package/src/assets/commands/_partials/_decisions.mds +22 -20
- 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 +7 -7
- package/src/assets/commands/bug-analysis.mds +37 -48
- package/src/assets/commands/code-review.mds +53 -57
- package/src/assets/commands/debug.mds +14 -14
- package/src/assets/commands/dynamic-build.mds +38 -37
- 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 +77 -98
- package/src/assets/commands/plan.mds +27 -27
- package/src/assets/commands/release.mds +12 -12
- package/src/assets/commands/research.mds +19 -19
- package/src/assets/commands/resolve.mds +66 -60
- package/src/assets/commands/self-review.mds +20 -20
- package/src/assets/mds/git/_ops.mds +9 -2
- package/src/assets/mds/git/_ops_pr.mds +21 -11
- package/src/assets/mds/git/_ops_steps.mds +20 -4
- package/src/assets/mds/git/_pr.mds +21 -18
- package/src/assets/mds/git/_references.mds +6 -7
- package/src/assets/mds/tracker/_github.mds +1 -4
- package/src/assets/mds/tracker/_jira.mds +1 -4
- package/src/assets/mds/tracker/_linear.mds +1 -4
- package/src/assets/rules/quality.md +1 -0
- package/src/assets/scripts/ci-wait.cjs +389 -92
- package/src/assets/scripts/hooks/background-memory-update +81 -3
- 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 +176 -51
- package/src/assets/scripts/hooks/json-parse +1 -1
- package/src/assets/scripts/hooks/lib/curation-move.cjs +1582 -0
- package/src/assets/scripts/hooks/lib/{learning-store.cjs → curation-store.cjs} +308 -122
- 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 +42 -22
- package/src/assets/scripts/hooks/lib/tracked-areas.cjs +452 -0
- package/src/assets/scripts/hooks/memory-permission +10 -2
- package/src/assets/scripts/hooks/memory-worker +12 -1
- package/src/assets/scripts/hooks/pre-compact-memory +17 -16
- package/src/assets/scripts/hooks/queue-append +444 -102
- package/src/assets/scripts/hooks/resolve-project-root +2 -2
- package/src/assets/scripts/hooks/session-start-context +198 -72
- package/src/assets/scripts/hooks/session-start-memory +42 -43
- package/src/assets/scripts/lib/project-config.cjs +12 -5
- package/src/assets/scripts/pr-evidence.cjs +5 -2
- package/src/assets/scripts/resolve-base.cjs +1043 -0
- package/src/assets/scripts/resolve-settings.cjs +283 -45
- package/src/assets/scripts/verify-evidence.cjs +307 -75
- package/src/assets/skills/agent-references/SKILL.md +11 -2
- package/src/assets/skills/agent-references/references/commands/implement-levels.md +29 -0
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +6 -4
- package/src/assets/skills/agent-references/references/commands/resolve-levels.md +25 -0
- package/src/assets/skills/agent-references/references/synthesize/review.md +4 -4
- package/src/assets/skills/agent-references/references/triage/severity-tiers.md +43 -0
- package/src/assets/skills/agent-references/references/validate/passed-alone.md +14 -0
- 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/cli/commands/learning.js +0 -554
- 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
|
@@ -3,7 +3,7 @@ description: Proactive bug finding with static and semantic analysis — hunts r
|
|
|
3
3
|
---
|
|
4
4
|
# Bug Analysis Command
|
|
5
5
|
|
|
6
|
-
Run a proactive bug analysis on the current branch by combining static analysis tools with parallel semantic analyzers, then synthesizing results into an actionable bug report.
|
|
6
|
+
Run a proactive bug analysis on the current branch by combining static analysis tools with parallel semantic analyzers, then synthesizing results into an actionable bug report.
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
@@ -55,16 +55,16 @@ Agent(subagent_type="Git", run_in_background=false):
|
|
|
55
55
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
56
56
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
57
57
|
Validate branch, commit if needed, push, create PR if needed.
|
|
58
|
-
Return: branch, base_branch, branch-slug, PR#"
|
|
58
|
+
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
**Extract from response:** `branch`, `base_branch`, `branch_slug`, `pr_number`.
|
|
61
|
+
**Extract from response:** `branch`, `base_branch`, `base_ref`, `branch_slug`, `pr_number`. 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.
|
|
62
62
|
|
|
63
63
|
**Fetch PR body** (after extracting `pr_number`):
|
|
64
64
|
```bash
|
|
65
65
|
PR_DESCRIPTION=$(gh pr view {pr_number} --json body --jq '.body' 2>/dev/null || echo "(none)")
|
|
66
66
|
```
|
|
67
|
-
If `pr_number` is absent
|
|
67
|
+
If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
68
68
|
|
|
69
69
|
### Phase 2: Static Analysis
|
|
70
70
|
|
|
@@ -75,14 +75,15 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
75
75
|
**Produces:** DIFF_RANGE, ANALYSIS_DIR
|
|
76
76
|
**Requires:** BRANCH_INFO
|
|
77
77
|
|
|
78
|
-
1. Check `{
|
|
78
|
+
1. Check `{gd}/devflow/bug-analysis/{branch-slug}/.last-analysis-head`, `{gd}` being what `git -C "{worktree}" rev-parse --absolute-git-dir` prints:
|
|
79
79
|
- **If exists AND `--full` NOT set:**
|
|
80
|
-
-
|
|
81
|
-
- Verify reachable: `git cat-file -t {sha}`
|
|
80
|
+
- The stored analysis 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
|
|
81
|
+
- Verify reachable: `git -C "{worktree}" cat-file -t {sha}` must print `commit`; if not (rebase invalidated SHA), take the full-range path
|
|
82
82
|
- If SHA == current HEAD → "No new commits since last analysis. Use --full for a full re-analysis." Stop.
|
|
83
83
|
- Set `DIFF_RANGE` to `{sha}...HEAD`
|
|
84
|
-
- **
|
|
85
|
-
-
|
|
84
|
+
- **Full-range path (no marker, or `--full`):**
|
|
85
|
+
- Stop as for a (rejected) Base line unless `base_ref` is 40 or 64 hex.
|
|
86
|
+
- Set `DIFF_RANGE` to `{base_ref}...HEAD`
|
|
86
87
|
2. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
|
|
87
88
|
3. Create timestamped analysis directory: `mkdir -p "{worktree}/.devflow/docs/bug-analysis/{branch-slug}/{timestamp}/"`
|
|
88
89
|
4. Set `ANALYSIS_DIR` to that path.
|
|
@@ -95,7 +96,7 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
95
96
|
CHANGED_FILES=$(git diff --name-only {DIFF_RANGE})
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
Store
|
|
99
|
+
Store as `CHANGED_FILES`; Steps 2d and Phase 4 read it. A non-zero diff exit stops.
|
|
99
100
|
|
|
100
101
|
If output is empty → "No changes to analyze." Stop.
|
|
101
102
|
|
|
@@ -124,7 +125,7 @@ Skip if `--no-static` flag provided or all tools unavailable.
|
|
|
124
125
|
|
|
125
126
|
Run available tools on the changed files (from `CHANGED_FILES` computed in Step 2b).
|
|
126
127
|
|
|
127
|
-
**Semgrep and Snyk run in parallel** — launch both in the background, then wait for both before proceeding to CodeQL. CodeQL is conditional and sequential
|
|
128
|
+
**Semgrep and Snyk run in parallel** — launch both in the background, then wait for both before proceeding to CodeQL. CodeQL is conditional and sequential.
|
|
128
129
|
|
|
129
130
|
**Semgrep** (if available):
|
|
130
131
|
```bash
|
|
@@ -135,11 +136,9 @@ Parse SARIF output → extract findings.
|
|
|
135
136
|
|
|
136
137
|
**Snyk Code** (if available):
|
|
137
138
|
```bash
|
|
138
|
-
#
|
|
139
|
-
# Per-file invocation via xargs would invoke snyk O(n) times and --file is for dependency scanning, not source code.
|
|
139
|
+
# One project-level scan (a per-file xargs run would invoke snyk O(n) times; --file is for dependency scans).
|
|
140
140
|
SNYK_SARIF=$(timeout 300 snyk code test --sarif 2>/dev/null)
|
|
141
|
-
# Programmatic filter: keep only results whose file path
|
|
142
|
-
# This is defense-in-depth — filtering at the data layer before the LLM agent sees any output.
|
|
141
|
+
# Programmatic filter: keep only results whose file path is in CHANGED_FILES — defense-in-depth, before the LLM agent sees any output.
|
|
143
142
|
SNYK_FILTERED=$(echo "$SNYK_SARIF" | jq --argjson files "$(echo "$CHANGED_FILES" | jq -R . | jq -s .)" \
|
|
144
143
|
'.runs[].results |= map(select(.locations[].physicalLocation.artifactLocation.uri as $uri | $files | index($uri) != null))' \
|
|
145
144
|
2>/dev/null || echo "$SNYK_SARIF")
|
|
@@ -165,7 +164,7 @@ trap - EXIT INT TERM
|
|
|
165
164
|
```
|
|
166
165
|
Parse `CODEQL_SARIF` → extract findings. If database creation fails, `CODEQL_EXIT` is non-zero — skip CodeQL findings and note it. The `trap` guarantees cleanup on SIGTERM/SIGINT/EXIT so orphaned temp directories do not accumulate across interrupted sessions.
|
|
167
166
|
|
|
168
|
-
**Normalize** all findings to unified table, cap at top 50 by severity. Truncate each Description entry to 200 characters maximum
|
|
167
|
+
**Normalize** all findings to unified table, cap at top 50 by severity. Truncate each Description entry to 200 characters maximum:
|
|
169
168
|
|
|
170
169
|
| Tool | File:Line | CWE | Severity | Title | Description |
|
|
171
170
|
|------|-----------|-----|----------|-------|-------------|
|
|
@@ -181,19 +180,19 @@ If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
|
|
|
181
180
|
|
|
182
181
|
#### Decisions Index
|
|
183
182
|
|
|
184
|
-
**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
|
|
183
|
+
**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:
|
|
185
184
|
|
|
186
185
|
```bash
|
|
187
186
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
188
187
|
```
|
|
189
188
|
|
|
190
|
-
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>
|
|
189
|
+
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.
|
|
191
190
|
|
|
192
191
|
The accepted line is the only source of these values.
|
|
193
192
|
|
|
194
193
|
### Load DECISIONS_CONTEXT
|
|
195
194
|
|
|
196
|
-
When the settings line says `
|
|
195
|
+
When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
197
196
|
|
|
198
197
|
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`):
|
|
199
198
|
|
|
@@ -207,11 +206,11 @@ Line 1 is the checkout's toplevel, line 2 the common git directory. A git older
|
|
|
207
206
|
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
208
207
|
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
209
208
|
|
|
210
|
-
This is the rule the
|
|
209
|
+
This is the rule the curation hooks apply, so you read the index the Curate agent writes.
|
|
211
210
|
|
|
212
211
|
**Step 1 — Read the pre-rendered index:**
|
|
213
212
|
|
|
214
|
-
Attempt to read `{ledger}/.devflow/
|
|
213
|
+
Attempt to read `{ledger}/.devflow/curation/index.md`.
|
|
215
214
|
|
|
216
215
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
217
216
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
@@ -355,13 +354,14 @@ Output: {ANALYSIS_DIR}/bug-analysis-summary.md"
|
|
|
355
354
|
|
|
356
355
|
**Requires:** BRANCH_INFO, ANALYSIS_DIR
|
|
357
356
|
|
|
358
|
-
1.
|
|
357
|
+
1. In one Bash call run `M="$(git -C "{worktree}" rev-parse --absolute-git-dir)/devflow/bug-analysis/{branch-slug}" && mkdir -p "$M" && git -C "{worktree}" rev-parse HEAD > "$M/.last-analysis-head"`. A failed or refused write never stops the run and is not retried another way.
|
|
359
358
|
2. Report to user:
|
|
360
359
|
|
|
361
360
|
```
|
|
362
361
|
## Bug Analysis Complete
|
|
363
362
|
|
|
364
363
|
**Branch**: {branch} -> {base_branch}
|
|
364
|
+
{any base `TRACEABILITY: DEGRADED` line from Phase 1, as returned}
|
|
365
365
|
**Analysis**: {ANALYSIS_DIR}
|
|
366
366
|
|
|
367
367
|
### Risk Assessment: {risk_level}
|
|
@@ -397,11 +397,7 @@ Run `/resolve` to process and fix these findings.
|
|
|
397
397
|
│ └─ Git agent (ensure-pr-ready)
|
|
398
398
|
│
|
|
399
399
|
├─ Phase 2: Static Analysis
|
|
400
|
-
│
|
|
401
|
-
│ ├─ Step 2b: Check changed files (stop if none)
|
|
402
|
-
│ ├─ Step 2c: Tool availability check
|
|
403
|
-
│ └─ Step 2d: Tiered static analysis (semgrep → snyk → codeql)
|
|
404
|
-
│ Write static-findings.md
|
|
400
|
+
│ └─ 2a incremental range, 2b changed files (stop if none), 2c tools, 2d semgrep → snyk → codeql
|
|
405
401
|
│
|
|
406
402
|
├─ Phase 3: Context Loading
|
|
407
403
|
│ ├─ index.md (pre-rendered) → DECISIONS_CONTEXT
|
|
@@ -412,10 +408,7 @@ Run `/resolve` to process and fix these findings.
|
|
|
412
408
|
│ └─ Detect active focuses (security + functional always; integration + usability conditional)
|
|
413
409
|
│
|
|
414
410
|
├─ Phase 5: Bug Analysis (PARALLEL)
|
|
415
|
-
│
|
|
416
|
-
│ ├─ Debug agent: functional
|
|
417
|
-
│ ├─ Debug agent: integration (conditional)
|
|
418
|
-
│ └─ Debug agent: usability (conditional)
|
|
411
|
+
│ └─ Debug agent per active focus (security also reads STATIC_FINDINGS)
|
|
419
412
|
│
|
|
420
413
|
├─ Phase 6: Synthesis
|
|
421
414
|
│ └─ Synthesize agent (mode: bug-analysis)
|
|
@@ -431,16 +424,12 @@ Run `/resolve` to process and fix these findings.
|
|
|
431
424
|
|------|----------|
|
|
432
425
|
| No new commits since last analysis | Stop: "No new commits since last analysis. Use --full for a full re-analysis." |
|
|
433
426
|
| Rebase invalidates `.last-analysis-head` SHA | `git cat-file -t` check fails → fallback to full diff |
|
|
434
|
-
| Zero changed files in DIFF_RANGE | Stop: "No changes to analyze." |
|
|
427
|
+
| Zero changed files in DIFF_RANGE with exit 0 | Stop: "No changes to analyze." |
|
|
435
428
|
| Same-minute analysis collision | `mkdir` with seconds suffix (`YYYY-MM-DD_HHMMSS`) |
|
|
436
429
|
| All static tools unavailable | Warn, proceed with semantic-only analysis |
|
|
437
430
|
| `--no-static` flag | Skip Phase 2c and 2d entirely; `STATIC_FINDINGS=(none)` |
|
|
438
431
|
| `--full` flag | Bypass incremental detection (Step 2a), run full diff from base |
|
|
439
432
|
| CodeQL database creation fails | Skip CodeQL, note in output, continue with other tools |
|
|
440
|
-
| Static tool produces no findings | `STATIC_FINDINGS=(none)` — normal, proceed with semantic analysis |
|
|
441
|
-
| No plan artifact found | `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)` — proceed without acceptance criteria |
|
|
442
|
-
| `integration` focus skipped | Not spawned when only 1 directory changed |
|
|
443
|
-
| `usability` focus skipped | Not spawned when no UI files changed |
|
|
444
433
|
|
|
445
434
|
## Resolve Compatibility
|
|
446
435
|
|
|
@@ -3,7 +3,7 @@ description: Comprehensive branch review using specialized sub-agents for PR rea
|
|
|
3
3
|
---
|
|
4
4
|
# Code Review Command
|
|
5
5
|
|
|
6
|
-
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
6
|
+
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
@@ -27,21 +27,21 @@ Run a comprehensive code review of the current branch by spawning parallel revie
|
|
|
27
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
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
29
|
2. **If `--path` flag provided:** use only that worktree, skip discovery
|
|
30
|
-
**`--path` validation**:
|
|
31
|
-
3. **If only 1 reviewable worktree**: proceed as single-worktree flow
|
|
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
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
33
|
|
|
34
34
|
#### Step 0b: Resolve the compliance lens and gate level
|
|
35
35
|
|
|
36
36
|
**Produces:** COMPLIANCE_ACTIVE, COMPLIANCE_FRAMEWORKS, GATE_LEVEL
|
|
37
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
|
|
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
39
|
|
|
40
40
|
```bash
|
|
41
41
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
42
42
|
```
|
|
43
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>
|
|
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
45
|
|
|
46
46
|
The accepted line is the only source of these values.
|
|
47
47
|
|
|
@@ -97,20 +97,20 @@ PR_DESCRIPTION_GUIDANCE: {pr_description_guidance}
|
|
|
97
97
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
98
98
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
99
99
|
Validate branch, commit if needed, push, create PR if needed.
|
|
100
|
-
Return: branch, base_branch, branch-slug, PR#"
|
|
100
|
+
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
In multi-worktree mode, spawn all pre-flight agents **in a single message**.
|
|
104
104
|
|
|
105
105
|
**If BLOCKED:** In single-worktree mode, stop and report. In multi-worktree mode, report the failure but continue with other worktrees.
|
|
106
106
|
|
|
107
|
-
**Extract from response:** `branch`, `base_branch`, `branch_slug`, `pr_number` per worktree.
|
|
107
|
+
**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.
|
|
108
108
|
|
|
109
109
|
**Fetch PR body** (after extracting `pr_number`):
|
|
110
110
|
```bash
|
|
111
111
|
PR_DESCRIPTION=$(gh pr view {pr_number} --json body --jq '.body' 2>/dev/null || echo "(none)")
|
|
112
112
|
```
|
|
113
|
-
If `pr_number` is absent
|
|
113
|
+
If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
114
114
|
|
|
115
115
|
#### Step 0d: Incremental Detection & Timestamp Setup
|
|
116
116
|
|
|
@@ -120,26 +120,27 @@ If `pr_number` is absent or the command fails, set `PR_DESCRIPTION` to `(none)`.
|
|
|
120
120
|
For each worktree:
|
|
121
121
|
|
|
122
122
|
1. Generate timestamp: `YYYY-MM-DD_HHMM`. If directory already exists (same-minute collision), append seconds (`YYYY-MM-DD_HHMMSS`).
|
|
123
|
-
2.
|
|
124
|
-
3. Check if `{worktree}/.devflow/docs/reviews/{branch-slug}/.last-review-head` exists:
|
|
123
|
+
2. Check if `{gd}/devflow/reviews/{branch-slug}/.last-review-head` exists, `{gd}` being what `git -C "{worktree}" rev-parse --absolute-git-dir` prints:
|
|
125
124
|
- **If yes AND `--full` NOT set:**
|
|
126
|
-
-
|
|
127
|
-
- Verify reachable: `git -C {worktree} cat-file -t {sha}`
|
|
125
|
+
- 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
|
|
126
|
+
- Verify reachable: `git -C "{worktree}" cat-file -t {sha}` must print `commit` (else take the full-range path)
|
|
128
127
|
- Check if SHA == current HEAD → if so, skip review: "No new commits since last review. Use --full for a full re-review."
|
|
129
128
|
- Set `DIFF_RANGE` to `{last-review-sha}...HEAD`
|
|
130
|
-
- **
|
|
131
|
-
-
|
|
129
|
+
- **Full-range path (no marker, or `--full`):**
|
|
130
|
+
- Stop as for a (rejected) Base line unless `base_ref` is 40 or 64 hex.
|
|
131
|
+
- Set `DIFF_RANGE` to `{base_ref}...HEAD`
|
|
132
|
+
3. Create timestamped review directory: `mkdir -p {worktree}/.devflow/docs/reviews/{branch-slug}/{timestamp}/`
|
|
132
133
|
|
|
133
134
|
#### Step 0e-i: Load Prior Resolution and Count Cycles
|
|
134
135
|
|
|
135
136
|
**Produces:** PRIOR_RESOLUTIONS, CYCLE_NUMBER
|
|
136
137
|
**Requires:** BRANCH_INFO
|
|
137
138
|
|
|
138
|
-
For each worktree
|
|
139
|
-
1. List timestamped directories
|
|
140
|
-
2. Iterate once:
|
|
139
|
+
For each worktree:
|
|
140
|
+
1. List the timestamped directories: `ls -1d {worktree}/.devflow/docs/reviews/{branch-slug}/20* 2>/dev/null | sort -r`
|
|
141
|
+
2. Iterate once: count each directory containing `resolution-summary.md` as CYCLE_NUMBER; capture the first (newest) as PRIOR_DIR.
|
|
141
142
|
3. If CYCLE_NUMBER = 0: set PRIOR_RESOLUTIONS=(none), CYCLE_NUMBER=1, proceed.
|
|
142
|
-
4. Otherwise: set CYCLE_NUMBER = count + 1. Read `{PRIOR_DIR}/resolution-summary.md` as PRIOR_RESOLUTIONS.
|
|
143
|
+
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).
|
|
143
144
|
5. If `--full`: still load PRIOR_RESOLUTIONS.
|
|
144
145
|
|
|
145
146
|
#### Step 0e-ii: Convergence Assessment
|
|
@@ -157,7 +158,7 @@ MAX_REVIEW_CYCLES = 10
|
|
|
157
158
|
- `deferred_count` = the Deferred row value (= FIX_SEPARATE + TECH_DEBT); By Design and Escalated are excluded from the fp_ratio denominator
|
|
158
159
|
- fp_ratio = fp_count / (fp_count + fixed_count + deferred_count)
|
|
159
160
|
- If denominator = 0: fp_ratio = 0, skip warning
|
|
160
|
-
- If parsing fails: fp_ratio = 0, skip warning; note in output: "Warning: Could not parse Statistics table
|
|
161
|
+
- If parsing fails: fp_ratio = 0, skip warning; note in output: "Warning: Could not parse Statistics table. Convergence tracking degraded."
|
|
161
162
|
3. If fp_ratio > 0.7 AND CYCLE_NUMBER >= 3:
|
|
162
163
|
Warn in output: "⚠️ Convergence: {ratio}% false positives in cycle {N-1}. Consider merging or manual inspection."
|
|
163
164
|
Continue with review.
|
|
@@ -199,10 +200,11 @@ List the changed paths into `{REVIEW_DIR}/paths.txt` and print only the line cou
|
|
|
199
200
|
|
|
200
201
|
```bash
|
|
201
202
|
git -C "{WORKTREE_PATH}" diff --name-only --no-renames {DIFF_RANGE} > "{REVIEW_DIR}/paths.txt"
|
|
203
|
+
echo "exit=$?"
|
|
202
204
|
wc -l < "{REVIEW_DIR}/paths.txt"
|
|
203
205
|
```
|
|
204
206
|
|
|
205
|
-
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.
|
|
207
|
+
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.
|
|
206
208
|
|
|
207
209
|
Set `DIFF_CLASS` by these rules, in order; the first that decides wins:
|
|
208
210
|
|
|
@@ -276,7 +278,7 @@ Write `diff.patch` once per worktree, by redirect:
|
|
|
276
278
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} > "{REVIEW_DIR}/diff.patch"
|
|
277
279
|
```
|
|
278
280
|
|
|
279
|
-
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:
|
|
281
|
+
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:
|
|
280
282
|
|
|
281
283
|
```bash
|
|
282
284
|
git -C "{WORKTREE_PATH}" diff --no-color --no-ext-diff --no-textconv {DIFF_RANGE} -- '<pathspec>' ... > "{REVIEW_DIR}/diff-{focus}.patch"
|
|
@@ -300,7 +302,7 @@ The core, database, dependencies, documentation and compliance focuses, and ever
|
|
|
300
302
|
|
|
301
303
|
### Load DECISIONS_CONTEXT
|
|
302
304
|
|
|
303
|
-
When the settings line says `
|
|
305
|
+
When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
304
306
|
|
|
305
307
|
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`):
|
|
306
308
|
|
|
@@ -314,11 +316,11 @@ Line 1 is the checkout's toplevel, line 2 the common git directory. A git older
|
|
|
314
316
|
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
315
317
|
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
316
318
|
|
|
317
|
-
This is the rule the
|
|
319
|
+
This is the rule the curation hooks apply, so you read the index the Curate agent writes.
|
|
318
320
|
|
|
319
321
|
**Step 1 — Read the pre-rendered index:**
|
|
320
322
|
|
|
321
|
-
Attempt to read `{ledger}/.devflow/
|
|
323
|
+
Attempt to read `{ledger}/.devflow/curation/index.md`.
|
|
322
324
|
|
|
323
325
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
324
326
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|
|
@@ -425,7 +427,7 @@ Spawn Review agents **in a single message**, one per focus in REVIEW_FOCUS_LIST
|
|
|
425
427
|
| documentation | conditional | devflow:documentation | diff.patch |
|
|
426
428
|
| compliance | diff-driven | devflow:compliance | diff.patch |
|
|
427
429
|
|
|
428
|
-
Review agent count:
|
|
430
|
+
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.
|
|
429
431
|
|
|
430
432
|
**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:
|
|
431
433
|
|
|
@@ -451,7 +453,7 @@ Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE — feature-specifi
|
|
|
451
453
|
IMPORTANT: Write report to {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/{focus}.md using Write tool"
|
|
452
454
|
```
|
|
453
455
|
|
|
454
|
-
In multi-worktree mode, process worktrees **sequentially**:
|
|
456
|
+
In multi-worktree mode, process worktrees **sequentially**: Phases 1-4 for each.
|
|
455
457
|
|
|
456
458
|
### Phase 3: Synthesis → Review Comment (Sequential)
|
|
457
459
|
|
|
@@ -486,7 +488,7 @@ CYCLE_NUMBER: {cycle_number}
|
|
|
486
488
|
REVIEW_TIMESTAMP: {timestamp}
|
|
487
489
|
REVIEW_PUBLICATION: {REVIEW_PUBLICATION}
|
|
488
490
|
WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
489
|
-
Posts the consolidated review-summary comment (marker-deduped
|
|
491
|
+
Posts the consolidated review-summary comment (marker-deduped on the cycle+timestamp pair)."
|
|
490
492
|
```
|
|
491
493
|
|
|
492
494
|
### Phase 4: Write Review Head Marker & Report
|
|
@@ -494,34 +496,29 @@ Posts the consolidated review-summary comment (marker-deduped by the operation o
|
|
|
494
496
|
**Requires:** BRANCH_INFO, REVIEW_DIR
|
|
495
497
|
|
|
496
498
|
Per worktree, after successful completion:
|
|
497
|
-
1.
|
|
499
|
+
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.
|
|
498
500
|
2. Display results from all agents:
|
|
499
501
|
- Merge recommendation (from Synthesize agent)
|
|
500
502
|
- Issue counts by category (🔴 blocking / ⚠️ should-fix / ℹ️ pre-existing)
|
|
501
503
|
- Review comment status: POSTED / POSTED+TRUNCATED (body exceeded 60k after redaction) / SKIPPED (D7 dedup) / DEGRADED (from Git)
|
|
502
504
|
- 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)
|
|
505
|
+
- Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned
|
|
503
506
|
- Artifact paths
|
|
504
507
|
|
|
505
508
|
## Architecture
|
|
506
509
|
|
|
507
510
|
```
|
|
508
|
-
/code-review
|
|
511
|
+
/code-review
|
|
509
512
|
│
|
|
510
|
-
├─ Phase 0: Worktree Discovery & Pre-flight
|
|
511
|
-
│ ├─ Step 0a: git worktree list → filter reviewable
|
|
513
|
+
├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0f (Git agent per worktree, parallel)
|
|
512
514
|
│ ├─ Step 0b: Resolve the compliance lens and gate level
|
|
513
|
-
│ ├─ Step 0c: Git agent (ensure-pr-ready) per worktree [parallel]
|
|
514
|
-
│ ├─ Step 0d: Incremental detection + timestamp setup per worktree
|
|
515
|
-
│ ├─ Step 0e-i: Load prior resolution-summary.md
|
|
516
|
-
│ ├─ Step 0e-ii: Convergence assessment (warn only)
|
|
517
|
-
│ └─ Step 0f: Resolve REVIEW_PUBLICATION per worktree (publication gate)
|
|
518
515
|
│
|
|
519
|
-
├─ Per worktree (SEQUENTIAL
|
|
516
|
+
├─ Per worktree (SEQUENTIAL):
|
|
520
517
|
│ │
|
|
521
518
|
│ ├─ Phase 1: Analyze changed files
|
|
522
519
|
│ │ ├─ Classify the diff (paths.txt → DIFF_CLASS)
|
|
523
|
-
│ │ ├─ Choose the focuses
|
|
524
|
-
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
520
|
+
│ │ ├─ Choose the focuses
|
|
521
|
+
│ │ └─ Write diff.patch and diff-{focus}.patch
|
|
525
522
|
│ │
|
|
526
523
|
│ ├─ Phase 2: Reviews (PARALLEL within worktree), one per REVIEW_FOCUS_LIST focus
|
|
527
524
|
│ │ ├─ code: core (diff.patch), language (diff-{focus}.patch), conditional
|
|
@@ -539,7 +536,7 @@ Per worktree, after successful completion:
|
|
|
539
536
|
| Case | Handling |
|
|
540
537
|
|------|----------|
|
|
541
538
|
| `--full` in multi-worktree mode | Applies to all worktrees (global modifier). It sets the diff range, never the gate level |
|
|
542
|
-
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7)
|
|
539
|
+
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7) |
|
|
543
540
|
| Docs-only diff | Its Step 1.1 set, narrowed by level |
|
|
544
541
|
| Tests-only diff | Its Step 1.1 set, narrowed by level |
|
|
545
542
|
| Lockfile-only diff | Its Step 1.1 set, narrowed by level |
|
|
@@ -548,8 +545,7 @@ Per worktree, after successful completion:
|
|
|
548
545
|
| A file moved across classes | `--no-renames` lists both paths, so a code path makes the diff `code` |
|
|
549
546
|
| Path listing above about 40 lines | Read in ranges (Step 1.1) |
|
|
550
547
|
| Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
|
|
551
|
-
|
|
|
552
|
-
| `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 |
|
|
548
|
+
| `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 unless no public text remains |
|
|
553
549
|
|
|
554
550
|
## Backwards Compatibility
|
|
555
551
|
|
|
@@ -557,8 +553,8 @@ Per worktree, after successful completion:
|
|
|
557
553
|
|
|
558
554
|
## Principles
|
|
559
555
|
|
|
560
|
-
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
|
|
556
|
+
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
|
|
561
557
|
2. **Parallel, not background** - Multiple agents in one message, but `run_in_background=false` so phases complete before proceeding
|
|
562
|
-
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1;
|
|
558
|
+
3. **Git agent for git work** - All git operations go through Git agent, except the exceptions named in Principle 1; its writes print nothing
|
|
563
559
|
4. **Honest reporting** - Display agent outputs directly
|
|
564
560
|
5. **Incremental by default** - Only review new changes unless `--full` specified
|
package/dist/commands/debug.md
CHANGED
|
@@ -32,13 +32,13 @@ $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
|
|
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 in a one-worktree run:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
node "$HOME/.devflow/scripts/resolve-settings.cjs" "{root}" 2>/dev/null; echo "exit=$?"
|
|
39
39
|
```
|
|
40
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>
|
|
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> 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.
|
|
42
42
|
|
|
43
43
|
The accepted line is the only source of these values.
|
|
44
44
|
|
|
@@ -52,7 +52,7 @@ Phase 7 passes `COMPLIANCE_DIRECTIVE` to the Code agent that implements the fix,
|
|
|
52
52
|
|
|
53
53
|
### Load DECISIONS_CONTEXT
|
|
54
54
|
|
|
55
|
-
When the settings line says `
|
|
55
|
+
When the settings line says `CURATION=off`, set `DECISIONS_CONTEXT` to `(none)` and skip this step, locating no ledger and reading no index.
|
|
56
56
|
|
|
57
57
|
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`):
|
|
58
58
|
|
|
@@ -66,11 +66,11 @@ Line 1 is the checkout's toplevel, line 2 the common git directory. A git older
|
|
|
66
66
|
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
67
67
|
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
68
68
|
|
|
69
|
-
This is the rule the
|
|
69
|
+
This is the rule the curation hooks apply, so you read the index the Curate agent writes.
|
|
70
70
|
|
|
71
71
|
**Step 1 — Read the pre-rendered index:**
|
|
72
72
|
|
|
73
|
-
Attempt to read `{ledger}/.devflow/
|
|
73
|
+
Attempt to read `{ledger}/.devflow/curation/index.md`.
|
|
74
74
|
|
|
75
75
|
- If the file exists and contains non-empty content: use that content as `DECISIONS_CONTEXT`.
|
|
76
76
|
- If the file is absent or empty: set `DECISIONS_CONTEXT` to `(none)`.
|