devflow-kit 3.0.1 → 3.2.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 +49 -0
- package/README.md +1 -1
- package/dist/agents/git.md +2 -2
- package/dist/cli/agents-view/index.js +1 -1
- package/dist/cli/agents-view/render.js +71 -17
- package/dist/cli/agents-view/state.js +42 -16
- package/dist/cli/agents-view/terminal.js +5 -5
- package/dist/cli/commands/agents.js +142 -51
- package/dist/cli/commands/ambient.js +1 -1
- package/dist/cli/commands/attribution-prompts.js +8 -8
- package/dist/cli/commands/capture.js +1 -1
- package/dist/cli/commands/compliance-prompts.js +8 -8
- package/dist/cli/commands/compliance.js +8 -7
- package/dist/cli/commands/flags.js +33 -31
- package/dist/cli/commands/hud.js +1 -1
- package/dist/cli/commands/init-seed.js +9 -9
- package/dist/cli/commands/init.js +162 -85
- package/dist/cli/commands/install-report.js +10 -10
- package/dist/cli/commands/learning.js +302 -136
- package/dist/cli/commands/memory.js +36 -15
- package/dist/cli/commands/proxy.js +23 -23
- package/dist/cli/commands/rules.js +6 -5
- package/dist/cli/commands/tracker-prompts.js +6 -6
- package/dist/cli/commands/tracker.js +9 -9
- package/dist/cli/commands/uninstall.js +183 -59
- package/dist/cli/flags-view/render.js +5 -5
- package/dist/cli/flags-view/state.js +9 -9
- package/dist/cli/flags-view/terminal.js +4 -4
- package/dist/cli/tui/cells.js +1 -1
- package/dist/cli/tui/terminal.js +6 -6
- package/dist/commands/code-review.md +0 -2
- package/dist/commands/debug.md +14 -11
- package/dist/commands/dynamic-build.md +51 -47
- package/dist/commands/dynamic-plan.md +27 -7
- package/dist/commands/dynamic-profile.md +17 -3
- package/dist/commands/dynamic-tickets.md +18 -4
- package/dist/commands/explore.md +9 -3
- package/dist/commands/implement.md +20 -16
- package/dist/commands/plan.md +13 -9
- package/dist/commands/release.md +23 -3
- package/dist/commands/research.md +9 -3
- package/dist/commands/resolve.md +9 -12
- package/dist/commands/self-review.md +0 -2
- package/dist/core/agent-frontmatter.js +28 -3
- package/dist/core/agent-models.js +204 -42
- package/dist/core/agent-state.js +28 -6
- package/dist/core/ansi.js +2 -2
- package/dist/core/assets.js +1 -1
- package/dist/core/cache.js +7 -8
- package/dist/core/codex-auth-inspect.js +4 -4
- package/dist/core/compliance-compose.js +3 -3
- package/dist/core/compliance.js +3 -4
- package/dist/core/evidence-policy.js +14 -13
- package/dist/core/external-models.js +1 -1
- package/dist/core/feature-config.js +71 -13
- package/dist/core/feature-switch.js +3 -3
- package/dist/core/flags.js +49 -25
- package/dist/core/fs-atomic.js +6 -7
- package/dist/core/learning-queue-cleanup.js +16 -81
- package/dist/core/learning-store.js +61 -0
- package/dist/core/linked-path.js +46 -0
- package/dist/core/manifest.js +5 -5
- package/dist/core/mds-variants.js +13 -13
- package/dist/core/model-discovery.js +8 -8
- package/dist/core/observations.js +17 -101
- package/dist/core/orphan-sweep.js +4 -4
- package/dist/core/plugins.js +13 -8
- package/dist/core/project-paths.js +9 -13
- package/dist/core/proxy-log.js +8 -8
- package/dist/core/proxy-state.js +3 -3
- package/dist/core/queue-drain.js +31 -0
- package/dist/core/reference-sweep.js +6 -6
- package/dist/core/teammate-mode-cleanup.js +1 -1
- package/dist/core/tracker.js +14 -14
- package/dist/hud/colors.js +2 -2
- package/dist/hud/components/learning-counts.js +54 -22
- package/dist/hud/components/version-badge.js +1 -1
- package/dist/skills/git/references/pr/resolve-review-threads.md +2 -2
- package/dist/skills/git/references/tracker/github/create-release.md +2 -2
- package/dist/skills/git/references/tracker/jira/create-release.md +2 -2
- package/dist/skills/git/references/tracker/linear/create-release.md +2 -2
- package/dist/targets/claude-code/compliance-install.js +17 -15
- package/dist/targets/claude-code/hooks.js +2 -2
- package/dist/targets/claude-code/installer.js +59 -32
- package/dist/targets/claude-code/legacy.js +1 -1
- package/dist/targets/claude-code/post-install.js +135 -45
- package/dist/targets/claude-code/tracker-install.js +2 -2
- package/package.json +1 -1
- package/src/assets/agents/code.md +15 -21
- package/src/assets/agents/design.md +4 -2
- package/src/assets/agents/diagnose.md +3 -1
- package/src/assets/agents/evaluate.md +4 -0
- package/src/assets/agents/git.mds +2 -2
- package/src/assets/agents/knowledge.md +5 -3
- package/src/assets/agents/learning.md +281 -196
- package/src/assets/agents/research.md +3 -1
- package/src/assets/agents/review.md +5 -3
- package/src/assets/agents/scrutinize.md +5 -1
- package/src/assets/agents/simplify.md +4 -0
- package/src/assets/agents/skim.md +4 -2
- package/src/assets/agents/synthesize.md +6 -0
- package/src/assets/agents/test.md +18 -10
- package/src/assets/agents/triage.md +11 -9
- package/src/assets/agents/validate.md +14 -10
- package/src/assets/commands/_partials/_decisions.mds +8 -3
- package/src/assets/commands/_partials/_docs_root.mds +3 -3
- package/src/assets/commands/_partials/_engine.mds +16 -32
- package/src/assets/commands/_partials/_knowledge.mds +0 -2
- package/src/assets/commands/_partials/_preamble.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +2 -2
- package/src/assets/commands/_partials/_tracker.mds +1 -1
- package/src/assets/commands/code-review.mds +0 -2
- package/src/assets/commands/debug.mds +13 -8
- package/src/assets/commands/dynamic-build.mds +18 -12
- package/src/assets/commands/dynamic-plan.mds +10 -4
- package/src/assets/commands/dynamic-profile.mds +1 -1
- package/src/assets/commands/dynamic-tickets.mds +2 -2
- package/src/assets/commands/explore.mds +9 -1
- package/src/assets/commands/implement.mds +19 -13
- package/src/assets/commands/plan.mds +12 -8
- package/src/assets/commands/release.md +23 -3
- package/src/assets/commands/research.mds +9 -3
- package/src/assets/commands/resolve.mds +9 -10
- package/src/assets/mds/git/_pr.mds +3 -3
- package/src/assets/mds/tracker/_common.mds +1 -1
- package/src/assets/mds/tracker/_github.mds +3 -3
- package/src/assets/mds/tracker/_jira.mds +3 -3
- package/src/assets/mds/tracker/_linear.mds +3 -3
- package/src/assets/mds/tracker/_mcp.mds +6 -5
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +4 -2
- package/src/assets/scripts/hooks/background-memory-update +97 -33
- package/src/assets/scripts/hooks/capture-prompt +4 -3
- package/src/assets/scripts/hooks/capture-question +4 -3
- package/src/assets/scripts/hooks/capture-turn +5 -20
- package/src/assets/scripts/hooks/ensure-devflow-init +14 -2
- package/src/assets/scripts/hooks/ensure-proxy +5 -6
- package/src/assets/scripts/hooks/ensure-root-gitignore +123 -11
- package/src/assets/scripts/hooks/git-marker +71 -0
- package/src/assets/scripts/hooks/is-hex-sha +1 -1
- package/src/assets/scripts/hooks/json-helper.cjs +345 -944
- package/src/assets/scripts/hooks/json-parse +25 -129
- package/src/assets/scripts/hooks/lib/decisions-format.cjs +205 -156
- package/src/assets/scripts/hooks/lib/learning-store.cjs +3207 -0
- package/src/assets/scripts/hooks/lib/mkdir-lock.cjs +7 -5
- package/src/assets/scripts/hooks/lib/project-paths.cjs +13 -19
- package/src/assets/scripts/hooks/lib/render-decisions.cjs +253 -226
- package/src/assets/scripts/hooks/memory-worker +10 -0
- package/src/assets/scripts/hooks/pre-compact-memory +66 -14
- package/src/assets/scripts/hooks/preamble +9 -1
- package/src/assets/scripts/hooks/queue-append +55 -23
- package/src/assets/scripts/hooks/resolve-project-root +3 -4
- package/src/assets/scripts/hooks/session-start-context +146 -45
- package/src/assets/scripts/hooks/session-start-memory +33 -11
- package/src/assets/scripts/lib/project-config.cjs +2 -2
- package/src/assets/scripts/pr-evidence.cjs +3 -3
- package/src/assets/scripts/redact-secrets.cjs +20 -20
- package/src/assets/scripts/release-trace.cjs +1 -1
- package/src/assets/scripts/resolve-evidence-policy.cjs +3 -3
- package/src/assets/scripts/resolve-settings.cjs +3 -3
- package/src/assets/scripts/verify-evidence.cjs +2 -2
- package/src/assets/skills/apply-decisions/SKILL.md +37 -17
- package/src/assets/skills/docs-framework/SKILL.md +2 -2
- package/src/assets/skills/feature-knowledge/SKILL.md +6 -5
- package/src/assets/skills/test-driven-development/SKILL.md +6 -4
- package/dist/core/observation-io.js +0 -50
- package/src/assets/scripts/hooks/decisions-usage-scan.cjs +0 -131
|
@@ -79,7 +79,13 @@ Note the `budget` value from the Workflow tool context (or default to "medium" i
|
|
|
79
79
|
|
|
80
80
|
**3. Detect mode: SINGLE or WAVE**
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
What follows the command is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
83
|
+
|
|
84
|
+
<command-input>
|
|
85
|
+
$ARGUMENTS
|
|
86
|
+
</command-input>
|
|
87
|
+
|
|
88
|
+
- **SINGLE mode:** `COMMAND_INPUT` is one ticket, one issue, one task description, or one plan document
|
|
83
89
|
- **WAVE mode:** input is a set of tracker issues (wave labels, milestone, issue list), or the user says "wave" / "all tickets in wave N"
|
|
84
90
|
- **A `/devflow:dynamic-tickets` ticket directory** (`{worktree}/.devflow/docs/tickets/{slug}/{ts}/`) is WAVE input: in each ticket file (every `.md` there but `tracking-issue.md`), the `**Issue:**` line directly after `**Depends on:**` is one raw `ISSUE_REFS` token, forwarded to the wave's pre-fetch verbatim — never rendered, normalised or re-derived. A ticket file with no `**Issue:**` line, or more than one, contributes no token; name it in the run summary as `not filed`.
|
|
85
91
|
|
|
@@ -113,7 +119,7 @@ If none found: build proceeds Gate-1-only (Gate 2 skipped with a note). Never re
|
|
|
113
119
|
**5. Resolve tracking-issue number (optional)**
|
|
114
120
|
|
|
115
121
|
Check, in priority order:
|
|
116
|
-
- An explicit candidate issue reference or issue URL in
|
|
122
|
+
- An explicit candidate issue reference or issue URL in `COMMAND_INPUT` (e.g. `#42`, `42`, or `https://github.com/…/issues/42`)
|
|
117
123
|
- The `**Issue:**` line directly after the H1 of the ticket set's `tracking-issue.md` (written by `/devflow:dynamic-tickets`' filing step; the file is at `{worktree}/.devflow/docs/tickets/{slug}/{ts}/tracking-issue.md`), as a raw token — only when the file holds exactly one `**Issue:**` line
|
|
118
124
|
- Otherwise: none
|
|
119
125
|
|
|
@@ -194,7 +200,7 @@ ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
|
194
200
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
195
201
|
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
196
202
|
|
|
197
|
-
When you build or run tests to verify your work,
|
|
203
|
+
When you build or run tests to verify your work, follow your Running commands block.
|
|
198
204
|
|
|
199
205
|
After implementing, commit your changes with a conventional-commit message and report:
|
|
200
206
|
- Files changed
|
|
@@ -206,7 +212,7 @@ After implementing, commit your changes with a conventional-commit message and r
|
|
|
206
212
|
const gate1 = await phase("gate1", async () => {
|
|
207
213
|
// Gate 1 #1 — runs once, immediately after the initial implementation.
|
|
208
214
|
const validation = await agent(`Run build, typecheck, lint, and tests on branch ${BRANCH}.
|
|
209
|
-
|
|
215
|
+
Follow your Running commands block for every build and test command.
|
|
210
216
|
Report: PASS or FAIL with details.`, { agentType: "Validate" });
|
|
211
217
|
|
|
212
218
|
if (validation.verdict === "FAIL") {
|
|
@@ -261,7 +267,7 @@ ${panel.filter(p => p.verdict === "FAIL").map(p => p.rationale).join("\n")}
|
|
|
261
267
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
262
268
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
263
269
|
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
264
|
-
Self-verify your fix compiles
|
|
270
|
+
Self-verify your fix compiles, following your Running commands block. Commit fixes.`, { agentType: "Code" });
|
|
265
271
|
evalVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
|
|
266
272
|
}
|
|
267
273
|
}
|
|
@@ -271,7 +277,7 @@ Self-verify your fix compiles (background-Bash + Monitor for any build >120s —
|
|
|
271
277
|
const testResult = await agent(`Run scenario-based acceptance tests on branch ${BRANCH} against these criteria:
|
|
272
278
|
${CRITERIA || "(none)"}
|
|
273
279
|
TEST_PLAN: ${TEST_PLAN || "(none)"}
|
|
274
|
-
|
|
280
|
+
Follow your Running commands block for every scenario command.
|
|
275
281
|
Cover: functionality, API contracts, performance, and cover every TEST_PLAN scenario. Report: PASS or FAIL per scenario.`, { agentType: "Test" });
|
|
276
282
|
testVerdict = testResult.verdict;
|
|
277
283
|
if (testVerdict === "FAIL") {
|
|
@@ -281,7 +287,7 @@ ${testResult.failures}
|
|
|
281
287
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
282
288
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
283
289
|
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
284
|
-
Self-verify your fix compiles and the scenarios pass
|
|
290
|
+
Self-verify your fix compiles and the scenarios pass, following your Running commands block. Commit fixes.`, { agentType: "Code" });
|
|
285
291
|
testVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
|
|
286
292
|
}
|
|
287
293
|
}
|
|
@@ -395,7 +401,7 @@ ${chunk.map(f => `- ${f.description} (${f.severity})`).join("\n")}
|
|
|
395
401
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
396
402
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
397
403
|
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
398
|
-
Fix all findings in this batch. Self-verify your fix compiles
|
|
404
|
+
Fix all findings in this batch. Self-verify your fix compiles, following your Running commands block. Commit with conventional-commit message.
|
|
399
405
|
Return: {"status": "fixed"|"blocked", "commitShas": ["<sha>"], "unresolved": ["<description of any finding that could not be fixed>"]}`, { agentType: "Code" });
|
|
400
406
|
chunkResults.push({ chunk, result: r });
|
|
401
407
|
}
|
|
@@ -435,7 +441,7 @@ Return: {"status": "fixed"|"blocked", "commitShas": ["<sha>"], "unresolved": ["<
|
|
|
435
441
|
// this is the build gate before the branch is handed back. See gate1_postcode() cadence.
|
|
436
442
|
const gate1Final = await phase("gate1-final", async () => {
|
|
437
443
|
const validation = await agent(`Run build, typecheck, lint, and tests on branch ${BRANCH} (final gate after all fixing).
|
|
438
|
-
|
|
444
|
+
Follow your Running commands block for every build and test command.
|
|
439
445
|
Report: PASS or FAIL with details.`, { agentType: "Validate" });
|
|
440
446
|
|
|
441
447
|
if (validation.verdict === "FAIL") {
|
|
@@ -447,7 +453,7 @@ ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
|
447
453
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
448
454
|
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
449
455
|
Self-verify your fix compiles. Commit fixes with conventional-commit message.`, { agentType: "Code" });
|
|
450
|
-
const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (
|
|
456
|
+
const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (follow your Running commands block). Report: PASS or FAIL.`, { agentType: "Validate" });
|
|
451
457
|
if (recheck.verdict === "PASS") break;
|
|
452
458
|
failureDetails = recheck.details || failureDetails;
|
|
453
459
|
if (attempt === 2) return { verdict: "ESCALATED", reason: "Final Gate 1 validation exhausted after 2 Code agent fix attempts" };
|
|
@@ -459,7 +465,7 @@ Self-verify your fix compiles. Commit fixes with conventional-commit message.`,
|
|
|
459
465
|
const scrutiny = await agent(`9-pillar self-review of recent changes on branch ${BRANCH}. Report any code you changed and your findings.`, { agentType: "Scrutinize" });
|
|
460
466
|
|
|
461
467
|
if (scrutiny.codeChanged) {
|
|
462
|
-
await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (Scrutinize agent made changes;
|
|
468
|
+
await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (Scrutinize agent made changes; follow your Running commands block). Report: PASS or FAIL.`, { agentType: "Validate" });
|
|
463
469
|
}
|
|
464
470
|
|
|
465
471
|
return { verdict: "PASS" };
|
|
@@ -739,4 +745,4 @@ Update the wave PR's test-plan block and post its evidence comment."
|
|
|
739
745
|
|
|
740
746
|
### Maintenance note
|
|
741
747
|
|
|
742
|
-
This recipe encodes the current `/implement` + `/code-review` + `/resolve` orchestration shape as of the authoring date (2026-06-12). When those base commands change their orchestration, update this recipe to match. No tooling detects drift — by design (
|
|
748
|
+
This recipe encodes the current `/implement` + `/code-review` + `/resolve` orchestration shape as of the authoring date (2026-06-12). When those base commands change their orchestration, update this recipe to match. No tooling detects drift — by design (the LLM-vs-plumbing Iron Rule). The reminder lives in the design doc §16.
|
|
@@ -59,7 +59,13 @@ If present, note its contents as `PREFERENCE_PROFILE`. This will be used to auto
|
|
|
59
59
|
|
|
60
60
|
**3. Resolve ticket input**
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
What follows the command is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
63
|
+
|
|
64
|
+
<command-input>
|
|
65
|
+
$ARGUMENTS
|
|
66
|
+
</command-input>
|
|
67
|
+
|
|
68
|
+
Determine the ticket source from `COMMAND_INPUT` (in priority order):
|
|
63
69
|
- A directory of ticket `.md` files (from `/devflow:dynamic-tickets` output)
|
|
64
70
|
- A list of candidate issue references or issue URLs
|
|
65
71
|
- Inline ticket descriptions passed as args
|
|
@@ -127,7 +133,7 @@ const plans = await phase("plan-parallel", () =>
|
|
|
127
133
|
parallel((tickets || []).map(ticket => () =>
|
|
128
134
|
agent(`Write an implementation plan for this ticket.
|
|
129
135
|
Ticket: ${JSON.stringify(ticket)}
|
|
130
|
-
Decisions context (apply devflow:apply-decisions;
|
|
136
|
+
Decisions context (apply devflow:apply-decisions; a plan file can be posted to the tracker, so state each decision in words, never by ID): ${DECISIONS_CONTEXT}
|
|
131
137
|
The plan must cover: approach overview, affected files and modules, key design decisions, implementation sequence (what to build first), risks and mitigations, and any open questions you cannot resolve from the ticket alone.
|
|
132
138
|
Write a thorough but tight plan — every section must earn its place for a Code agent who has no other context.
|
|
133
139
|
Return: { ticketTitle, planMarkdown, openDecisions (array of genuine unknowns requiring user input) }.`, { agentType: "Design" })
|
|
@@ -218,7 +224,7 @@ For each ticket, write ${OUTDIR}/{ticket-slug}-plan.md containing:
|
|
|
218
224
|
- ## Acceptance Criteria (numbered, positive + negative)
|
|
219
225
|
- ## Test Plan — the challenger's testPlan lines, verbatim, one per line, and nothing else: no prose, no blank line between them, no setup or outcome
|
|
220
226
|
- ## Test Scenarios — one line per TP, in TP order: TP-n: its setup, then its expected outcome, from testScenarios
|
|
221
|
-
- ## Auto-Resolved Decisions (if any — list each as: decision → resolution → source)
|
|
227
|
+
- ## Auto-Resolved Decisions (if any — list each as: decision → resolution → source, naming a recorded decision in words, never by ID)
|
|
222
228
|
|
|
223
229
|
Then write ${OUTDIR}/DECISIONS-NEEDED.md:
|
|
224
230
|
- ## Auto-Resolved Decisions — list each silently-resolved decision as: decision → resolution → source (preference profile / ADR-NNN), so auto-resolution is auditable and reversible. If none, write "None."
|
|
@@ -268,4 +274,4 @@ After the workflow returns: check each plan's test plan (step 1 of the F4 list a
|
|
|
268
274
|
|
|
269
275
|
### Maintenance note
|
|
270
276
|
|
|
271
|
-
This recipe encodes the planning pipeline as of the authoring date (2026-06-12). The plan-challenge verbatim intent (§5.1) is load-bearing — do not paraphrase it when authoring the challenger agent prompt. The "Acceptance criteria + test plan contract" section above is the shared shape with `/devflow:dynamic-build` Gate 2; any change must be kept in sync. No tooling detects drift — by design (
|
|
277
|
+
This recipe encodes the planning pipeline as of the authoring date (2026-06-12). The plan-challenge verbatim intent (§5.1) is load-bearing — do not paraphrase it when authoring the challenger agent prompt. The "Acceptance criteria + test plan contract" section above is the shared shape with `/devflow:dynamic-build` Gate 2; any change must be kept in sync. No tooling detects drift — by design (the LLM-vs-plumbing Iron Rule).
|
|
@@ -142,4 +142,4 @@ Next steps:
|
|
|
142
142
|
|
|
143
143
|
### Maintenance note
|
|
144
144
|
|
|
145
|
-
This command mines ALL projects' history on this machine. The bounded-reading discipline (grep/rg + sample — never full-read) is mandatory and must be preserved in every revision. The agent writes prose; no extraction or clustering algorithm is authored here. Per
|
|
145
|
+
This command mines ALL projects' history on this machine. The bounded-reading discipline (grep/rg + sample — never full-read) is mandatory and must be preserved in every revision. The agent writes prose; no extraction or clustering algorithm is authored here. Per the LLM-vs-plumbing Iron Rule: the agent does the reading and summarizing — not a script we maintain.
|
|
@@ -105,7 +105,7 @@ const drafts = await phase("draft", () =>
|
|
|
105
105
|
agent(`Draft ticket for initiative: "${initiative}"
|
|
106
106
|
Ticket: ${JSON.stringify(c)}
|
|
107
107
|
Constraints: ${constraints}
|
|
108
|
-
Decisions context (apply devflow:apply-decisions;
|
|
108
|
+
Decisions context (apply devflow:apply-decisions; the ticket is filed to the tracker, so state each decision in words, never by ID): ${DECISIONS_CONTEXT}
|
|
109
109
|
Write the ticket body following the ticket_body_template structure (Wave/Depends-on header, Summary, Scope with In/Out + anti-features, Invariants, numbered Acceptance Criteria with at least one negative criterion, Open Questions).
|
|
110
110
|
Return a JSON object with: title (string), summary (string), wave (number), dependsOn (array), bodyMarkdown (string), openQuestions (array).`, { agentType: "Design" })
|
|
111
111
|
))
|
|
@@ -270,4 +270,4 @@ The tracking-issue path and any open questions are the primary handoff to `/devf
|
|
|
270
270
|
|
|
271
271
|
### Maintenance note
|
|
272
272
|
|
|
273
|
-
This recipe encodes the ticket-factory shape as of the authoring date (2026-06-12). The pipeline structure (`draft → [2-lens review] → revise → whole-set critic → amend → tracking-issue`) is the load-bearing invariant. Per
|
|
273
|
+
This recipe encodes the ticket-factory shape as of the authoring date (2026-06-12). The pipeline structure (`draft → [2-lens review] → revise → whole-set critic → amend → tracking-issue`) is the load-bearing invariant. Per the LLM-vs-plumbing Iron Rule, no deterministic ticket-parsing logic is added — ticket slates are proposed by the model and confirmed by the user. When the devflow agent roster changes, update the `agentType` values above. No tooling detects drift — by design, under the same rule.
|
|
@@ -18,7 +18,13 @@ Explore a codebase area by spawning parallel agents for flow tracing, dependency
|
|
|
18
18
|
|
|
19
19
|
## Input
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
What follows `/explore` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
22
|
+
|
|
23
|
+
<command-input>
|
|
24
|
+
$ARGUMENTS
|
|
25
|
+
</command-input>
|
|
26
|
+
|
|
27
|
+
`COMMAND_INPUT` is one of:
|
|
22
28
|
- Area description: "how does the auth system work"
|
|
23
29
|
- Flow question: "trace the request lifecycle"
|
|
24
30
|
- Empty: use conversation context
|
|
@@ -58,6 +64,8 @@ Based on Skim agent findings, spawn 2-3 `Agent(subagent_type="Explore")` agents
|
|
|
58
64
|
|
|
59
65
|
Adjust explorer focus based on the specific exploration question.
|
|
60
66
|
|
|
67
|
+
Ask each explorer for a final report of at most about 1,500 tokens: findings with file:line references, not file dumps.
|
|
68
|
+
|
|
61
69
|
### Phase 4: Synthesize
|
|
62
70
|
|
|
63
71
|
**Produces:** MERGED_FINDINGS
|
|
@@ -25,7 +25,13 @@ Orchestrate a single task through implementation by spawning specialized agents.
|
|
|
25
25
|
|
|
26
26
|
## Input
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
What follows `/implement` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
29
|
+
|
|
30
|
+
<command-input>
|
|
31
|
+
$ARGUMENTS
|
|
32
|
+
</command-input>
|
|
33
|
+
|
|
34
|
+
`COMMAND_INPUT` is one of:
|
|
29
35
|
- Plan document path: `.devflow/docs/design/42-jwt-auth.2026-04-07_1430.md` (path to an existing `.md` file)
|
|
30
36
|
- Issue reference: `#42`
|
|
31
37
|
- Task description: "implement JWT auth"
|
|
@@ -53,15 +59,13 @@ If the user prompt does NOT match re-validation, proceed with the full pipeline
|
|
|
53
59
|
|
|
54
60
|
**Produces:** TASK_ID, BASE_BRANCH, EXECUTION_PLAN, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE, PR_DESCRIPTION_GUIDANCE, ISSUE_NUMBER, EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL, PR_EXCEPTIONS, TEST_PLAN, EVIDENCE_FILE, PR_TEST_PLAN_BLOCK, REVIEW_PUBLICATION
|
|
55
61
|
|
|
56
|
-
**Load Companion Skills** — Load via Skill tool: `devflow:test-driven-development`, `devflow:patterns`, `devflow:dependency-research`. If a skill fails to load, continue without it.
|
|
57
|
-
|
|
58
62
|
Record the current branch name as `BASE_BRANCH` - this will be the PR target.
|
|
59
63
|
|
|
60
64
|
{{docs_root()}}
|
|
61
65
|
|
|
62
66
|
{{evidence_policy()}}
|
|
63
67
|
|
|
64
|
-
**Plan Document Handling** (when
|
|
68
|
+
**Plan Document Handling** (when `COMMAND_INPUT` is a path ending in `.md`):
|
|
65
69
|
1. Read the plan document from the path provided
|
|
66
70
|
2. Extract from YAML frontmatter: `execution-strategy`, `context-risk`, `issue` number
|
|
67
71
|
3. Extract from body: Subtask Breakdown, Implementation Plan, Patterns to Follow, Acceptance Criteria
|
|
@@ -72,23 +76,25 @@ Record the current branch name as `BASE_BRANCH` - this will be the PR target.
|
|
|
72
76
|
|
|
73
77
|
If `PR_DESCRIPTION_GUIDANCE` was not set above (non-plan paths: issue input or task description), set it to `(none)`.
|
|
74
78
|
|
|
79
|
+
**Empty input.** When `COMMAND_INPUT` is empty — a plan handoff arrives this way, with the plan already in the conversation — there is no argument to name the branch from, and the Git agent sees none of this conversation. Write the description yourself: one line, taken from the plan's title or, with no plan, from the conversation. Send it as the setup-task `TASK_DESCRIPTION` below.
|
|
80
|
+
|
|
75
81
|
Spawn Git agent to set up task environment. The Git agent derives the branch name automatically from the issue or task description:
|
|
76
82
|
|
|
77
83
|
```
|
|
78
84
|
Agent(subagent_type="Git"):
|
|
79
85
|
"OPERATION: setup-task
|
|
80
86
|
BASE_BRANCH: {current branch name}
|
|
81
|
-
ISSUE_INPUT: {
|
|
82
|
-
TASK_DESCRIPTION: {
|
|
87
|
+
ISSUE_INPUT: {COMMAND_INPUT verbatim, when it is a single whitespace-delimited token that does not end in .md; when it ends in .md, the plan frontmatter's issue value verbatim unless absent or pending — otherwise omit}
|
|
88
|
+
TASK_DESCRIPTION: {COMMAND_INPUT verbatim, when it is two or more whitespace-delimited tokens; when COMMAND_INPUT is empty, the one-line description you wrote above — otherwise omit}
|
|
83
89
|
ISSUE_REQUIRED: {ISSUE_REQUIRED}
|
|
84
90
|
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
85
|
-
PLAN_ARTIFACT_PATH: {path to plan document if
|
|
91
|
+
PLAN_ARTIFACT_PATH: {path to plan document if COMMAND_INPUT ends in .md, otherwise (none)}
|
|
86
92
|
Derive branch name from issue or description, create feature branch, and fetch issue if specified.
|
|
87
93
|
Return the branch setup summary."
|
|
88
94
|
```
|
|
89
95
|
|
|
90
96
|
The issue token is forwarded **unclassified**, and the routing is decided by
|
|
91
|
-
SHAPE alone — how many tokens
|
|
97
|
+
SHAPE alone — how many tokens `COMMAND_INPUT` has, and whether it ends in `.md`.
|
|
92
98
|
|
|
93
99
|
`setup-task` is the one step that has resolved a provider, and therefore the only
|
|
94
100
|
one that knows what an issue reference looks like on this machine: `#123`,
|
|
@@ -133,7 +139,7 @@ visible, a silently discarded request is not.
|
|
|
133
139
|
|
|
134
140
|
**Test plan.** Before any Code spawn, give the task a test plan in the evidence file `{worktree}/.devflow/docs/evidence-{branch_slug}.md` (`EVIDENCE_FILE`) — unlike the handoff file, it stays after the PR exists. It holds up to three sections, in this order and nothing else: `## Test Plan`; `## Evidence Exceptions`, a byte copy of `PR_EXCEPTIONS` present only while that is not `(none)`; and `## Claims`, always last, so every claim is appended at the end of the file. Create the file if absent; if it exists, replace its `## Test Plan` and `## Evidence Exceptions` sections and keep `## Claims` byte-identical.
|
|
135
141
|
|
|
136
|
-
Write the `## Test Plan` section: when
|
|
142
|
+
Write the `## Test Plan` section: when `COMMAND_INPUT` is a plan document with a `## Test Plan` section, copy that section's lines verbatim; otherwise write one TP line per acceptance criterion the plan, the issue or the task text states, numbered from `TP-1`. Never invent a criterion, and word every scenario yourself in plain words: the lines reach the PR body, so a scenario holds no `#`, `@` or `/` — no issue reference, mention, closing keyword target or URL — and the files a TP covers go in its `files:` field. Each line follows the TP-line contract:
|
|
137
143
|
|
|
138
144
|
{{test_plan_line()}}
|
|
139
145
|
|
|
@@ -314,7 +320,7 @@ ISSUE_PR_LINK: {ISSUE_PR_LINK captured in Phase 1, or (none)}"
|
|
|
314
320
|
After Code agent completes, spawn Validate agent to verify correctness:
|
|
315
321
|
|
|
316
322
|
```
|
|
317
|
-
Agent(subagent_type="Validate"
|
|
323
|
+
Agent(subagent_type="Validate"):
|
|
318
324
|
"FILES_CHANGED: {list of files from Code agent output}
|
|
319
325
|
VALIDATION_SCOPE: full
|
|
320
326
|
Run build, typecheck, lint, test. Report pass/fail with failure details."
|
|
@@ -394,7 +400,7 @@ If Scrutinize agent returns BLOCKED, report to user and halt.
|
|
|
394
400
|
If Scrutinize agent made code changes (status: FIXED), spawn Validate agent to verify:
|
|
395
401
|
|
|
396
402
|
```
|
|
397
|
-
Agent(subagent_type="Validate"
|
|
403
|
+
Agent(subagent_type="Validate"):
|
|
398
404
|
"FILES_CHANGED: {files modified by Scrutinize agent}
|
|
399
405
|
VALIDATION_SCOPE: changed-only
|
|
400
406
|
Verify Scrutinize agent's fixes didn't break anything."
|
|
@@ -442,7 +448,7 @@ Validate alignment with request and plan. Report ALIGNED or MISALIGNED with deta
|
|
|
442
448
|
```
|
|
443
449
|
- Spawn Validate agent to verify fix didn't break tests:
|
|
444
450
|
```
|
|
445
|
-
Agent(subagent_type="Validate"
|
|
451
|
+
Agent(subagent_type="Validate"):
|
|
446
452
|
"FILES_CHANGED: {files modified by fix Code agent}
|
|
447
453
|
VALIDATION_SCOPE: changed-only"
|
|
448
454
|
```
|
|
@@ -490,7 +496,7 @@ After every Test agent run — PASS or FAIL, first run or retry — append its T
|
|
|
490
496
|
```
|
|
491
497
|
- Spawn Validate agent to verify fix didn't break tests:
|
|
492
498
|
```
|
|
493
|
-
Agent(subagent_type="Validate"
|
|
499
|
+
Agent(subagent_type="Validate"):
|
|
494
500
|
"FILES_CHANGED: {files modified by fix Code agent}
|
|
495
501
|
VALIDATION_SCOPE: changed-only"
|
|
496
502
|
```
|
|
@@ -26,7 +26,13 @@ The orchestrator only spawns agents and gates — all analytical work is done by
|
|
|
26
26
|
|
|
27
27
|
## Input
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
What follows `/plan` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
30
|
+
|
|
31
|
+
<command-input>
|
|
32
|
+
$ARGUMENTS
|
|
33
|
+
</command-input>
|
|
34
|
+
|
|
35
|
+
`COMMAND_INPUT` is one of:
|
|
30
36
|
- Opens with a candidate issue reference → issue mode (one candidate = single-ref, more than one = multi-issue)
|
|
31
37
|
- Path to existing `.md` file → **error**: "Use /implement with plan documents"
|
|
32
38
|
- Other text → feature description
|
|
@@ -66,7 +72,7 @@ Explore the user's intent through focused Socratic questioning before spawning a
|
|
|
66
72
|
|
|
67
73
|
**Step 0 — Fetch issue(s)** (issue mode only; skip for feature-description and empty modes):
|
|
68
74
|
|
|
69
|
-
- **Single-ref** (one candidate ref in
|
|
75
|
+
- **Single-ref** (one candidate ref in `COMMAND_INPUT`):
|
|
70
76
|
|
|
71
77
|
```
|
|
72
78
|
Agent(subagent_type="Git"):
|
|
@@ -106,8 +112,6 @@ If the user says "skip" or "just proceed" — skip remaining questions, present
|
|
|
106
112
|
**Produces:** SKIM_CONTEXT, DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
|
|
107
113
|
**Requires:** CONFIRMED_SCOPE
|
|
108
114
|
|
|
109
|
-
**Load Companion Skills** — Load via Skill tool: `devflow:test-driven-development`, `devflow:patterns`, `devflow:software-design`, `devflow:security`, `devflow:design-review`. If a skill fails to load, continue without it.
|
|
110
|
-
|
|
111
115
|
Spawn Skim agent for codebase context:
|
|
112
116
|
|
|
113
117
|
```
|
|
@@ -136,7 +140,7 @@ Pass `FEATURE_KNOWLEDGE` alongside `DECISIONS_CONTEXT` to Explore and Design age
|
|
|
136
140
|
**Produces:** EXPLORE_OUTPUTS
|
|
137
141
|
**Requires:** SKIM_CONTEXT, DECISIONS_CONTEXT
|
|
138
142
|
|
|
139
|
-
Spawn 4 Explore agents **in a single message**, each with Skim agent context, `DECISIONS_CONTEXT` (from Phase 2), and `FEATURE_KNOWLEDGE` (from Phase 2). Include instructions: "follow `devflow:apply-decisions` for DECISIONS_CONTEXT" and "The FEATURE_KNOWLEDGE is a baseline — VALIDATE, EXTEND, and CORRECT it, don't repeat it. Focus on areas the feature knowledge doesn't cover and changes since it was last updated."
|
|
143
|
+
Spawn 4 Explore agents **in a single message**, each with Skim agent context, `DECISIONS_CONTEXT` (from Phase 2), and `FEATURE_KNOWLEDGE` (from Phase 2). Include instructions: "follow `devflow:apply-decisions` for DECISIONS_CONTEXT" and "The FEATURE_KNOWLEDGE is a baseline — VALIDATE, EXTEND, and CORRECT it, don't repeat it. Focus on areas the feature knowledge doesn't cover and changes since it was last updated." Ask each agent for a final report of at most about 1,500 tokens: findings with file:line references, not file dumps.
|
|
140
144
|
|
|
141
145
|
| Focus | Thoroughness | Find |
|
|
142
146
|
|-------|-------------|------|
|
|
@@ -265,7 +269,7 @@ User can:
|
|
|
265
269
|
**Produces:** IMPL_EXPLORE_OUTPUTS
|
|
266
270
|
**Requires:** SKIM_CONTEXT, ACCEPTED_SCOPE
|
|
267
271
|
|
|
268
|
-
Spawn 4 Explore agents **in a single message**, each with Skim agent context + accepted scope:
|
|
272
|
+
Spawn 4 Explore agents **in a single message**, each with Skim agent context + accepted scope. Ask each agent for a final report of at most about 1,500 tokens: findings with file:line references, not file dumps.
|
|
269
273
|
|
|
270
274
|
| Focus | Thoroughness | Find |
|
|
271
275
|
|-------|-------------|------|
|
|
@@ -294,7 +298,7 @@ Combine into: patterns to follow, integration points, reusable code, edge cases"
|
|
|
294
298
|
**Produces:** PLAN_OUTPUTS
|
|
295
299
|
**Requires:** IMPL_EXPLORATION_SYNTHESIS, GAP_SYNTHESIS, DECISIONS_CONTEXT
|
|
296
300
|
|
|
297
|
-
Spawn 3 Plan agents **in a single message**, each with implementation exploration synthesis:
|
|
301
|
+
Spawn 3 Plan agents **in a single message**, each with implementation exploration synthesis. Ask each agent for a final report of at most about 1,500 tokens: the plan itself, not a restatement of the exploration.
|
|
298
302
|
|
|
299
303
|
| Focus | Output |
|
|
300
304
|
|-------|--------|
|
|
@@ -470,7 +474,7 @@ Spawn a Git agent with `OPERATION: ensure-traceable-issue`:
|
|
|
470
474
|
```
|
|
471
475
|
Agent(subagent_type="Git"):
|
|
472
476
|
"OPERATION: ensure-traceable-issue
|
|
473
|
-
ISSUE_INPUT: {the raw candidate token from
|
|
477
|
+
ISSUE_INPUT: {the raw candidate token from COMMAND_INPUT if /plan was invoked with an issue reference, else omit}
|
|
474
478
|
TASK_DESCRIPTION: {Gate 0 confirmed scope — one-line title}
|
|
475
479
|
INITIAL_REQUEST: {the Gate 0 confirmed scope statement}
|
|
476
480
|
REQUIREMENTS: {discovered requirements summary from Phase 6 gap synthesis}
|
|
@@ -17,13 +17,19 @@ Release the project using adaptive learned configuration. On first run, scans th
|
|
|
17
17
|
|
|
18
18
|
## Input
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
What follows `/release` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
21
|
+
|
|
22
|
+
<command-input>
|
|
23
|
+
$ARGUMENTS
|
|
24
|
+
</command-input>
|
|
25
|
+
|
|
26
|
+
`COMMAND_INPUT` is one of:
|
|
21
27
|
- Explicit version: `v1.2.3` or `1.2.3`
|
|
22
28
|
- Bump type: `patch`, `minor`, `major`
|
|
23
29
|
- Flag: `--dry-run`
|
|
24
30
|
- Empty: interactive mode (will ask for version)
|
|
25
31
|
|
|
26
|
-
Parse from
|
|
32
|
+
Parse from `COMMAND_INPUT`:
|
|
27
33
|
- `VERSION`: explicit version string if present (strip leading `v`)
|
|
28
34
|
- `BUMP_TYPE`: `patch | minor | major` if bump type provided
|
|
29
35
|
- `DRY_RUN`: true if `--dry-run` present, false otherwise
|
|
@@ -48,7 +54,21 @@ Read `.release/RELEASE-FLOW.md`:
|
|
|
48
54
|
|
|
49
55
|
**Produces:** DECISIONS_CONTEXT, FEATURE_KNOWLEDGE
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
The decisions ledger belongs to the repository, not to one checkout: in a linked worktree it lives in the main worktree, and a session started in a subdirectory reads the copy at the repository root. Locate it with ONE git call, run from the start directory — `WORKTREE_PATH` if provided, otherwise cwd (`devflow:worktree-support`):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git -C "{start}" rev-parse --path-format=absolute --show-toplevel --git-common-dir
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Line 1 is the checkout's toplevel, line 2 the repository's common git directory. A git older than 2.31 echoes `--path-format=absolute` back as a line of its own first. `{ledger}` is the first of these that applies:
|
|
64
|
+
|
|
65
|
+
1. **The main worktree** — line 2 without its trailing `/.git`, when the output is exactly two lines each beginning with `/`, line 2 ends in `/.git`, and the directory left once it is removed is not your home directory and contains a `.devflow/` directory.
|
|
66
|
+
2. **The toplevel** — line 1, or on an older git the line after the echoed flag.
|
|
67
|
+
3. **The start directory itself** — when the command failed or printed no absolute toplevel (outside a git repository).
|
|
68
|
+
|
|
69
|
+
This is the rule the learning hooks apply (D-LEDGER-MAIN-WORKTREE, D-PROMPT-ROOT), so you read the index the Learning agent writes.
|
|
70
|
+
|
|
71
|
+
Read `{ledger}/.devflow/learning/index.md`. If the file is absent or empty, set `DECISIONS_CONTEXT` to `(none)`; otherwise use the file content as `DECISIONS_CONTEXT`.
|
|
52
72
|
|
|
53
73
|
Load feature knowledge: Attempt to read `.devflow/features/index.md` (the regenerable cache). If absent or empty, glob `.devflow/features/*/KNOWLEDGE.md` and read each file's YAML frontmatter (`name`, `description`, `directories`) as the relevance surface. Pick release-relevant KBs by matching their documented area against the release context. For each selected KB, read the full `KNOWLEDGE.md` — trust current code over KB content on any mismatch. Concatenate under slug headers and set `FEATURE_KNOWLEDGE` (or `(none)` if no KBs exist or none are relevant). No `index.json`, no subprocess, no `.cjs` script.
|
|
54
74
|
|
|
@@ -20,7 +20,13 @@ Research a topic by spawning parallel Research agents across multiple research t
|
|
|
20
20
|
|
|
21
21
|
## Input
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
What follows `/research` is bound once, here. Every later step names it `COMMAND_INPUT` and never restates it:
|
|
24
|
+
|
|
25
|
+
<command-input>
|
|
26
|
+
$ARGUMENTS
|
|
27
|
+
</command-input>
|
|
28
|
+
|
|
29
|
+
`COMMAND_INPUT` is one of:
|
|
24
30
|
- Research question: "best caching strategies"
|
|
25
31
|
- Comparison question: "compare React vs Svelte for our use case"
|
|
26
32
|
- Empty: use conversation context
|
|
@@ -35,7 +41,7 @@ Research a topic by spawning parallel Research agents across multiple research t
|
|
|
35
41
|
|
|
36
42
|
{{decisions_load()}}
|
|
37
43
|
|
|
38
|
-
Use `DECISIONS_CONTEXT` locally when framing research — prior decisions and pitfalls suggest areas to investigate. Follow `devflow:apply-decisions` to Read full entry bodies on demand. Pass `DECISIONS_CONTEXT` to each Research agent in Phase 4 so
|
|
44
|
+
Use `DECISIONS_CONTEXT` locally when framing research — prior decisions and pitfalls suggest areas to investigate. Follow `devflow:apply-decisions` to Read full entry bodies on demand. Pass `DECISIONS_CONTEXT` to each Research agent in Phase 4 so their findings can account for relevant decisions.
|
|
39
45
|
|
|
40
46
|
{{knowledge_load()}}
|
|
41
47
|
|
|
@@ -111,7 +117,7 @@ If external research was skipped due to tool unavailability: inform user.
|
|
|
111
117
|
1. If `codebase` type was not in RESEARCH_PLAN → skip
|
|
112
118
|
2. Check if matching feature knowledge already exists by reading `{worktree}/.devflow/features/index.md` (or globbing frontmatter if absent). If covered → skip
|
|
113
119
|
3. Use AskUserQuestion: "No feature knowledge exists for {researched area}. Create one?"
|
|
114
|
-
4. If user accepts: spawn `Agent(subagent_type="Knowledge")` with researched area context + worktree root, instructing it to
|
|
120
|
+
4. If user accepts: spawn `Agent(subagent_type="Knowledge")` with researched area context + worktree root, instructing it to write `KNOWLEDGE.md` and update `index.md` directly
|
|
115
121
|
5. Set FEATURE_KNOWLEDGE_STATUS = created or skipped
|
|
116
122
|
|
|
117
123
|
**Failure handling**: Non-blocking. If Knowledge agent fails, log and continue.
|
|
@@ -180,14 +180,14 @@ Wait for Triage agent to complete before proceeding. Parse verdict ledger from T
|
|
|
180
180
|
- **ESCALATED**: Security issues requiring human escalation
|
|
181
181
|
- **FIX_NOW**: Valid issues assigned to Code agents (with risk tier: Standard | Careful)
|
|
182
182
|
- **FALSE_POSITIVE**: Issues the Review agent got wrong (with cited evidence)
|
|
183
|
-
- **BY_DESIGN**: Intentional code (with
|
|
183
|
+
- **BY_DESIGN**: Intentional code (with a recorded decision, stated in words, or a code doc citation)
|
|
184
184
|
- **FIX_SEPARATE**: Valid but out of blast-radius scope (must become manage-debt ticket)
|
|
185
185
|
- **TECH_DEBT**: Architectural overhaul only — LAST RESORT
|
|
186
186
|
- **DUPLICATE**: Collapsed duplicate issue — carries `duplicate_of: <primary-id>` referencing the non-DUPLICATE primary; inherits the primary's outcome
|
|
187
187
|
|
|
188
|
-
Collect
|
|
188
|
+
Collect every decision and pitfall the Triage agent's Reasoning columns state, in its words — the resolution summary is posted, so it never carries an ADR/PF ID.
|
|
189
189
|
|
|
190
|
-
**Triage agent completeness assertion
|
|
190
|
+
**Triage agent completeness assertion:** Verify the parsed ledger against ISSUES before proceeding:
|
|
191
191
|
1. Every issue `id` from ISSUES must appear in exactly one verdict bucket — none may vanish, none may appear in multiple buckets. DUPLICATE is a valid bucket; a valid DUPLICATE entry must name its `duplicate_of` primary (the `Duplicate Of` column of the ledger's DUPLICATE table) and that primary must be a non-DUPLICATE issue id. A missing `duplicate_of` or one that chains to another DUPLICATE is a **Triage agent failure** (retry-then-abort as below).
|
|
192
192
|
2. If the Triage agent output is empty, contains a skill re-entrancy guard string (e.g., contains `already running`), or is missing any issue IDs from ISSUES: treat as a **Triage agent failure**:
|
|
193
193
|
- Retry the Triage agent once with the same inputs.
|
|
@@ -275,7 +275,7 @@ If no fixes were made (CODE_AGENT_RESULTS contains 0 commits) → set VERIFICATI
|
|
|
275
275
|
Otherwise, spawn Validate agent:
|
|
276
276
|
|
|
277
277
|
```
|
|
278
|
-
Agent(subagent_type="Validate"
|
|
278
|
+
Agent(subagent_type="Validate"):
|
|
279
279
|
"FILES_CHANGED: {list of files from Code agent output}
|
|
280
280
|
VALIDATION_SCOPE: full
|
|
281
281
|
Run build, typecheck, lint, test. Report pass/fail with failure details."
|
|
@@ -401,7 +401,7 @@ Run this step only when `EVIDENCE_POLICY` is `required` and THREAD_MAP is non-em
|
|
|
401
401
|
|
|
402
402
|
Prepare THREAD_MAP with verdicts from triage/code agent results:
|
|
403
403
|
- For each `ext-{N}`: match to an issue verdict (FIXED, FALSE_POSITIVE, BY_DESIGN, ESCALATED) by `file:line` correlation
|
|
404
|
-
- If the matched issue has verdict DUPLICATE, use the **primary's** verdict and verification status for the reply — do not expose DUPLICATE to the thread author (
|
|
404
|
+
- If the matched issue has verdict DUPLICATE, use the **primary's** verdict and verification status for the reply — do not expose DUPLICATE to the thread author (caller-side mapping: the Git agent's verdict set has no DUPLICATE, so its contract stays unchanged)
|
|
405
405
|
- Include `commit_sha` from Code agent results for FIXED verdicts
|
|
406
406
|
- If `fork_no_push` is set: drop FIXED entries from THREAD_MAP — their commits never reached the PR — and record each as `DEGRADED` in `## Third-Party Threads`
|
|
407
407
|
- Unmatched threads: ESCALATED (human review)
|
|
@@ -642,8 +642,7 @@ Written in Phase 5 (Collect Results) to `{TARGET_DIR}/resolution-summary.md`:
|
|
|
642
642
|
|
|
643
643
|
## Decisions Citations
|
|
644
644
|
|
|
645
|
-
-
|
|
646
|
-
- avoids PF-{NNN} — {batch-id}, {issue-id}
|
|
645
|
+
- {decision applied or pitfall avoided, stated in words — never its ID} — {batch-id}, {issue-id}
|
|
647
646
|
|
|
648
647
|
(Omit section if no citations were made)
|
|
649
648
|
|
|
@@ -681,9 +680,9 @@ Final gate: PASS | FAILED after {n} attempts
|
|
|
681
680
|
| {description} | {file}:{line} | {why} |
|
|
682
681
|
|
|
683
682
|
## By Design
|
|
684
|
-
| Issue | File:Line | Rationale (
|
|
685
|
-
|
|
686
|
-
| {description} | {file}:{line} | {
|
|
683
|
+
| Issue | File:Line | Rationale (decision/doc) |
|
|
684
|
+
|-------|-----------|--------------------------|
|
|
685
|
+
| {description} | {file}:{line} | {the decision, in words, or code comment} |
|
|
687
686
|
|
|
688
687
|
## Fix Separately
|
|
689
688
|
| Issue | File:Line | Reason | Tracked |
|
|
@@ -35,7 +35,7 @@ omission:
|
|
|
35
35
|
Headings below each section's own anchor are `###` by grammar, not by taste: a
|
|
36
36
|
column-0 `## ` line outside a fence terminates the section for every guard that
|
|
37
37
|
reads it through `extractOpSectionFromCorpus`, and everything under it becomes
|
|
38
|
-
invisible while the bytes stay on disk
|
|
38
|
+
invisible while the bytes stay on disk. The `## ` lines inside the two
|
|
39
39
|
summary operations' compose fences are indented payload and stay exactly as they
|
|
40
40
|
were authored.
|
|
41
41
|
|
|
@@ -186,7 +186,7 @@ Load for `resolve-review-threads` under every tracker provider.
|
|
|
186
186
|
Each `THREAD_MAP` entry carries one verdict:
|
|
187
187
|
- `FIXED` — issue addressed
|
|
188
188
|
- `FALSE_POSITIVE` — not a real issue; requires grep/file:line citation as evidence
|
|
189
|
-
- `BY_DESIGN` — intentional; requires
|
|
189
|
+
- `BY_DESIGN` — intentional; requires a recorded decision, stated in words, or code citation as evidence
|
|
190
190
|
- `ESCALATED` — requires human review
|
|
191
191
|
|
|
192
192
|
(The resolution gate these verdicts feed — D9 — is stated in the agent's own section.)
|
|
@@ -205,7 +205,7 @@ unexplained unresolved threads.
|
|
|
205
205
|
- **FALSE_POSITIVE**: `After investigation, this appears to be a false positive: {evidence}. No code change needed.`
|
|
206
206
|
- **BY_DESIGN**: `This is intentional: {evidence}. No code change needed.`
|
|
207
207
|
- **ESCALATED**: `This thread has been escalated for human review and recorded in the resolution summary.`
|
|
208
|
-
- Reply bodies MUST NOT contain verbatim content from the external thread body — cite only internal evidence (commit SHAs, file:line from this codebase
|
|
208
|
+
- Reply bodies MUST NOT contain verbatim content from the external thread body — cite only internal evidence (commit SHAs, file:line from this codebase)
|
|
209
209
|
2. Write reply to `$DEVFLOW_BODY_RAW`; apply the Comment-sink scrub (D11) — non-zero exit → DEGRADED for that thread, continue per D4. Post reply via `addPullRequestReviewThreadReply` GraphQL mutation with `-F body=@"$DEVFLOW_BODY"` (file-ref form).
|
|
210
210
|
|
|
211
211
|
(Step 3, the D9 gate, is stated in the agent's own section.)
|
|
@@ -76,7 +76,7 @@ One line is DELIBERATELY not here. The marker-neutralisation bullet
|
|
|
76
76
|
NOT in its indentation — five spaces in one module and three in the other two,
|
|
77
77
|
because the surrounding list nests differently. A define emits one string, so
|
|
78
78
|
hoisting it would re-indent one of the three, and indentation is list grammar
|
|
79
|
-
rather than whitespace here
|
|
79
|
+
rather than whitespace here. Normalising those lists is its own edit.
|
|
80
80
|
|
|
81
81
|
@define state_batch_line(subject, subject_ref, ref_token):
|
|
82
82
|
2b. Render each issue's {{subject}} as a `**State**: {state}` line of its own, between that issue's `### Issue {{ref_token}}:` heading and its `<untrusted-issue-body>` marker — OUTSIDE the wrapper, because {{subject_ref}} is an enum the tracker computed, not remote prose. A caller refreshing a batch reads it to see a ticket closed out of band.
|
|
@@ -26,7 +26,7 @@ the single-authority corpus is the divergence this split exists to prevent.
|
|
|
26
26
|
Headings below each section's own anchor are `###` by grammar, not by taste: a
|
|
27
27
|
column-0 `## ` line outside a fence terminates the section for every guard that
|
|
28
28
|
reads it through `extractOpSectionFromCorpus`, and everything under it becomes
|
|
29
|
-
invisible while the bytes stay on disk
|
|
29
|
+
invisible while the bytes stay on disk.
|
|
30
30
|
|
|
31
31
|
`_common.mds` is an ALIAS import (`as common`), as in the other two provider
|
|
32
32
|
modules. A SELECTIVE import deep-copies each named function into every `@define`
|
|
@@ -226,13 +226,13 @@ This issue reached the size limit.
|
|
|
226
226
|
|
|
227
227
|
Load when the resolved tracker provider is `github` and the operation is `create-release`.
|
|
228
228
|
|
|
229
|
-
**Mechanics held here:** the
|
|
229
|
+
**Mechanics held here:** the shipped-issues step only. Tag creation, release creation and notes composition stay with the operation.
|
|
230
230
|
|
|
231
231
|
### Process
|
|
232
232
|
|
|
233
233
|
Inside step 5 (compose release notes):
|
|
234
234
|
|
|
235
|
-
- If `SHIPPED_ISSUES` provided: append a `##
|
|
235
|
+
- If `SHIPPED_ISSUES` provided: append a `## Shipped Issues` section with issue references — **first ≤50 issues** (the same bound `backlink-shipped-issues` applies); if truncated, add a final `…and {n} more issues` line (D4 degrade if enrichment fails)
|
|
236
236
|
@end
|
|
237
237
|
|
|
238
238
|
@define gather_release_evidence():
|
|
@@ -56,7 +56,7 @@ conflict the contract wins.
|
|
|
56
56
|
Headings below each section's own anchor are `###` by grammar, not by taste: a
|
|
57
57
|
column-0 `## ` line outside a fence terminates the section for every guard that
|
|
58
58
|
reads it through `extractOpSectionFromCorpus`, and everything under it becomes
|
|
59
|
-
invisible while the bytes stay on disk
|
|
59
|
+
invisible while the bytes stay on disk.
|
|
60
60
|
|
|
61
61
|
The comment-body cap is a PROVIDER FACT and is stated once, as `comment_cap()`
|
|
62
62
|
below; every site that renders it invokes the define. It is not in `_mcp.mds`
|
|
@@ -180,13 +180,13 @@ Over `{{comment_cap()}}` characters the rolling item is closed and a successor i
|
|
|
180
180
|
|
|
181
181
|
Load when the resolved tracker provider is `jira` and the operation is `create-release`.
|
|
182
182
|
|
|
183
|
-
**Mechanics held here:** the
|
|
183
|
+
**Mechanics held here:** the shipped-issues step only. Tag creation, release creation and notes composition stay with the operation and are unchanged — they are release-host mechanics, not tracker mechanics.
|
|
184
184
|
|
|
185
185
|
### Process
|
|
186
186
|
|
|
187
187
|
Inside step 5 (compose release notes):
|
|
188
188
|
|
|
189
|
-
- If `SHIPPED_ISSUES` is provided: append a `##
|
|
189
|
+
- If `SHIPPED_ISSUES` is provided: append a `## Shipped Issues` section rendering each entry through `## Reference Rendering` — **first ≤50 issues** (the same bound `backlink-shipped-issues` applies); if truncated, add a final `…and {n} more issues` line (D4 degrade if enrichment fails).
|
|
190
190
|
- {{common.ref_preflight_list("jira", "`^[A-Z][A-Z0-9_]{1,9}-[1-9][0-9]{0,8}$`", "", "", " and the section is omitted rather than rendered empty.")}}
|
|
191
191
|
- `## Reference Rendering` absent, or its token discarded by the gate below ⇒ render the key itself on its own line, and record the discard under `### Substitutions`.
|
|
192
192
|
|