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.
- package/CHANGELOG.md +142 -0
- package/README.md +1 -1
- package/dist/agents/code.md +6 -6
- package/dist/agents/fix.md +6 -6
- package/dist/agents/harden.md +7 -6
- package/dist/agents/refactor.md +6 -6
- package/dist/cli/commands/ambient.js +10 -2
- package/dist/cli/commands/backup-session.js +131 -0
- package/dist/cli/commands/compliance-prompts.js +9 -4
- package/dist/cli/commands/compliance.js +184 -24
- package/dist/cli/commands/curation.js +23 -10
- package/dist/cli/commands/gate-level-prompts.js +39 -25
- package/dist/cli/commands/gates.js +5 -7
- package/dist/cli/commands/init.js +169 -184
- package/dist/cli/commands/install-report.js +129 -0
- package/dist/cli/commands/legacy-sweep.js +159 -0
- package/dist/cli/commands/proxy.js +6 -1
- package/dist/cli/commands/rules.js +75 -21
- package/dist/cli/commands/skills.js +42 -9
- package/dist/cli/commands/tracker.js +9 -3
- package/dist/cli/commands/uninstall.js +339 -75
- package/dist/commands/bug-analysis.md +69 -120
- package/dist/commands/dynamic-build.md +23 -23
- package/dist/commands/implement.md +46 -32
- package/dist/commands/release.md +1 -1
- package/dist/commands/resolve.md +35 -31
- package/dist/commands/self-review.md +8 -7
- package/dist/compliance-off/agents/git.md +120 -0
- package/dist/compliance-off/agents/triage.md +180 -0
- package/dist/compliance-off/commands/bug-analysis.md +398 -0
- package/dist/compliance-off/commands/code-review.md +520 -0
- package/dist/compliance-off/commands/dynamic-build.md +1251 -0
- package/dist/compliance-off/commands/dynamic-tickets.md +676 -0
- package/dist/compliance-off/commands/implement.md +736 -0
- package/dist/compliance-off/commands/plan.md +671 -0
- package/dist/compliance-off/commands/release.md +309 -0
- package/dist/compliance-off/commands/resolve.md +742 -0
- package/dist/compliance-off/skills/git/references/decision-markers.md +17 -0
- package/dist/compliance-off/skills/git/references/learn-conventions.md +80 -0
- package/dist/compliance-off/skills/git/references/pr/check-ci-status.md +33 -0
- package/dist/compliance-off/skills/git/references/pr/check-merge-readiness.md +49 -0
- package/dist/compliance-off/skills/git/references/pr/fetch-review-threads.md +52 -0
- package/dist/compliance-off/skills/git/references/pr/validate-branch.md +47 -0
- package/dist/compliance-off/skills/git/references/tracker/_contract.md +33 -0
- package/dist/compliance-off/skills/git/references/tracker/_mcp.md +153 -0
- package/dist/compliance-off/skills/git/references/tracker/github/create-release.md +35 -0
- package/dist/compliance-off/skills/git/references/tracker/github/ensure-pr-ready.md +100 -0
- package/dist/compliance-off/skills/git/references/tracker/github/ensure-traceable-issue.md +74 -0
- package/dist/compliance-off/skills/git/references/tracker/github/fetch-issue.md +69 -0
- package/dist/compliance-off/skills/git/references/tracker/github/fetch-issues-batch.md +65 -0
- package/dist/compliance-off/skills/git/references/tracker/github/gather-release-evidence.md +48 -0
- package/dist/compliance-off/skills/git/references/tracker/github/setup-task.md +77 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/create-release.md +35 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/ensure-pr-ready.md +100 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/ensure-traceable-issue.md +61 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issue.md +51 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/fetch-issues-batch.md +63 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/gather-release-evidence.md +47 -0
- package/dist/compliance-off/skills/git/references/tracker/jira/setup-task.md +82 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/create-release.md +35 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/ensure-pr-ready.md +100 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/ensure-traceable-issue.md +61 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issue.md +51 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/fetch-issues-batch.md +63 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/gather-release-evidence.md +47 -0
- package/dist/compliance-off/skills/git/references/tracker/linear/setup-task.md +83 -0
- package/dist/compliance-off/skills/git/references/trust-rule.md +7 -0
- package/dist/core/agent-models.js +19 -4
- package/dist/core/assets.js +126 -17
- package/dist/core/compliance-off-files.js +27 -0
- package/dist/core/compliance.js +14 -0
- package/dist/core/curation-variants.js +460 -112
- package/dist/core/flags.js +2 -2
- package/dist/core/fs-atomic.js +5 -1
- package/dist/core/installed-variants.js +63 -0
- package/dist/core/manifest.js +48 -5
- package/dist/core/mds-variants.js +700 -3
- package/dist/core/orphan-sweep.js +29 -2
- package/dist/core/path-set.js +15 -0
- package/dist/core/plugins.js +68 -10
- package/dist/core/reference-sweep.js +42 -25
- package/dist/core/retired-shipped-names.js +278 -0
- package/dist/curation-compliance-off/agents/triage.md +176 -0
- package/dist/curation-compliance-off/commands/bug-analysis.md +349 -0
- package/dist/curation-compliance-off/commands/code-review.md +481 -0
- package/dist/curation-compliance-off/commands/dynamic-build.md +1211 -0
- package/dist/curation-compliance-off/commands/dynamic-tickets.md +634 -0
- package/dist/curation-compliance-off/commands/implement.md +689 -0
- package/dist/curation-compliance-off/commands/plan.md +631 -0
- package/dist/curation-compliance-off/commands/release.md +279 -0
- package/dist/curation-compliance-off/commands/resolve.md +692 -0
- package/dist/curation-off/agents/code.md +6 -6
- package/dist/curation-off/agents/fix.md +6 -6
- package/dist/curation-off/agents/harden.md +7 -6
- package/dist/curation-off/agents/refactor.md +6 -6
- package/dist/curation-off/commands/bug-analysis.md +69 -119
- package/dist/curation-off/commands/dynamic-build.md +23 -23
- package/dist/curation-off/commands/implement.md +46 -32
- package/dist/curation-off/commands/release.md +1 -1
- package/dist/curation-off/commands/resolve.md +35 -31
- package/dist/curation-off/commands/self-review.md +8 -7
- package/dist/skills/git/references/pr/resolve-review-threads.md +1 -1
- package/dist/targets/claude-code/behavior-install.js +23 -9
- package/dist/targets/claude-code/charter-render.js +374 -0
- package/dist/targets/claude-code/compliance-install.js +62 -17
- package/dist/targets/claude-code/compliance-off-files.js +249 -0
- package/dist/targets/claude-code/curation-install.js +632 -117
- package/dist/targets/claude-code/folder-swap.js +142 -0
- package/dist/targets/claude-code/install-backup.js +780 -0
- package/dist/targets/claude-code/installer.js +795 -199
- package/dist/targets/claude-code/language-stamp.js +6 -0
- package/dist/targets/claude-code/legacy-skill-hashes.js +170 -0
- package/dist/targets/claude-code/linked-folder.js +176 -0
- package/dist/targets/claude-code/reference-converge.js +131 -0
- package/dist/targets/claude-code/rules-folder.js +34 -0
- package/dist/targets/claude-code/shipped-set.js +160 -0
- package/dist/targets/claude-code/tracker-install.js +21 -8
- package/dist/targets/claude-code/tracker-servers.js +20 -6
- package/dist/targets/claude-code/workflow-folder-install.js +251 -0
- package/dist/variant-axes.json +109 -0
- package/package.json +1 -1
- package/src/assets/agents/_partials/_code.mds +6 -6
- package/src/assets/agents/evaluate.md +1 -1
- package/src/assets/agents/git.mds +32 -0
- package/src/assets/agents/harden.mds +7 -6
- package/src/assets/agents/test.md +21 -12
- package/src/assets/agents/triage.mds +2 -0
- package/src/assets/agents/validate.md +10 -10
- package/src/assets/commands/_partials/_compliance.mds +5 -3
- package/src/assets/commands/_partials/_engine.mds +9 -8
- package/src/assets/commands/_partials/_publication.mds +10 -1
- package/src/assets/commands/bug-analysis.mds +80 -126
- package/src/assets/commands/code-review.mds +43 -0
- package/src/assets/commands/dynamic-build.mds +109 -15
- package/src/assets/commands/dynamic-tickets.mds +13 -0
- package/src/assets/commands/implement.mds +145 -33
- package/src/assets/commands/plan.mds +19 -0
- package/src/assets/commands/release.mds +50 -1
- package/src/assets/commands/resolve.mds +217 -32
- package/src/assets/commands/self-review.mds +8 -7
- package/src/assets/mds/git/_ops.mds +23 -0
- package/src/assets/mds/git/_ops_steps.mds +17 -0
- package/src/assets/mds/git/_pr.mds +1 -1
- package/src/assets/mds/git/_references.mds +6 -0
- package/src/assets/mds/tracker/_common.mds +4 -0
- package/src/assets/mds/tracker/_github.mds +42 -0
- package/src/assets/mds/tracker/_jira.mds +43 -0
- package/src/assets/mds/tracker/_linear.mds +43 -0
- package/src/assets/rules/quality.md +2 -0
- package/src/assets/scripts/ci-wait.cjs +204 -126
- package/src/assets/scripts/hooks/assets/implement-installed +1 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +13 -11
- package/src/assets/scripts/hooks/preamble +18 -8
- package/src/assets/scripts/hooks/session-start-orchestrator +4 -2
- package/src/assets/scripts/pr-evidence.cjs +41 -2
- package/src/assets/scripts/verify-evidence.cjs +408 -56
- package/src/assets/skills/agent-references/references/commands/implement-revalidate.md +3 -3
- package/src/assets/skills/agent-references/references/commands/plan-levels.md +1 -1
- package/src/assets/skills/agent-references/references/synthesize/bug-analysis.md +6 -2
- package/src/assets/skills/agent-references/references/validate/passed-alone.md +7 -7
- package/src/assets/skills/docs-framework/SKILL.md +5 -2
- package/src/assets/skills/git/SKILL.md +3 -3
- package/src/assets/skills/git/references/github-api.md +2 -139
- package/src/assets/skills/git/references/github-posting.md +158 -0
- package/src/assets/skills/review-methodology/SKILL.md +1 -1
- package/src/assets/skills/review-methodology/references/patterns.md +1 -1
- package/src/assets/skills/review-methodology/references/report-template.md +1 -2
- package/src/assets/skills/testing/SKILL.md +2 -4
|
@@ -9,15 +9,11 @@ output-dir: dist/commands
|
|
|
9
9
|
@import "./_partials/_settings.mds" as settings
|
|
10
10
|
# Bug Analysis Command
|
|
11
11
|
|
|
12
|
-
Run a proactive bug analysis on the current branch
|
|
12
|
+
Run a proactive bug analysis on the current branch: static analysis tools and parallel semantic analyzers, synthesized into one bug report.
|
|
13
13
|
|
|
14
14
|
## Usage
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
/bug-analysis (analyze current branch — incremental if prior analysis exists)
|
|
18
|
-
/bug-analysis --full (force full analysis, ignore incremental state)
|
|
19
|
-
/bug-analysis --no-static (skip static analysis track, semantic-only)
|
|
20
|
-
```
|
|
16
|
+
`/bug-analysis [--full] [--no-static]`: `--full` ignores incremental state; `--no-static` skips static analysis.
|
|
21
17
|
|
|
22
18
|
## Phases
|
|
23
19
|
|
|
@@ -28,7 +24,11 @@ Run a proactive bug analysis on the current branch by combining static analysis
|
|
|
28
24
|
{{evidence_policy()}}
|
|
29
25
|
|
|
30
26
|
{{docs_root()}}
|
|
27
|
+
<!-- compliance:off -->
|
|
28
|
+
When `EVIDENCE_POLICY` is `required`, record `TRACEABILITY: DEGRADED (compliance off on this machine; the repository requires evidence)` once, for the Phase 7 report.
|
|
29
|
+
<!-- compliance:end -->
|
|
31
30
|
|
|
31
|
+
<!-- compliance:on -->
|
|
32
32
|
Render the test-plan block from `/implement`'s evidence file, and from nothing else:
|
|
33
33
|
1. `branch_slug` is `git -C "{worktree}" branch --show-current` with every `/` replaced by `-`.
|
|
34
34
|
2. Only when `branch_slug` matches `^[A-Za-z0-9._-]{1,200}$` and the file exists, run (the path double-quoted):
|
|
@@ -39,12 +39,15 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.dev
|
|
|
39
39
|
|
|
40
40
|
3. On `exit=0`, `PR_TEST_PLAN_BLOCK` is its stdout byte for byte without that `exit=` line; in every other case it is `(none)`. Nothing here waits on it: the Git agent pastes it only behind its own check, and only into a PR it creates.
|
|
41
41
|
|
|
42
|
+
<!-- compliance:end -->
|
|
42
43
|
Spawn Git agent:
|
|
43
44
|
|
|
44
45
|
```
|
|
45
46
|
Agent(subagent_type="Git", run_in_background=false):
|
|
46
47
|
"OPERATION: ensure-pr-ready
|
|
48
|
+
<!-- compliance:on -->
|
|
47
49
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
50
|
+
<!-- compliance:end -->
|
|
48
51
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
49
52
|
Validate branch, commit if needed, push, create PR if needed.
|
|
50
53
|
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
@@ -88,7 +91,7 @@ If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
|
88
91
|
CHANGED_FILES=$(git diff --name-only {DIFF_RANGE})
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
Store as `CHANGED_FILES`;
|
|
94
|
+
Store as `CHANGED_FILES`; Phase 4 reads it. A non-zero diff exit stops.
|
|
92
95
|
|
|
93
96
|
If output is empty → "No changes to analyze." Stop.
|
|
94
97
|
|
|
@@ -96,75 +99,81 @@ If output is empty → "No changes to analyze." Stop.
|
|
|
96
99
|
|
|
97
100
|
**Produces:** STATIC_TOOL_STATUS
|
|
98
101
|
|
|
99
|
-
|
|
102
|
+
If `--no-static` is set: set `STATIC_FINDINGS` to "Static analysis skipped (--no-static)." and `STATIC_STATUS` to "skipped (--no-static): static analysis did not cover these commits". Skip the rest of Phase 2.
|
|
100
103
|
|
|
101
104
|
```bash
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
CODEQL_AVAILABLE=$(which codeql 2>/dev/null && echo "yes" || echo "no")
|
|
105
|
+
for t in semgrep snyk codeql jq; do printf '%s=%s\n' "$t" "$(command -v "$t" || echo no)"; done
|
|
106
|
+
set -o pipefail; export LC_ALL=C; git -C "{worktree}" diff --name-only -z --diff-filter=d {DIFF_RANGE} | tr '\0\n' '\n?' | sed -n 's/.*\.\([^./]*\)$/\1/p' | sort -u || echo "extension list failed"
|
|
105
107
|
```
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
Its second line lists the extensions of the changed files. `{lang}` is the first of javascript-typescript (js jsx mjs cjs ts tsx), python (py), ruby (rb) whose extension is listed; no other value reaches the command. With none, CodeQL does not run and its status is `no supported language`; `extension list failed` means it did not complete.
|
|
110
|
+
|
|
111
|
+
If all three scanners print `no`: warn user "No static analysis tools found. Install semgrep or snyk." Set `STATIC_FINDINGS` to "Static analysis did not run: no scanner is installed." and `STATIC_STATUS` to `not installed` for each tool.
|
|
112
|
+
|
|
113
|
+
If a scanner is installed but `jq` prints `no`: set `STATIC_FINDINGS` to "Static analysis did not complete: jq is not installed." and `STATIC_STATUS` to `did not complete (jq is not installed)` for an installed tool, else `not installed`.
|
|
108
114
|
|
|
109
115
|
If some are available: note which tools will run.
|
|
110
116
|
|
|
111
117
|
#### Step 2d: Tiered Static Analysis
|
|
112
118
|
|
|
113
|
-
**Produces:** STATIC_FINDINGS
|
|
119
|
+
**Produces:** STATIC_FINDINGS, STATIC_STATUS
|
|
114
120
|
**Requires:** STATIC_TOOL_STATUS, DIFF_RANGE, ANALYSIS_DIR
|
|
115
121
|
|
|
116
|
-
Skip if
|
|
117
|
-
|
|
118
|
-
Run available tools on the changed files (from `CHANGED_FILES` computed in Step 2b).
|
|
122
|
+
Skip if Step 2c set `STATIC_STATUS`.
|
|
119
123
|
|
|
120
|
-
|
|
124
|
+
Run each available tool in this order, each in its own foreground Bash call with the Bash `timeout` at the ceiling: 600000 ms, or `BASH_MAX_TIMEOUT_MS` when set. Past it, make no tool call, even a Read, until its end notice, then Read the last `exit=` line of the output file that notice names, never a scanner file; the notice sets nothing. File names reach a scanner only through `-z`, `xargs -0` and after `--`.
|
|
121
125
|
|
|
122
126
|
**Semgrep** (if available):
|
|
123
127
|
```bash
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
cd "{worktree}" || exit
|
|
129
|
+
set -o pipefail; git diff --name-only -z --diff-filter=d {DIFF_RANGE} | xargs -0 -r semgrep scan --config auto --sarif --quiet -- >"{ANALYSIS_DIR}/semgrep.part" 2>/dev/null; E=$?
|
|
130
|
+
mv "{ANALYSIS_DIR}"/semgrep.{part,sarif}
|
|
131
|
+
printf '\nexit=%s\n' "$E"
|
|
126
132
|
```
|
|
127
|
-
Parse SARIF output → extract findings.
|
|
128
133
|
|
|
129
134
|
**Snyk Code** (if available):
|
|
130
135
|
```bash
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
136
|
+
cd "{worktree}" || exit
|
|
137
|
+
snyk code test --sarif >"{ANALYSIS_DIR}/snyk-all.json" 2>/dev/null; E=$?
|
|
138
|
+
git diff --name-only -z {DIFF_RANGE} >"{ANALYSIS_DIR}/changed.z" && jq --rawfile n "{ANALYSIS_DIR}/changed.z" \
|
|
139
|
+
'($n|split("\u0000")) as $f|.runs[]?.results|=[.[]?|select([.locations[]?.physicalLocation.artifactLocation.uri//empty] as $u|($u|length)==0 or any($u[];IN($f[])))]' \
|
|
140
|
+
"{ANALYSIS_DIR}/snyk-all.json" >"{ANALYSIS_DIR}/snyk.sarif" \
|
|
141
|
+
&& jq -nr '[inputs|[.runs[]?.results[]?]|length]|"total=\(.[0]) kept=\(.[1])"' "{ANALYSIS_DIR}/snyk-all.json" "{ANALYSIS_DIR}/snyk.sarif" \
|
|
142
|
+
|| { echo "Snyk scope filter failed: unfiltered"; cp "{ANALYSIS_DIR}/snyk-all.json" "{ANALYSIS_DIR}/snyk.sarif"; }
|
|
143
|
+
printf '\nexit=%s\n' "$E"
|
|
137
144
|
```
|
|
138
|
-
|
|
145
|
+
|
|
146
|
+
**Counts and table** (after Snyk with `{tools}` = `semgrep snyk`; after CodeQL with `codeql`):
|
|
147
|
+
```bash
|
|
148
|
+
cd "{ANALYSIS_DIR}" || exit
|
|
149
|
+
L='def L($r):.ruleId as $i|.level//([$r.tool|.driver,.extensions[]?|.rules[]?|select(.id==$i)]|.[0].defaultConfiguration.level)//"warning";'
|
|
150
|
+
for t in {tools}; do [ -f $t.sarif ] || continue
|
|
151
|
+
jq -rs --arg t $t "$L"'[.[].runs[]?|. as $r|.results[]?|L($r)] as $l|def c(k):[$l[]|select(.==k)]|length;"\($t) docs=\(length) results=\($l|length) error=\(c("error")) warning=\(c("warning")) note=\(c("note"))"' $t.sarif || echo "$t sarif=unreadable"
|
|
152
|
+
jq -r --arg t $t "$L"'.runs[]?|. as $r|.results[]?|[$t,(.locations[0].physicalLocation|.artifactLocation.uri,.region.startLine),L($r),(.ruleId//"—"),((.message.text//"")[:200])]|@tsv' $t.sarif >findings-$t.tsv || echo "findings table incomplete: $t"
|
|
153
|
+
done
|
|
154
|
+
cat findings-{semgrep,snyk,codeql}.tsv >findings.tsv 2>/dev/null
|
|
155
|
+
jq -Rrs 'split("\n")|map(select(.!=""))|sort_by(split("\t")[3]|{error:0,warning:1}[.]//2)|.[:50][]' findings.tsv >findings-top.tsv || echo "findings table incomplete: top"
|
|
156
|
+
```
|
|
157
|
+
Read `error` as HIGH, `warning` as MEDIUM, `note` as LOW.
|
|
139
158
|
|
|
140
159
|
**CodeQL** (if available AND (`--full` OR Semgrep/Snyk found HIGH/CRITICAL findings)):
|
|
141
160
|
```bash
|
|
142
|
-
|
|
143
|
-
CODEQL_TMP=$(mktemp -d)
|
|
144
|
-
# Register cleanup trap immediately after mktemp — ensures rm -rf runs on EXIT, SIGTERM, and SIGINT
|
|
145
|
-
# even if the session is interrupted before reaching the explicit rm -rf below
|
|
161
|
+
CODEQL_TMP=$(mktemp -d) || exit
|
|
146
162
|
trap 'rm -rf "${CODEQL_TMP}"' EXIT INT TERM
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
# Capture exit status before cleanup so cleanup doesn't mask failures
|
|
163
|
+
{ codeql database create "${CODEQL_TMP}/db" --language={lang} --source-root="{worktree}" && \
|
|
164
|
+
codeql database analyze "${CODEQL_TMP}/db" --format=sarif-latest --output="{ANALYSIS_DIR}/codeql.sarif"; } >"{ANALYSIS_DIR}/codeql.log" 2>&1
|
|
150
165
|
CODEQL_EXIT=$?
|
|
151
|
-
|
|
152
|
-
CODEQL_SARIF=$(cat "${CODEQL_TMP}/results.sarif" 2>/dev/null || echo "")
|
|
153
|
-
# Explicit cleanup (trap also covers this path; explicit rm is belt-and-suspenders)
|
|
166
|
+
printf '\nexit=%s\n' "$CODEQL_EXIT"
|
|
154
167
|
rm -rf "${CODEQL_TMP}"
|
|
155
168
|
trap - EXIT INT TERM
|
|
156
169
|
```
|
|
157
|
-
|
|
170
|
+
A tool's status is its last line, `exit={n}`; a tool that ran completed only on Semgrep 0, Snyk 0 or 1 (1 = issues, only with SARIF output), CodeQL 0. Snyk 3 (no supported file) is `no supported language`: its counts are not checked. Any other status, or no such line, means it did not complete (126-127: scanner did not start; else failed. Semgrep via xargs: number only). A call with no `exit=` line read did not complete. A tool that ran also did not complete when the counts fence prints no `{tool} docs=` line for it, `sarif=unreadable` or `findings table incomplete` for it (`: top` counts for every tool), or `docs=0` (Semgrep exit 0 with `docs=0`: no file to scan, completed).
|
|
158
171
|
|
|
159
|
-
|
|
172
|
+
`findings.tsv` keeps every finding. Read only `findings-top.tsv` (top 50 by level: tool, file, line, level, rule, message cut to 200 chars), set `STATIC_FINDINGS` to the column names and its rows, and write them with the status lines to `{ANALYSIS_DIR}/static-findings.md`.
|
|
160
173
|
|
|
161
|
-
|
|
162
|
-
|------|-----------|-----|----------|-------|-------------|
|
|
163
|
-
| {tool} | {file}:{line} | {CWE or —} | {CRITICAL/HIGH/MEDIUM/LOW} | {title} | {description truncated to 200 chars} |
|
|
174
|
+
`STATIC_FINDINGS` is `(none)` only when every tool that was to run completed, at least one did, and none found anything; when no tool was to run, it is "Static analysis did not run: no tool ran." For each tool that did not complete, add under any rows the line "Static analysis did not complete: {tool}: " plus "exit {n} ({meaning}).", "no exit status.", "no counts line." or "SARIF not read." A Snyk call (not Snyk 3) that printed "Snyk scope filter failed: unfiltered" adds that line too.
|
|
164
175
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
|
|
176
|
+
Set `STATIC_STATUS` to one `{tool}: {value}` per tool: `completed`, `not installed`, `not needed` (CodeQL, not triggered) or `no supported language` (CodeQL with no table row, or Snyk 3), all covered, or `did not complete ({why})`, not covered. A covered tool other than `completed` was not to run.
|
|
168
177
|
|
|
169
178
|
### Phase 3: Context Loading
|
|
170
179
|
|
|
@@ -188,23 +197,22 @@ If no tool produced findings: set `STATIC_FINDINGS` to `(none)`.
|
|
|
188
197
|
#### Plan Artifact
|
|
189
198
|
|
|
190
199
|
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). 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
|
|
191
|
-
2. Read the most recent file that carries an `## Acceptance Criteria` section
|
|
192
|
-
3.
|
|
193
|
-
4.
|
|
194
|
-
5. If no plan files exist or section not found: `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)`
|
|
200
|
+
2. Read the most recent file that carries an `## Acceptance Criteria` section; parse it into the table `| ID | Criterion | Type | Testable Condition |`
|
|
201
|
+
3. Set `PLAN_CONTEXT` to plan summary; `ACCEPTANCE_RULES` to the table
|
|
202
|
+
4. If no plan files exist or section not found: `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)`
|
|
195
203
|
|
|
196
204
|
### Phase 4: File Analysis
|
|
197
205
|
|
|
198
206
|
**Produces:** ACTIVE_FOCUSES
|
|
199
207
|
**Requires:** DIFF_RANGE
|
|
200
208
|
|
|
201
|
-
|
|
209
|
+
Pick the focus analyzers from `CHANGED_FILES` (Step 2b; do not re-run `git diff`):
|
|
202
210
|
|
|
203
211
|
| Focus | Condition |
|
|
204
212
|
|-------|-----------|
|
|
205
213
|
| `security` | Always |
|
|
206
214
|
| `functional` | Always |
|
|
207
|
-
| `integration` | 2+ distinct directories changed
|
|
215
|
+
| `integration` | 2+ distinct directories changed |
|
|
208
216
|
| `usability` | Any `.tsx`, `.jsx`, `.html`, or `.css` file changed |
|
|
209
217
|
|
|
210
218
|
### Phase 5: Parallel Bug Analysis
|
|
@@ -226,7 +234,7 @@ FOCUS: {focus}
|
|
|
226
234
|
DIFF_COMMAND: git diff {DIFF_RANGE}
|
|
227
235
|
ACCEPTANCE_RULES: {ACCEPTANCE_RULES filtered to this focus type, or (none)}
|
|
228
236
|
PLAN_CONTEXT: {PLAN_CONTEXT}
|
|
229
|
-
STATIC_FINDINGS: {STATIC_FINDINGS if focus == security, else (none)}
|
|
237
|
+
STATIC_FINDINGS: <static-findings>{STATIC_FINDINGS if focus == security, else (none)}</static-findings>
|
|
230
238
|
<!-- curation:on -->
|
|
231
239
|
DECISIONS_CONTEXT: {DECISIONS_CONTEXT}
|
|
232
240
|
<!-- curation:end -->
|
|
@@ -237,18 +245,13 @@ OUTPUT_PATH: {ANALYSIS_DIR}/{focus}.md
|
|
|
237
245
|
Follow devflow:apply-decisions to Read full ADR/PF bodies on demand.
|
|
238
246
|
<!-- curation:end -->
|
|
239
247
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE.
|
|
240
|
-
IMPORTANT: Write report to
|
|
248
|
+
IMPORTANT: Write the report to OUTPUT_PATH using the Write tool"
|
|
241
249
|
```
|
|
242
250
|
|
|
243
|
-
Notes:
|
|
244
|
-
- Security analyzer receives full `STATIC_FINDINGS`; all others receive `(none)`
|
|
245
|
-
- Filter `ACCEPTANCE_RULES` by the `Type` column matching each focus: security criteria → security analyzer, functional criteria → functional analyzer, etc. Pass the filtered subset only
|
|
246
|
-
- Spawn all in a single message for true parallel execution
|
|
247
|
-
|
|
248
251
|
### Phase 6: Synthesis
|
|
249
252
|
|
|
250
253
|
**Produces:** BUG_ANALYSIS_SUMMARY
|
|
251
|
-
**Requires:** ANALYZER_OUTPUTS, ANALYSIS_DIR, BRANCH_INFO
|
|
254
|
+
**Requires:** ANALYZER_OUTPUTS, ANALYSIS_DIR, BRANCH_INFO, STATIC_STATUS
|
|
252
255
|
|
|
253
256
|
Spawn Synthesize agent:
|
|
254
257
|
|
|
@@ -258,42 +261,43 @@ Agent(subagent_type="Synthesize", run_in_background=false):
|
|
|
258
261
|
ANALYSIS_BASE_DIR: {ANALYSIS_DIR}
|
|
259
262
|
BRANCH: {branch} -> {base_branch}
|
|
260
263
|
TIMESTAMP: {timestamp}
|
|
264
|
+
STATIC_STATUS: {STATIC_STATUS}
|
|
261
265
|
Output: {ANALYSIS_DIR}/bug-analysis-summary.md"
|
|
262
266
|
```
|
|
263
267
|
|
|
264
268
|
### Phase 7: Finalize
|
|
265
269
|
|
|
266
|
-
**Requires:** BRANCH_INFO, ANALYSIS_DIR
|
|
270
|
+
**Requires:** BRANCH_INFO, ANALYSIS_DIR, STATIC_STATUS
|
|
267
271
|
|
|
268
|
-
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.
|
|
272
|
+
1. Run the write below only when every tool that was to run completed, or `--no-static` is set, also with `--full`. Else keep the marker; the report names the way out (fix the tool, or run with `--no-static`). 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.
|
|
269
273
|
2. Report to user:
|
|
270
274
|
|
|
271
275
|
```
|
|
272
276
|
## Bug Analysis Complete
|
|
273
277
|
|
|
274
278
|
**Branch**: {branch} -> {base_branch}
|
|
279
|
+
<!-- compliance:on -->
|
|
275
280
|
{any base `TRACEABILITY: DEGRADED` line from Phase 1, as returned}
|
|
281
|
+
<!-- compliance:off -->
|
|
282
|
+
{any base `TRACEABILITY: DEGRADED` line from Phase 1, as returned, and the compliance-off line of Phase 1}
|
|
283
|
+
<!-- compliance:end -->
|
|
276
284
|
**Analysis**: {ANALYSIS_DIR}
|
|
285
|
+
**Static analysis**: {STATIC_STATUS per tool; if a tool did not complete: "marker kept" and the way out; any Snyk filter note}
|
|
277
286
|
|
|
278
287
|
### Risk Assessment: {risk_level}
|
|
279
288
|
|
|
280
289
|
{brief_reasoning}
|
|
281
290
|
|
|
282
291
|
### Bug Counts
|
|
283
|
-
|
|
284
|
-
|----------|----------|------|--------|-----|-------|
|
|
285
|
-
| Security | {n} | {n} | {n} | {n} | {n} |
|
|
286
|
-
| Functional | {n} | {n} | {n} | {n} | {n} |
|
|
287
|
-
| Integration | {n} | {n} | {n} | {n} | {n} |
|
|
288
|
-
| Usability | {n} | {n} | {n} | {n} | {n} |
|
|
292
|
+
{The summary's Bug Summary table: Security, Functional, Integration and Usability rows by CRITICAL, HIGH, MEDIUM, LOW and Total}
|
|
289
293
|
|
|
290
294
|
### Top Findings
|
|
291
|
-
{
|
|
295
|
+
{Top 3-5 bugs by severity and confidence}
|
|
292
296
|
|
|
293
297
|
### Artifacts
|
|
294
298
|
- Bug report: {ANALYSIS_DIR}/bug-analysis-summary.md
|
|
295
|
-
- Per-focus reports: {ANALYSIS_DIR}/{
|
|
296
|
-
- Static findings: {ANALYSIS_DIR}/static-findings.md (if
|
|
299
|
+
- Per-focus reports: {ANALYSIS_DIR}/{focus}.md
|
|
300
|
+
- Static findings: {ANALYSIS_DIR}/static-findings.md (if it ran)
|
|
297
301
|
|
|
298
302
|
{if any CRITICAL or HIGH bugs found:}
|
|
299
303
|
Run `/resolve` to process and fix these findings.
|
|
@@ -301,76 +305,26 @@ Run `/resolve` to process and fix these findings.
|
|
|
301
305
|
|
|
302
306
|
## Architecture
|
|
303
307
|
|
|
304
|
-
|
|
305
|
-
/bug-analysis (orchestrator — spawns agents only)
|
|
306
|
-
│
|
|
307
|
-
├─ Phase 1: Pre-flight
|
|
308
|
-
│ └─ Git agent (ensure-pr-ready)
|
|
309
|
-
│
|
|
310
|
-
├─ Phase 2: Static Analysis
|
|
311
|
-
│ └─ 2a incremental range, 2b changed files (stop if none), 2c tools, 2d semgrep → snyk → codeql
|
|
312
|
-
│
|
|
313
|
-
├─ Phase 3: Context Loading
|
|
314
|
-
<!-- curation:on -->
|
|
315
|
-
│ ├─ index.md (pre-rendered) → DECISIONS_CONTEXT
|
|
316
|
-
<!-- curation:end -->
|
|
317
|
-
│ ├─ Feature knowledge load → FEATURE_KNOWLEDGE
|
|
318
|
-
│ └─ {worktree}/.devflow/docs/design/*.md → PLAN_CONTEXT + ACCEPTANCE_RULES
|
|
319
|
-
│
|
|
320
|
-
├─ Phase 4: File Analysis
|
|
321
|
-
│ └─ Detect active focuses (security + functional always; integration + usability conditional)
|
|
322
|
-
│
|
|
323
|
-
├─ Phase 5: Bug Analysis (PARALLEL)
|
|
324
|
-
│ └─ Debug agent per active focus (security also reads STATIC_FINDINGS)
|
|
325
|
-
│
|
|
326
|
-
├─ Phase 6: Synthesis
|
|
327
|
-
│ └─ Synthesize agent (mode: bug-analysis)
|
|
328
|
-
│
|
|
329
|
-
└─ Phase 7: Finalize
|
|
330
|
-
├─ Write .last-analysis-head
|
|
331
|
-
└─ Display results + suggest /resolve if blocking bugs found
|
|
332
|
-
```
|
|
308
|
+
Seven phases: Phase 1 to Phase 7.
|
|
333
309
|
|
|
334
310
|
## Edge Cases
|
|
335
311
|
|
|
336
312
|
| Case | Handling |
|
|
337
313
|
|------|----------|
|
|
338
|
-
| No new commits since last analysis | Stop: "No new commits since last analysis. Use --full for a full re-analysis." |
|
|
339
314
|
| Rebase invalidates `.last-analysis-head` SHA | `git cat-file -t` check fails → fallback to full diff |
|
|
340
315
|
| Zero changed files in DIFF_RANGE with exit 0 | Stop: "No changes to analyze." |
|
|
341
|
-
| Same-minute analysis collision | `mkdir` with seconds suffix (`YYYY-MM-DD_HHMMSS`) |
|
|
342
|
-
| All static tools unavailable | Warn, proceed with semantic-only analysis |
|
|
343
|
-
| `--no-static` flag | Skip Phase 2c and 2d entirely; `STATIC_FINDINGS=(none)` |
|
|
344
316
|
| `--full` flag | Bypass incremental detection (Step 2a), run full diff from base |
|
|
345
|
-
|
|
|
317
|
+
| A scanner did not run or did not complete | Name the tool and why in `STATIC_FINDINGS`, not `(none)`; a tool that did not complete keeps the marker |
|
|
346
318
|
|
|
347
319
|
## Resolve Compatibility
|
|
348
320
|
|
|
349
|
-
|
|
321
|
+
`/resolve` detects and uses bug analysis reports when no code review report exists.
|
|
350
322
|
|
|
351
323
|
## Principles
|
|
352
324
|
|
|
353
|
-
1. **Orchestration only** —
|
|
354
|
-
2. **
|
|
355
|
-
3. **Static + semantic** — Two complementary tracks, each validates the other
|
|
356
|
-
4. **Incremental by default** — Only analyze new changes unless `--full` specified
|
|
357
|
-
5. **Verify before reporting** — Debug agents self-verify every finding
|
|
358
|
-
6. **Honest reporting** — Display risk level and counts directly from synthesis
|
|
325
|
+
1. **Orchestration only** — the command spawns agents and does no analysis itself
|
|
326
|
+
2. **Incremental by default** — only new changes, unless `--full`
|
|
359
327
|
|
|
360
328
|
## Phase Completion Checklist
|
|
361
329
|
|
|
362
|
-
Before reporting results, verify every phase was
|
|
363
|
-
|
|
364
|
-
- [ ] Phase 1: Pre-flight → BRANCH_INFO captured, PR_DESCRIPTION fetched (or `(none)`)
|
|
365
|
-
- [ ] Phase 2: Static Analysis → STATIC_FINDINGS captured (or `(none)` if skipped/no tools/no findings); ANALYSIS_DIR created; CHANGED_FILES populated
|
|
366
|
-
<!-- curation:on -->
|
|
367
|
-
- [ ] Phase 3: Context Loading → DECISIONS_CONTEXT captured, FEATURE_KNOWLEDGE loaded (or `(none)`), PLAN_CONTEXT and ACCEPTANCE_RULES captured (or `(none)`)
|
|
368
|
-
<!-- curation:off -->
|
|
369
|
-
- [ ] Phase 3: Context Loading → FEATURE_KNOWLEDGE loaded (or `(none)`), PLAN_CONTEXT and ACCEPTANCE_RULES captured (or `(none)`)
|
|
370
|
-
<!-- curation:end -->
|
|
371
|
-
- [ ] Phase 4: File Analysis → ACTIVE_FOCUSES determined (security + functional always present)
|
|
372
|
-
- [ ] Phase 5: Parallel Bug Analysis → ANALYZER_OUTPUTS captured per active focus; all reports written to ANALYSIS_DIR
|
|
373
|
-
- [ ] Phase 6: Synthesis → BUG_ANALYSIS_SUMMARY written to `{ANALYSIS_DIR}/bug-analysis-summary.md`
|
|
374
|
-
- [ ] Phase 7: Finalize → `.last-analysis-head` updated; results displayed to user
|
|
375
|
-
|
|
376
|
-
If any phase is unchecked, execute it before proceeding.
|
|
330
|
+
Before reporting results, verify that every phase ran and that each variable it produces is captured, with STATIC_FINDINGS (`(none)` only if every tool that was to run completed clean), the report files in ANALYSIS_DIR present and `.last-analysis-head` written only if Phase 7's gate allows; run any missing phase first.
|
|
@@ -10,7 +10,11 @@ output-dir: dist/commands
|
|
|
10
10
|
@import "./_partials/_settings.mds" as settings
|
|
11
11
|
# Code Review Command
|
|
12
12
|
|
|
13
|
+
<!-- compliance:on -->
|
|
13
14
|
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into PR comments.
|
|
15
|
+
<!-- compliance:off -->
|
|
16
|
+
Run a comprehensive code review of the current branch by spawning parallel review agents, then synthesizing results into a local review summary.
|
|
17
|
+
<!-- compliance:end -->
|
|
14
18
|
|
|
15
19
|
## Usage
|
|
16
20
|
|
|
@@ -52,6 +56,9 @@ Keep each worktree's values for every downstream phase.
|
|
|
52
56
|
**Produces:** EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL
|
|
53
57
|
|
|
54
58
|
{{evidence_policy()}}
|
|
59
|
+
<!-- compliance:off -->
|
|
60
|
+
When `EVIDENCE_POLICY` is `required`, record `TRACEABILITY: DEGRADED (compliance off on this machine; the repository requires evidence)` once, for the Phase 4 report.
|
|
61
|
+
<!-- compliance:end -->
|
|
55
62
|
|
|
56
63
|
#### Step 0c: Per-Worktree Pre-Flight (Git Agent)
|
|
57
64
|
|
|
@@ -64,6 +71,7 @@ Discover PR description guidance from plan artifact (per worktree):
|
|
|
64
71
|
3. Read the most recent file that carries the section, extract `## PR Description Guidance` section
|
|
65
72
|
4. If no plan files exist or section not found, set `PR_DESCRIPTION_GUIDANCE` to `(none)`
|
|
66
73
|
|
|
74
|
+
<!-- compliance:on -->
|
|
67
75
|
Render the test-plan block (per worktree) from `/implement`'s evidence file, and from nothing else:
|
|
68
76
|
1. `branch_slug` is `git -C "{worktree}" branch --show-current` with every `/` replaced by `-`.
|
|
69
77
|
2. Only when `branch_slug` matches `^[A-Za-z0-9._-]{1,200}$` and the file exists, run (the path double-quoted):
|
|
@@ -74,6 +82,7 @@ node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{worktree}/.dev
|
|
|
74
82
|
|
|
75
83
|
3. On `exit=0`, `PR_TEST_PLAN_BLOCK` is its stdout byte for byte without that `exit=` line; in every other case it is `(none)`. Nothing here waits on it: the Git agent pastes it only behind its own check, and only into a PR it creates.
|
|
76
84
|
|
|
85
|
+
<!-- compliance:end -->
|
|
77
86
|
For each reviewable worktree, spawn Git agent:
|
|
78
87
|
|
|
79
88
|
```
|
|
@@ -81,7 +90,9 @@ Agent(subagent_type="Git", run_in_background=false):
|
|
|
81
90
|
"OPERATION: ensure-pr-ready
|
|
82
91
|
WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
83
92
|
PR_DESCRIPTION_GUIDANCE: {pr_description_guidance}
|
|
93
|
+
<!-- compliance:on -->
|
|
84
94
|
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}
|
|
95
|
+
<!-- compliance:end -->
|
|
85
96
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
86
97
|
Validate branch, commit if needed, push, create PR if needed.
|
|
87
98
|
Return: branch, base_branch, base_ref, branch-slug, PR#"
|
|
@@ -158,6 +169,7 @@ MAX_REVIEW_CYCLES = 10
|
|
|
158
169
|
| denominator = 0 OR parsing failed | fp_ratio = 0, skip warning (degraded note on parse failure) |
|
|
159
170
|
| fp_ratio > 0.7 AND CYCLE_NUMBER >= 3 | Warn in output, continue |
|
|
160
171
|
|
|
172
|
+
<!-- compliance:on -->
|
|
161
173
|
#### Step 0f: Resolve Publication Mode (Per Worktree)
|
|
162
174
|
|
|
163
175
|
**Produces:** REVIEW_PUBLICATION
|
|
@@ -167,6 +179,7 @@ For each reviewable worktree, call:
|
|
|
167
179
|
|
|
168
180
|
{{publication_gate()}}
|
|
169
181
|
|
|
182
|
+
<!-- compliance:end -->
|
|
170
183
|
### Phase 1: Analyze Changed Files
|
|
171
184
|
|
|
172
185
|
**Produces:** REVIEW_FOCUS_LIST, DIFF_CLASS, DIFF_FILES
|
|
@@ -371,12 +384,22 @@ IMPORTANT: Write report to {worktree_path}/.devflow/docs/reviews/{branch-slug}/{
|
|
|
371
384
|
|
|
372
385
|
In multi-worktree mode, process worktrees **sequentially**: Phases 1-4 for each.
|
|
373
386
|
|
|
387
|
+
<!-- compliance:on -->
|
|
374
388
|
### Phase 3: Synthesis → Review Comment (Sequential)
|
|
375
389
|
|
|
376
390
|
**Produces:** REVIEW_SUMMARY, PR_COMMENT
|
|
391
|
+
<!-- compliance:off -->
|
|
392
|
+
### Phase 3: Synthesis → Review Summary (Sequential)
|
|
393
|
+
|
|
394
|
+
**Produces:** REVIEW_SUMMARY
|
|
395
|
+
<!-- compliance:end -->
|
|
377
396
|
**Requires:** REVIEW_FOCUS_OUTPUTS, REVIEW_DIR, PR_INFO, GATE_LEVEL, REVIEW_FOCUS_LIST
|
|
378
397
|
|
|
398
|
+
<!-- compliance:on -->
|
|
379
399
|
**WAIT** for Phase 2. For each worktree, run steps 3a and 3b in sequence:
|
|
400
|
+
<!-- compliance:off -->
|
|
401
|
+
**WAIT** for Phase 2. For each worktree, run step 3a:
|
|
402
|
+
<!-- compliance:end -->
|
|
380
403
|
|
|
381
404
|
**Step 3a — Synthesize agent** per worktree:
|
|
382
405
|
```
|
|
@@ -394,6 +417,7 @@ Aggregate findings, determine merge recommendation.
|
|
|
394
417
|
Output: {worktree_path}/.devflow/docs/reviews/{branch-slug}/{timestamp}/review-summary.md"
|
|
395
418
|
```
|
|
396
419
|
|
|
420
|
+
<!-- compliance:on -->
|
|
397
421
|
**Step 3b — Git agent (post-review-summary)** per worktree (after Step 3a writes review-summary.md):
|
|
398
422
|
```
|
|
399
423
|
Agent(subagent_type="Git", run_in_background=false):
|
|
@@ -407,6 +431,7 @@ WORKTREE_PATH: {worktree_path} (omit if cwd)
|
|
|
407
431
|
Posts the consolidated review-summary comment (marker-deduped on the cycle+timestamp pair)."
|
|
408
432
|
```
|
|
409
433
|
|
|
434
|
+
<!-- compliance:end -->
|
|
410
435
|
### Phase 4: Write Review Head Marker & Report
|
|
411
436
|
|
|
412
437
|
**Requires:** BRANCH_INFO, REVIEW_DIR
|
|
@@ -416,9 +441,14 @@ Per worktree, after successful completion:
|
|
|
416
441
|
2. Display results from all agents:
|
|
417
442
|
- Merge recommendation (from Synthesize agent)
|
|
418
443
|
- Issue counts by category (🔴 blocking / ⚠️ should-fix / ℹ️ pre-existing)
|
|
444
|
+
<!-- compliance:on -->
|
|
419
445
|
- Review comment status: POSTED / POSTED+TRUNCATED (body exceeded 60k after redaction) / SKIPPED (D7 dedup) / DEGRADED (from Git)
|
|
420
446
|
- 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
447
|
- Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned
|
|
448
|
+
<!-- compliance:off -->
|
|
449
|
+
- Review summary: `.devflow/docs/reviews/{branch-slug}/{timestamp}/review-summary.md` (local; not posted)
|
|
450
|
+
- Any base `TRACEABILITY: DEGRADED` line from Step 0c, as returned, and the compliance-off line of Step 0b-ii
|
|
451
|
+
<!-- compliance:end -->
|
|
422
452
|
- Artifact paths
|
|
423
453
|
|
|
424
454
|
## Architecture
|
|
@@ -426,7 +456,11 @@ Per worktree, after successful completion:
|
|
|
426
456
|
```
|
|
427
457
|
/code-review
|
|
428
458
|
│
|
|
459
|
+
<!-- compliance:on -->
|
|
429
460
|
├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0f (Git agent per worktree, parallel)
|
|
461
|
+
<!-- compliance:off -->
|
|
462
|
+
├─ Phase 0: Worktree Discovery & Pre-flight, Steps 0a-0e (Git agent per worktree, parallel)
|
|
463
|
+
<!-- compliance:end -->
|
|
430
464
|
│ ├─ Step 0b: Resolve the compliance lens and gate level
|
|
431
465
|
│
|
|
432
466
|
├─ Per worktree (SEQUENTIAL):
|
|
@@ -440,9 +474,14 @@ Per worktree, after successful completion:
|
|
|
440
474
|
│ │ ├─ code: core (diff.patch), language (diff-{focus}.patch), conditional
|
|
441
475
|
│ │ └─ docs-only / tests-only / lockfile-only: the reduced set (diff.patch)
|
|
442
476
|
│ │
|
|
477
|
+
<!-- compliance:on -->
|
|
443
478
|
│ ├─ Phase 3: Synthesis → Review Comment (SEQUENTIAL within worktree)
|
|
444
479
|
│ │ ├─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
|
|
445
480
|
│ │ └─ Step 3b: Git agent (post-review-summary)
|
|
481
|
+
<!-- compliance:off -->
|
|
482
|
+
│ ├─ Phase 3: Synthesis → Review Summary (SEQUENTIAL within worktree)
|
|
483
|
+
│ │ └─ Step 3a: Synthesize agent (mode: review, writes review-summary.md)
|
|
484
|
+
<!-- compliance:end -->
|
|
446
485
|
│ │
|
|
447
486
|
│ └─ Phase 4: Write .last-review-head + display results
|
|
448
487
|
```
|
|
@@ -452,7 +491,9 @@ Per worktree, after successful completion:
|
|
|
452
491
|
| Case | Handling |
|
|
453
492
|
|------|----------|
|
|
454
493
|
| `--full` in multi-worktree mode | Applies to all worktrees (global modifier). It sets the diff range, never the gate level |
|
|
494
|
+
<!-- compliance:on -->
|
|
455
495
|
| Review comment already posted | Git agent matches its own marker on the `{cycle, timestamp}` pair → skip silently (D7) |
|
|
496
|
+
<!-- compliance:end -->
|
|
456
497
|
| Docs-only diff | Its Step 1.1 set, narrowed by level |
|
|
457
498
|
| Tests-only diff | Its Step 1.1 set, narrowed by level |
|
|
458
499
|
| Lockfile-only diff | Its Step 1.1 set, narrowed by level |
|
|
@@ -461,7 +502,9 @@ Per worktree, after successful completion:
|
|
|
461
502
|
| A file moved across classes | `--no-renames` lists both paths, so a code path makes the diff `code` |
|
|
462
503
|
| Path listing above about 40 lines | Read in ranges (Step 1.1) |
|
|
463
504
|
| Language files changed, plugin not installed | The focus is absent from the stamped line: not spawned |
|
|
505
|
+
<!-- compliance:on -->
|
|
464
506
|
| `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 |
|
|
507
|
+
<!-- compliance:end -->
|
|
465
508
|
|
|
466
509
|
## Backwards Compatibility
|
|
467
510
|
|