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
|
@@ -3,15 +3,11 @@ 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
|
|
6
|
+
Run a proactive bug analysis on the current branch: static analysis tools and parallel semantic analyzers, synthesized into one bug report.
|
|
7
7
|
|
|
8
8
|
## Usage
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
/bug-analysis (analyze current branch — incremental if prior analysis exists)
|
|
12
|
-
/bug-analysis --full (force full analysis, ignore incremental state)
|
|
13
|
-
/bug-analysis --no-static (skip static analysis track, semantic-only)
|
|
14
|
-
```
|
|
10
|
+
`/bug-analysis [--full] [--no-static]`: `--full` ignores incremental state; `--no-static` skips static analysis.
|
|
15
11
|
|
|
16
12
|
## Phases
|
|
17
13
|
|
|
@@ -96,7 +92,7 @@ If `pr_number` is absent, set `PR_DESCRIPTION` to `(none)`.
|
|
|
96
92
|
CHANGED_FILES=$(git diff --name-only {DIFF_RANGE})
|
|
97
93
|
```
|
|
98
94
|
|
|
99
|
-
Store as `CHANGED_FILES`;
|
|
95
|
+
Store as `CHANGED_FILES`; Phase 4 reads it. A non-zero diff exit stops.
|
|
100
96
|
|
|
101
97
|
If output is empty → "No changes to analyze." Stop.
|
|
102
98
|
|
|
@@ -104,75 +100,81 @@ If output is empty → "No changes to analyze." Stop.
|
|
|
104
100
|
|
|
105
101
|
**Produces:** STATIC_TOOL_STATUS
|
|
106
102
|
|
|
107
|
-
|
|
103
|
+
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.
|
|
108
104
|
|
|
109
105
|
```bash
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
CODEQL_AVAILABLE=$(which codeql 2>/dev/null && echo "yes" || echo "no")
|
|
106
|
+
for t in semgrep snyk codeql jq; do printf '%s=%s\n' "$t" "$(command -v "$t" || echo no)"; done
|
|
107
|
+
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"
|
|
113
108
|
```
|
|
114
109
|
|
|
115
|
-
|
|
110
|
+
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.
|
|
111
|
+
|
|
112
|
+
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.
|
|
113
|
+
|
|
114
|
+
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`.
|
|
116
115
|
|
|
117
116
|
If some are available: note which tools will run.
|
|
118
117
|
|
|
119
118
|
#### Step 2d: Tiered Static Analysis
|
|
120
119
|
|
|
121
|
-
**Produces:** STATIC_FINDINGS
|
|
120
|
+
**Produces:** STATIC_FINDINGS, STATIC_STATUS
|
|
122
121
|
**Requires:** STATIC_TOOL_STATUS, DIFF_RANGE, ANALYSIS_DIR
|
|
123
122
|
|
|
124
|
-
Skip if
|
|
123
|
+
Skip if Step 2c set `STATIC_STATUS`.
|
|
125
124
|
|
|
126
|
-
Run available
|
|
127
|
-
|
|
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.
|
|
125
|
+
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 `--`.
|
|
129
126
|
|
|
130
127
|
**Semgrep** (if available):
|
|
131
128
|
```bash
|
|
132
|
-
|
|
133
|
-
|
|
129
|
+
cd "{worktree}" || exit
|
|
130
|
+
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=$?
|
|
131
|
+
mv "{ANALYSIS_DIR}"/semgrep.{part,sarif}
|
|
132
|
+
printf '\nexit=%s\n' "$E"
|
|
134
133
|
```
|
|
135
|
-
Parse SARIF output → extract findings.
|
|
136
134
|
|
|
137
135
|
**Snyk Code** (if available):
|
|
138
136
|
```bash
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
cd "{worktree}" || exit
|
|
138
|
+
snyk code test --sarif >"{ANALYSIS_DIR}/snyk-all.json" 2>/dev/null; E=$?
|
|
139
|
+
git diff --name-only -z {DIFF_RANGE} >"{ANALYSIS_DIR}/changed.z" && jq --rawfile n "{ANALYSIS_DIR}/changed.z" \
|
|
140
|
+
'($n|split("\u0000")) as $f|.runs[]?.results|=[.[]?|select([.locations[]?.physicalLocation.artifactLocation.uri//empty] as $u|($u|length)==0 or any($u[];IN($f[])))]' \
|
|
141
|
+
"{ANALYSIS_DIR}/snyk-all.json" >"{ANALYSIS_DIR}/snyk.sarif" \
|
|
142
|
+
&& jq -nr '[inputs|[.runs[]?.results[]?]|length]|"total=\(.[0]) kept=\(.[1])"' "{ANALYSIS_DIR}/snyk-all.json" "{ANALYSIS_DIR}/snyk.sarif" \
|
|
143
|
+
|| { echo "Snyk scope filter failed: unfiltered"; cp "{ANALYSIS_DIR}/snyk-all.json" "{ANALYSIS_DIR}/snyk.sarif"; }
|
|
144
|
+
printf '\nexit=%s\n' "$E"
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Counts and table** (after Snyk with `{tools}` = `semgrep snyk`; after CodeQL with `codeql`):
|
|
148
|
+
```bash
|
|
149
|
+
cd "{ANALYSIS_DIR}" || exit
|
|
150
|
+
L='def L($r):.ruleId as $i|.level//([$r.tool|.driver,.extensions[]?|.rules[]?|select(.id==$i)]|.[0].defaultConfiguration.level)//"warning";'
|
|
151
|
+
for t in {tools}; do [ -f $t.sarif ] || continue
|
|
152
|
+
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"
|
|
153
|
+
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"
|
|
154
|
+
done
|
|
155
|
+
cat findings-{semgrep,snyk,codeql}.tsv >findings.tsv 2>/dev/null
|
|
156
|
+
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"
|
|
145
157
|
```
|
|
146
|
-
|
|
158
|
+
Read `error` as HIGH, `warning` as MEDIUM, `note` as LOW.
|
|
147
159
|
|
|
148
160
|
**CodeQL** (if available AND (`--full` OR Semgrep/Snyk found HIGH/CRITICAL findings)):
|
|
149
161
|
```bash
|
|
150
|
-
|
|
151
|
-
CODEQL_TMP=$(mktemp -d)
|
|
152
|
-
# Register cleanup trap immediately after mktemp — ensures rm -rf runs on EXIT, SIGTERM, and SIGINT
|
|
153
|
-
# even if the session is interrupted before reaching the explicit rm -rf below
|
|
162
|
+
CODEQL_TMP=$(mktemp -d) || exit
|
|
154
163
|
trap 'rm -rf "${CODEQL_TMP}"' EXIT INT TERM
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# Capture exit status before cleanup so cleanup doesn't mask failures
|
|
164
|
+
{ codeql database create "${CODEQL_TMP}/db" --language={lang} --source-root="{worktree}" && \
|
|
165
|
+
codeql database analyze "${CODEQL_TMP}/db" --format=sarif-latest --output="{ANALYSIS_DIR}/codeql.sarif"; } >"{ANALYSIS_DIR}/codeql.log" 2>&1
|
|
158
166
|
CODEQL_EXIT=$?
|
|
159
|
-
|
|
160
|
-
CODEQL_SARIF=$(cat "${CODEQL_TMP}/results.sarif" 2>/dev/null || echo "")
|
|
161
|
-
# Explicit cleanup (trap also covers this path; explicit rm is belt-and-suspenders)
|
|
167
|
+
printf '\nexit=%s\n' "$CODEQL_EXIT"
|
|
162
168
|
rm -rf "${CODEQL_TMP}"
|
|
163
169
|
trap - EXIT INT TERM
|
|
164
170
|
```
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
**Normalize** all findings to unified table, cap at top 50 by severity. Truncate each Description entry to 200 characters maximum:
|
|
171
|
+
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).
|
|
168
172
|
|
|
169
|
-
|
|
170
|
-
|------|-----------|-----|----------|-------|-------------|
|
|
171
|
-
| {tool} | {file}:{line} | {CWE or —} | {CRITICAL/HIGH/MEDIUM/LOW} | {title} | {description truncated to 200 chars} |
|
|
173
|
+
`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`.
|
|
172
174
|
|
|
173
|
-
|
|
175
|
+
`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.
|
|
174
176
|
|
|
175
|
-
|
|
177
|
+
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.
|
|
176
178
|
|
|
177
179
|
### Phase 3: Context Loading
|
|
178
180
|
|
|
@@ -285,23 +287,22 @@ A KB with no Rules section labels its entries `Rules ({section name}):` and give
|
|
|
285
287
|
#### Plan Artifact
|
|
286
288
|
|
|
287
289
|
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
|
|
288
|
-
2. Read the most recent file that carries an `## Acceptance Criteria` section
|
|
289
|
-
3.
|
|
290
|
-
4.
|
|
291
|
-
5. If no plan files exist or section not found: `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)`
|
|
290
|
+
2. Read the most recent file that carries an `## Acceptance Criteria` section; parse it into the table `| ID | Criterion | Type | Testable Condition |`
|
|
291
|
+
3. Set `PLAN_CONTEXT` to plan summary; `ACCEPTANCE_RULES` to the table
|
|
292
|
+
4. If no plan files exist or section not found: `PLAN_CONTEXT=(none)`, `ACCEPTANCE_RULES=(none)`
|
|
292
293
|
|
|
293
294
|
### Phase 4: File Analysis
|
|
294
295
|
|
|
295
296
|
**Produces:** ACTIVE_FOCUSES
|
|
296
297
|
**Requires:** DIFF_RANGE
|
|
297
298
|
|
|
298
|
-
|
|
299
|
+
Pick the focus analyzers from `CHANGED_FILES` (Step 2b; do not re-run `git diff`):
|
|
299
300
|
|
|
300
301
|
| Focus | Condition |
|
|
301
302
|
|-------|-----------|
|
|
302
303
|
| `security` | Always |
|
|
303
304
|
| `functional` | Always |
|
|
304
|
-
| `integration` | 2+ distinct directories changed
|
|
305
|
+
| `integration` | 2+ distinct directories changed |
|
|
305
306
|
| `usability` | Any `.tsx`, `.jsx`, `.html`, or `.css` file changed |
|
|
306
307
|
|
|
307
308
|
### Phase 5: Parallel Bug Analysis
|
|
@@ -319,25 +320,20 @@ FOCUS: {focus}
|
|
|
319
320
|
DIFF_COMMAND: git diff {DIFF_RANGE}
|
|
320
321
|
ACCEPTANCE_RULES: {ACCEPTANCE_RULES filtered to this focus type, or (none)}
|
|
321
322
|
PLAN_CONTEXT: {PLAN_CONTEXT}
|
|
322
|
-
STATIC_FINDINGS: {STATIC_FINDINGS if focus == security, else (none)}
|
|
323
|
+
STATIC_FINDINGS: <static-findings>{STATIC_FINDINGS if focus == security, else (none)}</static-findings>
|
|
323
324
|
DECISIONS_CONTEXT: {DECISIONS_CONTEXT}
|
|
324
325
|
FEATURE_KNOWLEDGE: {FEATURE_KNOWLEDGE}
|
|
325
326
|
PR_DESCRIPTION: <pr-description>{PR_DESCRIPTION}</pr-description>
|
|
326
327
|
OUTPUT_PATH: {ANALYSIS_DIR}/{focus}.md
|
|
327
328
|
Follow devflow:apply-decisions to Read full ADR/PF bodies on demand.
|
|
328
329
|
Follow devflow:apply-feature-knowledge for FEATURE_KNOWLEDGE.
|
|
329
|
-
IMPORTANT: Write report to
|
|
330
|
+
IMPORTANT: Write the report to OUTPUT_PATH using the Write tool"
|
|
330
331
|
```
|
|
331
332
|
|
|
332
|
-
Notes:
|
|
333
|
-
- Security analyzer receives full `STATIC_FINDINGS`; all others receive `(none)`
|
|
334
|
-
- Filter `ACCEPTANCE_RULES` by the `Type` column matching each focus: security criteria → security analyzer, functional criteria → functional analyzer, etc. Pass the filtered subset only
|
|
335
|
-
- Spawn all in a single message for true parallel execution
|
|
336
|
-
|
|
337
333
|
### Phase 6: Synthesis
|
|
338
334
|
|
|
339
335
|
**Produces:** BUG_ANALYSIS_SUMMARY
|
|
340
|
-
**Requires:** ANALYZER_OUTPUTS, ANALYSIS_DIR, BRANCH_INFO
|
|
336
|
+
**Requires:** ANALYZER_OUTPUTS, ANALYSIS_DIR, BRANCH_INFO, STATIC_STATUS
|
|
341
337
|
|
|
342
338
|
Spawn Synthesize agent:
|
|
343
339
|
|
|
@@ -347,14 +343,15 @@ Agent(subagent_type="Synthesize", run_in_background=false):
|
|
|
347
343
|
ANALYSIS_BASE_DIR: {ANALYSIS_DIR}
|
|
348
344
|
BRANCH: {branch} -> {base_branch}
|
|
349
345
|
TIMESTAMP: {timestamp}
|
|
346
|
+
STATIC_STATUS: {STATIC_STATUS}
|
|
350
347
|
Output: {ANALYSIS_DIR}/bug-analysis-summary.md"
|
|
351
348
|
```
|
|
352
349
|
|
|
353
350
|
### Phase 7: Finalize
|
|
354
351
|
|
|
355
|
-
**Requires:** BRANCH_INFO, ANALYSIS_DIR
|
|
352
|
+
**Requires:** BRANCH_INFO, ANALYSIS_DIR, STATIC_STATUS
|
|
356
353
|
|
|
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.
|
|
354
|
+
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.
|
|
358
355
|
2. Report to user:
|
|
359
356
|
|
|
360
357
|
```
|
|
@@ -363,26 +360,22 @@ Output: {ANALYSIS_DIR}/bug-analysis-summary.md"
|
|
|
363
360
|
**Branch**: {branch} -> {base_branch}
|
|
364
361
|
{any base `TRACEABILITY: DEGRADED` line from Phase 1, as returned}
|
|
365
362
|
**Analysis**: {ANALYSIS_DIR}
|
|
363
|
+
**Static analysis**: {STATIC_STATUS per tool; if a tool did not complete: "marker kept" and the way out; any Snyk filter note}
|
|
366
364
|
|
|
367
365
|
### Risk Assessment: {risk_level}
|
|
368
366
|
|
|
369
367
|
{brief_reasoning}
|
|
370
368
|
|
|
371
369
|
### Bug Counts
|
|
372
|
-
|
|
373
|
-
|----------|----------|------|--------|-----|-------|
|
|
374
|
-
| Security | {n} | {n} | {n} | {n} | {n} |
|
|
375
|
-
| Functional | {n} | {n} | {n} | {n} | {n} |
|
|
376
|
-
| Integration | {n} | {n} | {n} | {n} | {n} |
|
|
377
|
-
| Usability | {n} | {n} | {n} | {n} | {n} |
|
|
370
|
+
{The summary's Bug Summary table: Security, Functional, Integration and Usability rows by CRITICAL, HIGH, MEDIUM, LOW and Total}
|
|
378
371
|
|
|
379
372
|
### Top Findings
|
|
380
|
-
{
|
|
373
|
+
{Top 3-5 bugs by severity and confidence}
|
|
381
374
|
|
|
382
375
|
### Artifacts
|
|
383
376
|
- Bug report: {ANALYSIS_DIR}/bug-analysis-summary.md
|
|
384
|
-
- Per-focus reports: {ANALYSIS_DIR}/{
|
|
385
|
-
- Static findings: {ANALYSIS_DIR}/static-findings.md (if
|
|
377
|
+
- Per-focus reports: {ANALYSIS_DIR}/{focus}.md
|
|
378
|
+
- Static findings: {ANALYSIS_DIR}/static-findings.md (if it ran)
|
|
386
379
|
|
|
387
380
|
{if any CRITICAL or HIGH bugs found:}
|
|
388
381
|
Run `/resolve` to process and fix these findings.
|
|
@@ -390,70 +383,26 @@ Run `/resolve` to process and fix these findings.
|
|
|
390
383
|
|
|
391
384
|
## Architecture
|
|
392
385
|
|
|
393
|
-
|
|
394
|
-
/bug-analysis (orchestrator — spawns agents only)
|
|
395
|
-
│
|
|
396
|
-
├─ Phase 1: Pre-flight
|
|
397
|
-
│ └─ Git agent (ensure-pr-ready)
|
|
398
|
-
│
|
|
399
|
-
├─ Phase 2: Static Analysis
|
|
400
|
-
│ └─ 2a incremental range, 2b changed files (stop if none), 2c tools, 2d semgrep → snyk → codeql
|
|
401
|
-
│
|
|
402
|
-
├─ Phase 3: Context Loading
|
|
403
|
-
│ ├─ index.md (pre-rendered) → DECISIONS_CONTEXT
|
|
404
|
-
│ ├─ Feature knowledge load → FEATURE_KNOWLEDGE
|
|
405
|
-
│ └─ {worktree}/.devflow/docs/design/*.md → PLAN_CONTEXT + ACCEPTANCE_RULES
|
|
406
|
-
│
|
|
407
|
-
├─ Phase 4: File Analysis
|
|
408
|
-
│ └─ Detect active focuses (security + functional always; integration + usability conditional)
|
|
409
|
-
│
|
|
410
|
-
├─ Phase 5: Bug Analysis (PARALLEL)
|
|
411
|
-
│ └─ Debug agent per active focus (security also reads STATIC_FINDINGS)
|
|
412
|
-
│
|
|
413
|
-
├─ Phase 6: Synthesis
|
|
414
|
-
│ └─ Synthesize agent (mode: bug-analysis)
|
|
415
|
-
│
|
|
416
|
-
└─ Phase 7: Finalize
|
|
417
|
-
├─ Write .last-analysis-head
|
|
418
|
-
└─ Display results + suggest /resolve if blocking bugs found
|
|
419
|
-
```
|
|
386
|
+
Seven phases: Phase 1 to Phase 7.
|
|
420
387
|
|
|
421
388
|
## Edge Cases
|
|
422
389
|
|
|
423
390
|
| Case | Handling |
|
|
424
391
|
|------|----------|
|
|
425
|
-
| No new commits since last analysis | Stop: "No new commits since last analysis. Use --full for a full re-analysis." |
|
|
426
392
|
| Rebase invalidates `.last-analysis-head` SHA | `git cat-file -t` check fails → fallback to full diff |
|
|
427
393
|
| Zero changed files in DIFF_RANGE with exit 0 | Stop: "No changes to analyze." |
|
|
428
|
-
| Same-minute analysis collision | `mkdir` with seconds suffix (`YYYY-MM-DD_HHMMSS`) |
|
|
429
|
-
| All static tools unavailable | Warn, proceed with semantic-only analysis |
|
|
430
|
-
| `--no-static` flag | Skip Phase 2c and 2d entirely; `STATIC_FINDINGS=(none)` |
|
|
431
394
|
| `--full` flag | Bypass incremental detection (Step 2a), run full diff from base |
|
|
432
|
-
|
|
|
395
|
+
| 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 |
|
|
433
396
|
|
|
434
397
|
## Resolve Compatibility
|
|
435
398
|
|
|
436
|
-
|
|
399
|
+
`/resolve` detects and uses bug analysis reports when no code review report exists.
|
|
437
400
|
|
|
438
401
|
## Principles
|
|
439
402
|
|
|
440
|
-
1. **Orchestration only** —
|
|
441
|
-
2. **
|
|
442
|
-
3. **Static + semantic** — Two complementary tracks, each validates the other
|
|
443
|
-
4. **Incremental by default** — Only analyze new changes unless `--full` specified
|
|
444
|
-
5. **Verify before reporting** — Debug agents self-verify every finding
|
|
445
|
-
6. **Honest reporting** — Display risk level and counts directly from synthesis
|
|
403
|
+
1. **Orchestration only** — the command spawns agents and does no analysis itself
|
|
404
|
+
2. **Incremental by default** — only new changes, unless `--full`
|
|
446
405
|
|
|
447
406
|
## Phase Completion Checklist
|
|
448
407
|
|
|
449
|
-
Before reporting results, verify every phase was
|
|
450
|
-
|
|
451
|
-
- [ ] Phase 1: Pre-flight → BRANCH_INFO captured, PR_DESCRIPTION fetched (or `(none)`)
|
|
452
|
-
- [ ] Phase 2: Static Analysis → STATIC_FINDINGS captured (or `(none)` if skipped/no tools/no findings); ANALYSIS_DIR created; CHANGED_FILES populated
|
|
453
|
-
- [ ] Phase 3: Context Loading → DECISIONS_CONTEXT captured, FEATURE_KNOWLEDGE loaded (or `(none)`), PLAN_CONTEXT and ACCEPTANCE_RULES captured (or `(none)`)
|
|
454
|
-
- [ ] Phase 4: File Analysis → ACTIVE_FOCUSES determined (security + functional always present)
|
|
455
|
-
- [ ] Phase 5: Parallel Bug Analysis → ANALYZER_OUTPUTS captured per active focus; all reports written to ANALYSIS_DIR
|
|
456
|
-
- [ ] Phase 6: Synthesis → BUG_ANALYSIS_SUMMARY written to `{ANALYSIS_DIR}/bug-analysis-summary.md`
|
|
457
|
-
- [ ] Phase 7: Finalize → `.last-analysis-head` updated; results displayed to user
|
|
458
|
-
|
|
459
|
-
If any phase is unchecked, execute it before proceeding.
|
|
408
|
+
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.
|
|
@@ -155,7 +155,7 @@ The following agentType values are valid. Model tiers are shown for reference
|
|
|
155
155
|
Before authoring, verify:
|
|
156
156
|
|
|
157
157
|
1. **Workflow tool available:** if the `Workflow` tool is not in your available tools, STOP and tell the user: "The Workflow tool is not available in this session. dynamic-build requires Claude Code's dynamic workflow runtime."
|
|
158
|
-
2. **`agentType` support:**
|
|
158
|
+
2. **`agentType` support:** if spawned agents return no results, check that devflow is installed (`devflow init` has been run).
|
|
159
159
|
3. **Tracker paths:** an issue reference or URL in the input is read through the Git agent, which resolves the configured tracker and its access itself and reports `TRACEABILITY: DEGRADED ({reason})` when it cannot read one — then note it and fall back to the issue text the user provided. No tracker CLI is checked here.
|
|
160
160
|
4. **No-remote path:** if the repo has no remote, skip the remote-dependent steps (the wave PR and its evidence) and proceed with local branch operations only; the Git agent reports DEGRADED for any tracker step it cannot reach.
|
|
161
161
|
|
|
@@ -357,7 +357,7 @@ After implementing, commit your changes with a conventional-commit message and r
|
|
|
357
357
|
);
|
|
358
358
|
|
|
359
359
|
// Phase 3: Gate 1 #1 — post-code pipeline: Polish agent → Harden agent → Validate agent.
|
|
360
|
-
// Validate runs last and unconditionally, so its one full run covers every commit the pass made
|
|
360
|
+
// Validate runs last and unconditionally, so its one full run covers every commit the pass made.
|
|
361
361
|
const gate1 = await phase("gate1", async () => {
|
|
362
362
|
await agent(`Polish and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Polish" });
|
|
363
363
|
|
|
@@ -416,8 +416,7 @@ Criteria: ${CRITERIA || "see plan"}
|
|
|
416
416
|
Return: {"verdict": "PASS" | "FAIL", "rationale": "..."} — FAIL if either answer is no, naming the failing criterion or the drift.`, { agentType: "Evaluate" });
|
|
417
417
|
evalVerdict = evaluation?.verdict === "PASS" ? "PASS" : "FAIL";
|
|
418
418
|
if (evalVerdict === "FAIL") {
|
|
419
|
-
// fix-and-continue — no re-evaluate, no inline Gate 1.
|
|
420
|
-
// after the review pass is the build gate before the branch is handed back.
|
|
419
|
+
// fix-and-continue — no re-evaluate, no inline Gate 1.
|
|
421
420
|
await agent(`OPERATION: alignment-fix
|
|
422
421
|
Fix the alignment issues identified by the Evaluate agent on branch ${BRANCH}:
|
|
423
422
|
${evaluation?.rationale || "see the Evaluate agent's report"}
|
|
@@ -434,17 +433,19 @@ Self-verify your fix compiles, following your Running commands block. Commit fix
|
|
|
434
433
|
${CRITERIA || "(none)"}
|
|
435
434
|
TEST_PLAN: ${TEST_PLAN || "(none)"}
|
|
436
435
|
Follow your Running commands block for every scenario command.
|
|
437
|
-
Cover: functionality, API contracts, performance, and cover every TEST_PLAN scenario.
|
|
438
|
-
|
|
436
|
+
Cover: functionality, API contracts, performance, and cover every TEST_PLAN scenario.
|
|
437
|
+
Return: {"verdict": "PASS" | "FAIL" | "BLOCKED", "failures": "..."}`, { agentType: "Test" });
|
|
438
|
+
const word = testResult?.verdict?.split?.(/[ (]/)[0];
|
|
439
|
+
testVerdict = ["PASS", "FAIL"].includes(word) ? word : "BLOCKED";
|
|
439
440
|
if (testVerdict === "FAIL") {
|
|
440
441
|
// fix-and-continue — no re-test, no inline Gate 1.
|
|
441
442
|
await agent(`OPERATION: qa-fix
|
|
442
443
|
Fix the failing acceptance test scenarios on branch ${BRANCH}:
|
|
443
|
-
${testResult.failures}
|
|
444
|
+
${testResult.failures || "see the Test agent's report"}
|
|
444
445
|
DECISIONS_CONTEXT: ${DECISIONS_CONTEXT}
|
|
445
446
|
${COMPLIANCE_DIRECTIVE}
|
|
446
447
|
Self-verify your fix compiles and the scenarios pass, following your Running commands block. Commit fixes.`, { agentType: "Fix" });
|
|
447
|
-
testVerdict = "FAIL-FIXED";
|
|
448
|
+
testVerdict = "FAIL-FIXED";
|
|
448
449
|
}
|
|
449
450
|
}
|
|
450
451
|
|
|
@@ -590,8 +591,6 @@ Return: {"status": "fixed"|"blocked", "commitShas": ["<sha>"], "unresolved": ["<
|
|
|
590
591
|
});
|
|
591
592
|
|
|
592
593
|
// Phase 5.5: Gate 1 #2 — FINAL post-fix gate (Polish agent → Harden agent → full Validate agent, Validate last and unconditional).
|
|
593
|
-
// Runs ONCE, after the review pass. Inside the pass the Code agent self-verified its own fixes;
|
|
594
|
-
// this is the build gate before the branch is handed back. See gate1_postcode() cadence.
|
|
595
594
|
const gate1Final = await phase("gate1-final", async () => {
|
|
596
595
|
await agent(`Polish and reduce complexity of recent changes on branch ${BRANCH}. Commit any improvements.`, { agentType: "Polish" });
|
|
597
596
|
|
|
@@ -626,9 +625,9 @@ Return: {"verdict": "PASS" | "FAIL", "details": "..."}`, { agentType: "Validate"
|
|
|
626
625
|
});
|
|
627
626
|
|
|
628
627
|
// PASS requires survivingFindings.length === 0 && coverageGaps.length === 0 && gate1Final.verdict !== "ESCALATED"
|
|
629
|
-
// and
|
|
628
|
+
// and every Gate 2 verdict PASS or SKIPPED; any other reports UNVERIFIED, never PASS
|
|
630
629
|
const coverageGaps = reviewResult.coverageGaps || [];
|
|
631
|
-
const gate2Unverified = [gate2.evaluateVerdict, gate2.testVerdict].
|
|
630
|
+
const gate2Unverified = ![gate2.evaluateVerdict, gate2.testVerdict].every(v => v === "PASS" || v === "SKIPPED");
|
|
632
631
|
const overallVerdict = (reviewResult.survivingFindings?.length || 0) === 0 && coverageGaps.length === 0 && gate1Final.verdict !== "ESCALATED" ? (gate2Unverified ? "UNVERIFIED" : "PASS") : "PARTIAL";
|
|
633
632
|
|
|
634
633
|
// Phase 6: Report — the phase returns the engine result (engine_output_schema); its verdict is overallVerdict
|
|
@@ -674,17 +673,17 @@ This applies to both: multiple Code agents working on a single ticket AND multi-
|
|
|
674
673
|
|
|
675
674
|
### Build execution doctrine — the Running commands block (LOAD-BEARING)
|
|
676
675
|
|
|
677
|
-
The
|
|
676
|
+
The Code, Fix, Refactor, Validate and Test agents each carry this `## Running commands` block in their bodies, so each prompt in this engine names the block ("your Running commands block") instead of copying it:
|
|
678
677
|
|
|
679
678
|
Run builds, typechecks, lints and tests in the foreground, each with an explicit Bash `timeout` above its expected run time. The ceiling is 600000 ms, or `BASH_MAX_TIMEOUT_MS` when set (`echo ${BASH_MAX_TIMEOUT_MS:-600000}`).
|
|
680
679
|
|
|
681
|
-
- Capture, then tail, in one Bash call
|
|
682
|
-
- Never background a
|
|
683
|
-
- Prefer the scoped command for the change
|
|
684
|
-
- A run
|
|
685
|
-
- A run expected to exceed the ceiling
|
|
680
|
+
- Capture, then tail, in one Bash call: `LOG=$(mktemp); echo "LOG=$LOG"; <command> >"$LOG" 2>&1; rc=$?; tail -n 40 "$LOG"; printf '\nEXIT=%s\n' "$rc"`. The last `EXIT=` line is the result; never decide one from a grep count.
|
|
681
|
+
- Never background a build or test, and never poll across turns: no `sleep` or `true` turns, no sentinel-file checks, no Monitor.
|
|
682
|
+
- Prefer the scoped command for the change; for the whole set, one workspace command over per-package loops.
|
|
683
|
+
- A run past its timeout moves to the background: no tool call, even a Read, until its end notice, then Read the last `EXIT=` line of the file the move names, not `$LOG`; it alone sets the label, not the notice. With none read it is BLOCKED: report its duration and log path. Report only after the end notice.
|
|
684
|
+
- A run expected to exceed the ceiling may be split into parts, run in sequence.
|
|
686
685
|
- Never re-run a command when nothing it reads has changed.
|
|
687
|
-
- Never wrap a build or test command in `sh -c`, `bash -c`, `python3 -c` or `node -e`: permission rules deny wrapped commands they
|
|
686
|
+
- Never wrap a build or test command in `sh -c`, `bash -c`, `python3 -c` or `node -e`: permission rules deny wrapped commands they allow directly.
|
|
688
687
|
- The same rules hold inside a dynamic Workflow sub-agent.
|
|
689
688
|
|
|
690
689
|
**Cheapest-sufficient validation:** iterate with the fastest check that proves the change — `tsc --noEmit`, `cargo check`, `go vet`, a single test file — the ecosystem's cheapest sufficient signal. Reserve expensive full/optimized builds and whole-suite runs for the final gates only.
|
|
@@ -742,6 +741,7 @@ Gate 2 inputs are produced by `/devflow:dynamic-plan`'s plan-challenge step —
|
|
|
742
741
|
**Test agent** (only if acceptance criteria or a test plan exist):
|
|
743
742
|
- Scenario-based acceptance tests covering functionality, API contracts, performance
|
|
744
743
|
- FAIL → fix-and-continue — a Fix agent applies the demanded fixes and self-verifies its own build. The recorded verdict becomes `FAIL-FIXED`; Gate 2 then proceeds. In SINGLE mode the run reports it as `UNVERIFIED`, never PASS.
|
|
744
|
+
- BLOCKED (no result), or any other or missing verdict → no fix, and the run never reports PASS.
|
|
745
745
|
|
|
746
746
|
**When Gate 2 inputs are absent:**
|
|
747
747
|
- No plan → skip the Evaluate agent silently (note in output: "Gate 2 Evaluate agent skipped — no plan available")
|
|
@@ -910,7 +910,7 @@ Each ticket engine run returns a structured result. The Synthesize agent or the
|
|
|
910
910
|
],
|
|
911
911
|
"gate2": {
|
|
912
912
|
"evaluateVerdict": "PASS | FAIL | FAIL-FIXED | SKIPPED",
|
|
913
|
-
"testVerdict": "PASS | FAIL | FAIL-FIXED | SKIPPED",
|
|
913
|
+
"testVerdict": "PASS | FAIL | FAIL-FIXED | SKIPPED | BLOCKED",
|
|
914
914
|
"skipReasons": ["string — why a gate was skipped, if applicable"]
|
|
915
915
|
}
|
|
916
916
|
}
|
|
@@ -1228,12 +1228,12 @@ Agent(subagent_type="Test"):
|
|
|
1228
1228
|
FILES_CHANGED: {the file list that diff printed}
|
|
1229
1229
|
TEST_PLAN: {the TP lines of the wave evidence file's ## Test Plan section}
|
|
1230
1230
|
WORKTREE_PATH: {integration worktree root}
|
|
1231
|
-
Cover every TEST_PLAN line on the integration branch as it stands. Report
|
|
1231
|
+
Cover every TEST_PLAN line on the integration branch as it stands. Report your Status with evidence."
|
|
1232
1232
|
```
|
|
1233
1233
|
|
|
1234
|
-
Nothing is fixed here,
|
|
1234
|
+
Nothing is fixed here, whatever the Status: the wave is done and its PR is open. Report the Test agent's Status.
|
|
1235
1235
|
|
|
1236
|
-
**(b) Claims.** Append its TP claims,
|
|
1236
|
+
**(b) Claims.** Append its TP claims, whatever its Status, to the `## Claims` section of `"{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md"` — the file's last section, created when absent. Append only: never edit or remove a claim. Each line is `/implement`'s TP claim, keyed to the 40-hex `HEAD:` the Test agent's report shows:
|
|
1237
1237
|
|
|
1238
1238
|
```
|
|
1239
1239
|
- TP-<n> <PASS|FAIL|SKIP> sha:<head> by:test exit:<0-255>
|