devflow-kit 2.5.0 → 3.0.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 +73 -0
- package/README.md +44 -19
- package/dist/agents/git.md +13 -15
- package/dist/cli/commands/ambient.js +160 -145
- package/dist/cli/commands/capture.js +29 -55
- package/dist/cli/commands/compliance.js +32 -61
- package/dist/cli/commands/context.js +17 -32
- package/dist/cli/commands/debug.js +65 -26
- package/dist/cli/commands/flags.js +3 -3
- package/dist/cli/commands/hud.js +34 -10
- package/dist/cli/commands/init-seed.js +40 -4
- package/dist/cli/commands/init.js +249 -271
- package/dist/cli/commands/install-report.js +10 -15
- package/dist/cli/commands/knowledge/index.js +1 -1
- package/dist/cli/commands/knowledge/toggle.js +11 -3
- package/dist/cli/commands/learning.js +52 -37
- package/dist/cli/commands/legacy-hooks.js +11 -14
- package/dist/cli/commands/memory.js +67 -78
- package/dist/cli/commands/proxy.js +23 -41
- package/dist/cli/commands/security.js +5 -13
- package/dist/cli/commands/skills.js +21 -3
- package/dist/cli/commands/tracker.js +100 -228
- package/dist/cli/commands/uninstall.js +343 -138
- package/dist/commands/bug-analysis.md +38 -12
- package/dist/commands/code-review.md +70 -21
- package/dist/commands/debug.md +37 -7
- package/dist/commands/dynamic-build.md +66 -17
- package/dist/commands/dynamic-plan.md +19 -8
- package/dist/commands/dynamic-profile.md +24 -10
- package/dist/commands/dynamic-tickets.md +22 -11
- package/dist/commands/explore.md +37 -7
- package/dist/commands/implement.md +96 -32
- package/dist/commands/plan.md +62 -19
- package/dist/commands/release.md +2 -2
- package/dist/commands/research.md +34 -8
- package/dist/commands/resolve.md +65 -17
- package/dist/commands/self-review.md +45 -9
- package/dist/core/compliance-compose.js +27 -27
- package/dist/core/evidence-policy.js +240 -24
- package/dist/core/feature-config.js +94 -25
- package/dist/core/feature-switch.js +1 -1
- package/dist/core/flags.js +30 -2
- package/dist/core/fs-atomic.js +27 -0
- package/dist/core/hook-log-dirs.js +104 -0
- package/dist/core/learning-tuning-config.js +5 -3
- package/dist/core/ledger-root.js +102 -0
- package/dist/core/manifest.js +6 -4
- package/dist/core/mds-variants.js +34 -97
- package/dist/core/migrations.js +49 -23
- package/dist/core/plugins.js +5 -4
- package/dist/core/project-paths.js +0 -17
- package/dist/core/same-location.js +25 -0
- package/dist/core/tracker.js +226 -139
- package/dist/hud/components/config-counts.js +15 -4
- package/dist/hud/components/learning-counts.js +14 -0
- package/dist/hud/config.js +2 -1
- package/dist/hud/cost-history.js +2 -4
- package/dist/hud/git.js +52 -7
- package/dist/hud/index.js +7 -9
- package/dist/skills/git/references/pr/check-merge-readiness.md +1 -1
- package/dist/skills/git/references/pr/ensure-pr-ready.md +1 -1
- package/dist/skills/git/references/pr/update-pr-evidence.md +1 -1
- package/dist/skills/git/references/tracker/_mcp.md +1 -1
- package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/github/manage-debt.md +3 -3
- package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/jira/manage-debt.md +1 -1
- package/dist/skills/git/references/tracker/jira/post-wave-report.md +1 -1
- package/dist/skills/git/references/tracker/jira/setup-task.md +1 -1
- package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +1 -1
- package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +1 -1
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +2 -2
- package/dist/skills/git/references/tracker/linear/manage-debt.md +1 -1
- package/dist/skills/git/references/tracker/linear/post-wave-report.md +1 -1
- package/dist/skills/git/references/tracker/linear/setup-task.md +1 -1
- package/dist/targets/claude-code/claude-paths.js +59 -57
- package/dist/targets/claude-code/compliance-install.js +49 -65
- package/dist/targets/claude-code/hooks.js +108 -3
- package/dist/targets/claude-code/installer.js +30 -57
- package/dist/targets/claude-code/post-install.js +232 -139
- package/dist/targets/claude-code/tracker-install.js +38 -65
- package/package.json +5 -4
- package/src/assets/agents/code.md +4 -3
- package/src/assets/agents/design.md +1 -0
- package/src/assets/agents/git.mds +55 -57
- package/src/assets/agents/knowledge.md +2 -2
- package/src/assets/agents/review.md +3 -1
- package/src/assets/agents/tracker.md +37 -30
- package/src/assets/commands/_partials/_compliance.mds +19 -1
- package/src/assets/commands/_partials/_decisions.mds +15 -3
- package/src/assets/commands/_partials/_docs_root.mds +35 -0
- package/src/assets/commands/_partials/_engine.mds +2 -2
- package/src/assets/commands/_partials/_evidence_policy.mds +3 -3
- package/src/assets/commands/_partials/_factory.mds +1 -1
- package/src/assets/commands/_partials/_knowledge.mds +27 -9
- package/src/assets/commands/_partials/_plan_contract.mds +2 -2
- package/src/assets/commands/_partials/_preamble.mds +1 -1
- package/src/assets/commands/_partials/_publication.mds +6 -2
- package/src/assets/commands/_partials/_settings.mds +28 -0
- package/src/assets/commands/_partials/_ticket_template.mds +3 -3
- package/src/assets/commands/_partials/_tracker.mds +4 -4
- package/src/assets/commands/_partials/_wave.mds +4 -4
- package/src/assets/commands/bug-analysis.mds +19 -17
- package/src/assets/commands/code-review.mds +39 -33
- package/src/assets/commands/debug.mds +4 -5
- package/src/assets/commands/dynamic-build.mds +75 -53
- package/src/assets/commands/dynamic-plan.mds +20 -15
- package/src/assets/commands/dynamic-profile.mds +24 -11
- package/src/assets/commands/dynamic-tickets.mds +25 -20
- package/src/assets/commands/explore.mds +4 -5
- package/src/assets/commands/implement.mds +58 -45
- package/src/assets/commands/plan.mds +34 -29
- package/src/assets/commands/release.md +2 -2
- package/src/assets/commands/research.mds +11 -9
- package/src/assets/commands/resolve.mds +41 -39
- package/src/assets/commands/self-review.mds +24 -25
- package/src/assets/mds/git/_pr.mds +61 -61
- package/src/assets/mds/git/_references.mds +19 -19
- package/src/assets/mds/tracker/_common.mds +8 -8
- package/src/assets/mds/tracker/_github.mds +71 -71
- package/src/assets/mds/tracker/_jira.mds +74 -74
- package/src/assets/mds/tracker/_linear.mds +75 -75
- package/src/assets/mds/tracker/_mcp.mds +23 -17
- package/src/assets/scripts/hooks/background-memory-update +35 -19
- package/src/assets/scripts/hooks/capture-prompt +18 -12
- package/src/assets/scripts/hooks/capture-question +18 -12
- package/src/assets/scripts/hooks/capture-turn +27 -17
- package/src/assets/scripts/hooks/debug-trace +11 -6
- package/src/assets/scripts/hooks/ensure-devflow-init +33 -6
- package/src/assets/scripts/hooks/ensure-proxy +9 -8
- package/src/assets/scripts/hooks/ensure-root-gitignore +111 -36
- package/src/assets/scripts/hooks/git-marker +48 -0
- package/src/assets/scripts/hooks/json-helper.cjs +6 -1
- package/src/assets/scripts/hooks/lib/project-paths.cjs +0 -19
- package/src/assets/scripts/hooks/log-paths +80 -0
- package/src/assets/scripts/hooks/memory-worker +17 -15
- package/src/assets/scripts/hooks/pre-compact-memory +41 -16
- package/src/assets/scripts/hooks/queue-append +104 -30
- package/src/assets/scripts/hooks/resolve-project-root +101 -7
- package/src/assets/scripts/hooks/session-start-context +289 -122
- package/src/assets/scripts/hooks/session-start-memory +35 -16
- package/src/assets/scripts/lib/project-config.cjs +633 -0
- package/src/assets/scripts/resolve-evidence-policy.cjs +300 -220
- package/src/assets/scripts/resolve-settings.cjs +1054 -0
- package/src/assets/scripts/verify-evidence.cjs +1 -1
- package/src/assets/skills/compliance/SKILL.md +2 -2
- package/src/assets/skills/docs-framework/SKILL.md +6 -7
- package/src/assets/skills/docs-framework/references/patterns.md +10 -17
- package/src/assets/skills/gap-analysis/SKILL.md +2 -2
- package/src/assets/skills/git/references/github-api.md +9 -9
- package/src/assets/skills/git/references/patterns.md +1 -1
- package/src/assets/skills/worktree-support/SKILL.md +1 -1
- package/src/assets/skills/worktree-support/references/roots.md +29 -0
- package/src/targets/claude-code/templates/managed-settings.json +25 -9
|
@@ -5,14 +5,15 @@ output-dir: dist/commands
|
|
|
5
5
|
---
|
|
6
6
|
@import { authoring_preamble } from "./_partials/_preamble.mds"
|
|
7
7
|
@import { evidence_policy } from "./_partials/_evidence_policy.mds"
|
|
8
|
+
@import { docs_root } from "./_partials/_docs_root.mds"
|
|
8
9
|
@import { agent_roster, agent_caveats } from "./_partials/_roster.mds"
|
|
9
10
|
@import { gate1_postcode, gate2_acceptance, evaluator_panel, implement_bundle, review_pass, concurrency_doctrine, build_execution_doctrine, engine_output_schema, engine_invariants } from "./_partials/_engine.mds"
|
|
10
11
|
@import { wave_loop, branch_merge_model, merge_doctrine, escalation_model } from "./_partials/_wave.mds"
|
|
11
12
|
@import { acceptance_criteria_contract } from "./_partials/_plan_contract.mds"
|
|
12
13
|
@import { issue_ref_grammar, issue_capture_contract } from "./_partials/_tracker.mds"
|
|
13
14
|
@import "./_partials/_publication.mds" as pub
|
|
14
|
-
|
|
15
|
-
{authoring_preamble()}
|
|
15
|
+
@import "./_partials/_compliance.mds" as compliance
|
|
16
|
+
{{authoring_preamble()}}
|
|
16
17
|
|
|
17
18
|
---
|
|
18
19
|
|
|
@@ -20,14 +21,14 @@ output-dir: dist/commands
|
|
|
20
21
|
|
|
21
22
|
This command instructs you to construct and run a Claude Code dynamic Workflow that implements, reviews, and verifies one ticket or a full wave of tickets, reusing devflow's existing agents via `agentType`.
|
|
22
23
|
|
|
23
|
-
{agent_roster()}
|
|
24
|
+
{{agent_roster()}}
|
|
24
25
|
|
|
25
|
-
{agent_caveats()}
|
|
26
|
+
{{agent_caveats()}}
|
|
26
27
|
|
|
27
28
|
---
|
|
28
29
|
|
|
29
30
|
**Requires:** ticket or task description; optional plan document and acceptance criteria from `/devflow:dynamic-plan`
|
|
30
|
-
**Produces:** implemented and reviewed branch per ticket; wave run report at
|
|
31
|
+
**Produces:** implemented and reviewed branch per ticket; wave run report at `{integration worktree root}/.devflow/docs/waves/{slug}/{ts}/wave-report.md`
|
|
31
32
|
|
|
32
33
|
---
|
|
33
34
|
|
|
@@ -37,7 +38,7 @@ Before authoring, verify:
|
|
|
37
38
|
|
|
38
39
|
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."
|
|
39
40
|
2. **`agentType` support:** confirmed available (spike F5, 2026-06-11). If spawned agents return no results, check that devflow is installed (`devflow init` has been run).
|
|
40
|
-
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 (
|
|
41
|
+
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.
|
|
41
42
|
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.
|
|
42
43
|
|
|
43
44
|
---
|
|
@@ -50,10 +51,24 @@ Before you write the workflow script:
|
|
|
50
51
|
|
|
51
52
|
**Produces:** EVIDENCE_POLICY, ISSUE_REQUIRED, APPLY_CONVENTIONS, REQUIRE_NON_AUTHOR_APPROVAL
|
|
52
53
|
|
|
53
|
-
{evidence_policy()}
|
|
54
|
+
{{evidence_policy()}}
|
|
54
55
|
|
|
55
56
|
Author the resolved `ISSUE_REQUIRED` and `APPLY_CONVENTIONS` into the workflow script as constants — pass them as `issueRequired` and `applyConventions` when invoking the workflow — and pass both to the Git `setup-task` spawn.
|
|
56
57
|
|
|
58
|
+
**0b. Resolve the compliance lens**
|
|
59
|
+
|
|
60
|
+
**Produces:** COMPLIANCE_FRAMEWORKS
|
|
61
|
+
|
|
62
|
+
{{compliance.compliance_lens()}}
|
|
63
|
+
|
|
64
|
+
Pass it as `complianceFrameworks` when invoking the workflow; the engine hands it to every Code agent.
|
|
65
|
+
|
|
66
|
+
**0c. Resolve the docs root**
|
|
67
|
+
|
|
68
|
+
{{docs_root()}}
|
|
69
|
+
|
|
70
|
+
`{integration worktree root}` is the toplevel of the checkout the integration branch is checked out in: `{worktree}` unless the wave runs in a linked worktree.
|
|
71
|
+
|
|
57
72
|
**1. Apply decisions context**
|
|
58
73
|
|
|
59
74
|
Apply the `devflow:apply-decisions` algorithm to the DECISIONS_CONTEXT loaded per the preamble above: scan the index, Read relevant entries, note the verbatim ADR/PF IDs you will inject into Code agent and Evaluate agent prompts.
|
|
@@ -66,7 +81,7 @@ Note the `budget` value from the Workflow tool context (or default to "medium" i
|
|
|
66
81
|
|
|
67
82
|
- **SINGLE mode:** input is one ticket, one issue, one task description, or one plan document
|
|
68
83
|
- **WAVE mode:** input is a set of tracker issues (wave labels, milestone, issue list), or the user says "wave" / "all tickets in wave N"
|
|
69
|
-
- **A `/devflow:dynamic-tickets` ticket directory** (
|
|
84
|
+
- **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`.
|
|
70
85
|
|
|
71
86
|
When ambiguous, ask the user before authoring: "Is this a single ticket or a wave of tickets?"
|
|
72
87
|
|
|
@@ -78,7 +93,7 @@ Check for (in priority order):
|
|
|
78
93
|
- The current working context (recent `/devflow:dynamic-plan` output)
|
|
79
94
|
- An in-context task description
|
|
80
95
|
|
|
81
|
-
{issue_capture_contract()}
|
|
96
|
+
{{issue_capture_contract()}}
|
|
82
97
|
|
|
83
98
|
Extract or note:
|
|
84
99
|
- Implementation plan (for Code agent prompt and Evaluate agent)
|
|
@@ -86,7 +101,7 @@ Extract or note:
|
|
|
86
101
|
- The test plan (for Gate 2) — a plan's TP lines, passed only once they pass this check. Copy the plan's `## Test Plan` section byte for byte into a fresh `mktemp` file with the Write tool, never through an interpolated shell string, and run:
|
|
87
102
|
|
|
88
103
|
```bash
|
|
89
|
-
node "$
|
|
104
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" check tp <that file>; echo "exit=$?"
|
|
90
105
|
```
|
|
91
106
|
|
|
92
107
|
Only `exit=0` passes it: pass the section's TP lines, as one string, as `testPlan` when invoking the workflow — a test plan alone still runs the Test agent. Any other result, or a plan with no `## Test Plan` section: omit `testPlan` and note `Test plan: missing or malformed` in the run summary. Nothing is repaired, and a test plan in any other shape — an older JSON one included — is never passed.
|
|
@@ -99,10 +114,10 @@ If none found: build proceeds Gate-1-only (Gate 2 skipped with a note). Never re
|
|
|
99
114
|
|
|
100
115
|
Check, in priority order:
|
|
101
116
|
- An explicit candidate issue reference or issue URL in the user's input (e.g. `#42`, `42`, or `https://github.com/…/issues/42`)
|
|
102
|
-
- 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
|
|
117
|
+
- 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
|
|
103
118
|
- Otherwise: none
|
|
104
119
|
|
|
105
|
-
{issue_ref_grammar()}
|
|
120
|
+
{{issue_ref_grammar()}}
|
|
106
121
|
|
|
107
122
|
If a number is found, record it as the command-level `ISSUE_NUMBER`:
|
|
108
123
|
- **SINGLE mode:** it is the ticket's own reference. Pass it as `issueNumber: <number>` when invoking the workflow; the engine hands it to setup-task as `ISSUE_INPUT`. If none is found, pass nothing.
|
|
@@ -133,6 +148,7 @@ const DECISIONS_CONTEXT = args.decisionsContext || ""; // injected before autho
|
|
|
133
148
|
const ISSUE_INPUT = args.issueInput || args.issueNumber || "(none)"; // this ticket's OWN raw reference (Pre-authoring step 5; a wave passes issueInput) — setup-task's input, never a Code agent's
|
|
134
149
|
const ISSUE_REQUIRED = String(args.issueRequired) === "false" ? "false" : "true"; // Pre-authoring step 0; only an explicit false turns it off — absent or unrecognised fails closed, like the resolver
|
|
135
150
|
const APPLY_CONVENTIONS = String(args.applyConventions) === "false" ? "false" : "true";
|
|
151
|
+
const COMPLIANCE_FRAMEWORKS = /^(?:off|none|[a-z][a-z0-9-]{0,15}(?:,[a-z][a-z0-9-]{0,15}){0,7})$/.test(String(args.complianceFrameworks)) ? String(args.complianceFrameworks) : "off"; // Pre-authoring step 0b; any other shape is no lens
|
|
136
152
|
|
|
137
153
|
// Phase 1: Git setup — declare the operation; the agent owns the process, the branch name included
|
|
138
154
|
const setup = await phase("setup", () =>
|
|
@@ -176,6 +192,7 @@ ${DECISIONS_CONTEXT}
|
|
|
176
192
|
|
|
177
193
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
178
194
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
195
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
179
196
|
|
|
180
197
|
When you build or run tests to verify your work, use your "Long-running commands" discipline (background-Bash + Monitor poll) for anything that may run silent >120s, and prefer package-scoped commands.
|
|
181
198
|
|
|
@@ -199,6 +216,7 @@ Report: PASS or FAIL with details.`, { agentType: "Validate" });
|
|
|
199
216
|
${validation.details}
|
|
200
217
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
201
218
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
219
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
202
220
|
Commit fixes with conventional-commit message.`, { agentType: "Code" });
|
|
203
221
|
const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH}. Report: PASS or FAIL.`, { agentType: "Validate" });
|
|
204
222
|
if (recheck.verdict === "PASS") break;
|
|
@@ -242,6 +260,7 @@ Report: PASS or FAIL with rationale.`, { agentType: "Evaluate" }),
|
|
|
242
260
|
${panel.filter(p => p.verdict === "FAIL").map(p => p.rationale).join("\n")}
|
|
243
261
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
244
262
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
263
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
245
264
|
Self-verify your fix compiles (background-Bash + Monitor for any build >120s — see your "Long-running commands" discipline). Commit fixes.`, { agentType: "Code" });
|
|
246
265
|
evalVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
|
|
247
266
|
}
|
|
@@ -261,6 +280,7 @@ Cover: functionality, API contracts, performance, and cover every TEST_PLAN scen
|
|
|
261
280
|
${testResult.failures}
|
|
262
281
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
263
282
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
283
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
264
284
|
Self-verify your fix compiles and the scenarios pass (background-Bash + Monitor for any build/test >120s). Commit fixes.`, { agentType: "Code" });
|
|
265
285
|
testVerdict = "FAIL-FIXED"; // issues found, fixes applied, not re-evaluated by design
|
|
266
286
|
}
|
|
@@ -374,6 +394,7 @@ ${chunk.map(f => `- ${f.description} (${f.severity})`).join("\n")}
|
|
|
374
394
|
|
|
375
395
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
376
396
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
397
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
377
398
|
Fix all findings in this batch. Self-verify your fix compiles (background-Bash + Monitor for any build >120s — see your "Long-running commands" discipline). Commit with conventional-commit message.
|
|
378
399
|
Return: {"status": "fixed"|"blocked", "commitShas": ["<sha>"], "unresolved": ["<description of any finding that could not be fixed>"]}`, { agentType: "Code" });
|
|
379
400
|
chunkResults.push({ chunk, result: r });
|
|
@@ -424,6 +445,7 @@ Report: PASS or FAIL with details.`, { agentType: "Validate" });
|
|
|
424
445
|
${failureDetails}
|
|
425
446
|
ISSUE_NUMBER: ${ISSUE_NUMBER}
|
|
426
447
|
ISSUE_PR_LINK: ${ISSUE_PR_LINK}
|
|
448
|
+
COMPLIANCE_FRAMEWORKS: ${COMPLIANCE_FRAMEWORKS}
|
|
427
449
|
Self-verify your fix compiles. Commit fixes with conventional-commit message.`, { agentType: "Code" });
|
|
428
450
|
const recheck = await agent(`Re-run build, typecheck, lint, tests on branch ${BRANCH} (background+Monitor for long commands). Report: PASS or FAIL.`, { agentType: "Validate" });
|
|
429
451
|
if (recheck.verdict === "PASS") break;
|
|
@@ -476,25 +498,25 @@ Write a concise report. Present only surviving findings as outstanding — never
|
|
|
476
498
|
});
|
|
477
499
|
```
|
|
478
500
|
|
|
479
|
-
{concurrency_doctrine()}
|
|
501
|
+
{{concurrency_doctrine()}}
|
|
480
502
|
|
|
481
|
-
{build_execution_doctrine()}
|
|
503
|
+
{{build_execution_doctrine()}}
|
|
482
504
|
|
|
483
|
-
{implement_bundle()}
|
|
505
|
+
{{implement_bundle()}}
|
|
484
506
|
|
|
485
|
-
{gate1_postcode()}
|
|
507
|
+
{{gate1_postcode()}}
|
|
486
508
|
|
|
487
|
-
{gate2_acceptance()}
|
|
509
|
+
{{gate2_acceptance()}}
|
|
488
510
|
|
|
489
|
-
{evaluator_panel()}
|
|
511
|
+
{{evaluator_panel()}}
|
|
490
512
|
|
|
491
|
-
{acceptance_criteria_contract()}
|
|
513
|
+
{{acceptance_criteria_contract()}}
|
|
492
514
|
|
|
493
|
-
{review_pass()}
|
|
515
|
+
{{review_pass()}}
|
|
494
516
|
|
|
495
|
-
{engine_invariants()}
|
|
517
|
+
{{engine_invariants()}}
|
|
496
518
|
|
|
497
|
-
{engine_output_schema()}
|
|
519
|
+
{{engine_output_schema()}}
|
|
498
520
|
|
|
499
521
|
---
|
|
500
522
|
|
|
@@ -502,17 +524,17 @@ Write a concise report. Present only surviving findings as outstanding — never
|
|
|
502
524
|
|
|
503
525
|
When WAVE mode is detected, author a workflow that wraps the single-ticket engine with the wave loop:
|
|
504
526
|
|
|
505
|
-
{wave_loop()}
|
|
527
|
+
{{wave_loop()}}
|
|
506
528
|
|
|
507
|
-
{branch_merge_model()}
|
|
529
|
+
{{branch_merge_model()}}
|
|
508
530
|
|
|
509
|
-
{merge_doctrine()}
|
|
531
|
+
{{merge_doctrine()}}
|
|
510
532
|
|
|
511
|
-
{escalation_model()}
|
|
533
|
+
{{escalation_model()}}
|
|
512
534
|
|
|
513
535
|
**Wave workflow structure (author after the SINGLE engine blocks above):**
|
|
514
536
|
|
|
515
|
-
The wave workflow uses the same phases as SINGLE but wraps them in a wave loop. The integration branch is `wave/<initiative>` — the initiative slug, referenced below as
|
|
537
|
+
The wave workflow uses the same phases as SINGLE but wraps them in a wave loop. The integration branch is `wave/<initiative>` — the initiative slug, referenced below as `{slug}` — (or the user's current branch). Each ticket works on the branch setup-task created. The Git agent manages worktrees for parallel-eligible tickets. After every merge: Validate agent (build + test). Escalations accumulate in a list; the final report lists all of them.
|
|
516
538
|
|
|
517
539
|
Wave skeleton — compact reference (see `wave_loop()` doctrine for full semantics):
|
|
518
540
|
|
|
@@ -556,7 +578,7 @@ Return: {"ready": [...ticket-ids], "blocked": [{"ticket": "id", "namedBlocker":
|
|
|
556
578
|
try {
|
|
557
579
|
// ticketId is the ISSUE_REF the pre-fetch heading printed — this ticket's OWN reference: the engine's `ticket` (its TICKET)
|
|
558
580
|
// and its setup-task ISSUE_INPUT; the engine returns the branch that setup-task created, merged below; plans[ticketId] is its own plan, criteria and checked testPlan (Pre-authoring step 4)
|
|
559
|
-
const engineResult = await runSingleTicketEngine({ ticket: ticketId, baseBranch: INTEGRATION_BRANCH, ...(plans[ticketId] || {}), decisionsContext: DECISIONS_CONTEXT, issueRequired: ISSUE_REQUIRED, applyConventions: APPLY_CONVENTIONS, issueInput: ticketId });
|
|
581
|
+
const engineResult = await runSingleTicketEngine({ ticket: ticketId, baseBranch: INTEGRATION_BRANCH, ...(plans[ticketId] || {}), decisionsContext: DECISIONS_CONTEXT, issueRequired: ISSUE_REQUIRED, applyConventions: APPLY_CONVENTIONS, complianceFrameworks: COMPLIANCE_FRAMEWORKS, issueInput: ticketId });
|
|
560
582
|
// Check both verdict (engine_output_schema) and overallVerdict (SINGLE skeleton alias).
|
|
561
583
|
// PASS and UNVERIFIED merge; PARTIAL, FAIL, ESCALATED (the ticket-link and branch stops included) or no verdict quarantine.
|
|
562
584
|
if (["PASS", "UNVERIFIED"].includes(engineResult.verdict || engineResult.overallVerdict)) {
|
|
@@ -587,21 +609,21 @@ return { tickets: WAVE_TICKETS.map(t => results[t] || { ticket: t, ran: false, v
|
|
|
587
609
|
|
|
588
610
|
A workflow cannot pause mid-run. After the build/wave workflow returns, you (the main model) surface anything that needs a human decision — all at once:
|
|
589
611
|
|
|
590
|
-
1. Read the wave report (
|
|
591
|
-
2. **Post wave-report as tracking-issue comment** (WAVE mode only — skip this step entirely in SINGLE mode; SINGLE runs produce no wave report): In WAVE mode, if a tracking-issue number was resolved in Pre-authoring step 5 (`ISSUE_NUMBER` is not `(none)`) AND
|
|
612
|
+
1. Read the wave report (`{integration worktree root}/.devflow/docs/waves/{slug}/{ts}/wave-report.md`) for its **escalations** (quarantined/blocked tickets and why), and read any `DECISIONS-NEEDED.md` left by a prior `/devflow:dynamic-plan` run for this initiative.
|
|
613
|
+
2. **Post wave-report as tracking-issue comment** (WAVE mode only — skip this step entirely in SINGLE mode; SINGLE runs produce no wave report): In WAVE mode, if a tracking-issue number was resolved in Pre-authoring step 5 (`ISSUE_NUMBER` is not `(none)`) AND `{integration worktree root}/.devflow/docs/waves/{slug}/{ts}/wave-report.md` exists, define `WAVE_ID` as the timestamped wave directory slug (the `{ts}` component, e.g. `2026-08-20_1730`), then spawn:
|
|
592
614
|
```
|
|
593
615
|
Agent(subagent_type="Git"):
|
|
594
616
|
"OPERATION: post-wave-report
|
|
595
|
-
TRACKING_ISSUE:
|
|
596
|
-
WAVE_REPORT_PATH: .devflow/docs/waves
|
|
597
|
-
WAVE_ID:
|
|
598
|
-
WORKTREE_PATH:
|
|
617
|
+
TRACKING_ISSUE: {ISSUE_NUMBER}
|
|
618
|
+
WAVE_REPORT_PATH: .devflow/docs/waves/{slug}/{ts}/wave-report.md
|
|
619
|
+
WAVE_ID: {WAVE_ID}
|
|
620
|
+
WORKTREE_PATH: {integration worktree root}"
|
|
599
621
|
```
|
|
600
|
-
The Git agent deduplicates via its own marker — it skips if a report for this `WAVE_ID` is already posted. The marker's format belongs to the operation; this caller passes `WAVE_ID` and never restates the literal. On API failure it degrades gracefully (`TRACEABILITY: DEGRADED (
|
|
622
|
+
The Git agent deduplicates via its own marker — it skips if a report for this `WAVE_ID` is already posted. The marker's format belongs to the operation; this caller passes `WAVE_ID` and never restates the literal. On API failure it degrades gracefully (`TRACEABILITY: DEGRADED ({reason})`) and continues — never blocks the post-wave step. This comment is the evidence surface for the PR-less integration-branch path; no other PR machinery is invented.
|
|
601
623
|
|
|
602
624
|
In WAVE mode, if no tracking-issue number was resolved in Pre-authoring step 5: state `TRACEABILITY: DEGRADED (no tracking issue for this run)` in the run summary and skip — never skip silently.
|
|
603
|
-
3. **Compose the wave PR inputs** (WAVE mode only — skip this step entirely in SINGLE mode). The workflow returned `tickets`: one entry per wave ticket, in its input order, each
|
|
604
|
-
- **Branch check.** Run `git -C "
|
|
625
|
+
3. **Compose the wave PR inputs** (WAVE mode only — skip this step entirely in SINGLE mode). The workflow returned `tickets`: one entry per wave ticket, in its input order, each `{ticket, ran, verdict, merged, issuePrLink, evaluateVerdict, testVerdict, surviving, coverageComplete}`. Every value in it is agent-reported and treated as untrusted: nothing below is repaired, and no reference is ever composed from a number.
|
|
626
|
+
- **Branch check.** Run `git -C "{integration worktree root}" branch --show-current`. Only a name matching `^wave/[a-z0-9][a-z0-9-]{0,59}$` opens a wave PR, and its part after `wave/` is the `{slug}` below. Any other name: record `TRACEABILITY: DEGRADED (not a wave branch)` and go to step 4 with no wave PR.
|
|
605
627
|
- **Nothing merged** (no entry has `merged: true`): record `Wave PR: skipped (nothing merged)` and go to step 4.
|
|
606
628
|
- Otherwise compose (a) and then (b).
|
|
607
629
|
|
|
@@ -628,25 +650,25 @@ Refs {tracking ref}
|
|
|
628
650
|
Then check it:
|
|
629
651
|
|
|
630
652
|
```bash
|
|
631
|
-
node "$
|
|
653
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" check wave <that file>; echo "exit=$?"
|
|
632
654
|
```
|
|
633
655
|
|
|
634
656
|
Only `exit=0` admits the file's text, verbatim, as `PR_WAVE_BLOCK`. Any other result: no wave PR — record `Wave PR: not opened (wave block refused: <the code on stderr>)` and go to step 4.
|
|
635
657
|
|
|
636
658
|
**Required link** — only when `EVIDENCE_POLICY` is `required`: a `PASS` or `UNVERIFIED` row whose Ticket is `(none)` — a merged ticket whose setup-task captured an Issue ID but no link line, so the wave PR would close nothing for it — ⇒ `Wave PR: BLOCKED (no ticket link for T<k>, …)`, with no wave PR question and the remedy "link or create those tickets' issues, then re-run"; there is no exception. Under `standard` such a row stays as the Ticket rule above renders it.
|
|
637
659
|
|
|
638
|
-
**(b) The wave test plan.** Take the checked TP lines each merged row's ticket was given in Pre-authoring step 4, in row order; renumber them `TP-1`, `TP-2`, … and prefix each scenario with its row's `T<k>: `. A line is never shortened or reworded: one whose prefixed scenario would pass 200 characters leaves its ticket with no usable test plan. Write `## Test Plan` and those lines, and nothing else, to `"
|
|
660
|
+
**(b) The wave test plan.** Take the checked TP lines each merged row's ticket was given in Pre-authoring step 4, in row order; renumber them `TP-1`, `TP-2`, … and prefix each scenario with its row's `T<k>: `. A line is never shortened or reworded: one whose prefixed scenario would pass 200 characters leaves its ticket with no usable test plan. Write `## Test Plan` and those lines, and nothing else, to `"{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md"` with the Write tool, then run (the path double-quoted; one rewrite from the same lines after a refusal, never a second):
|
|
639
661
|
|
|
640
662
|
```bash
|
|
641
|
-
node "$
|
|
642
|
-
node "$
|
|
663
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" check tp "{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md"; echo "exit=$?"
|
|
664
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" render --plan "{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md"; echo "exit=$?"
|
|
643
665
|
```
|
|
644
666
|
|
|
645
667
|
Only when both exit 0 is `PR_TEST_PLAN_BLOCK` the render's stdout, byte for byte without its `exit=` line; in every other case it is `(none)`.
|
|
646
668
|
|
|
647
669
|
**Required plan** — only when `EVIDENCE_POLICY` is `required`: a merged ticket with no usable test plan ⇒ `Wave PR: BLOCKED (no test plan for T<k>, …)`, more than 200 lines in all ⇒ `Wave PR: BLOCKED (test plan over 200 lines)`, and a plan that did not check and render ⇒ `Wave PR: BLOCKED (test plan malformed)` — each with no wave PR question and the remedy "run `/devflow:dynamic-plan` for those tickets and re-run, or ship them through `/implement`"; no exception is offered here. Otherwise the block is optional: a ticket with no usable test plan is left out of it and named in the summary, and `(none)` is passed when no line remains.
|
|
648
670
|
4. Surface ALL of them — escalations AND open decisions — to the user in ONE batched `AskUserQuestion` (never one-at-a-time). `_wave.mds`'s escalation model already quarantines-and-continues; this batches the surfacing so the user answers everything in a single pass.
|
|
649
|
-
- **The wave PR question.** Only when step 3 composed `PR_WAVE_BLOCK`, the batch gains exactly one question: "Open the wave PR from wave
|
|
671
|
+
- **The wave PR question.** Only when step 3 composed `PR_WAVE_BLOCK`, the batch gains exactly one question: "Open the wave PR from wave/{slug}? It links {n} merged tickets ({u} UNVERIFIED) and references {q} quarantined." It has exactly two options: open it, or don't. The counts come from the checked block's rows: `{n}` PASS and UNVERIFIED, `{u}` UNVERIFIED, `{q}` QUARANTINED.
|
|
650
672
|
- A `ticket-link-missing` escalation carries its remedy: link or create that ticket's issue, then re-run. There is no per-ticket exception.
|
|
651
673
|
- **Headless** — `AskUserQuestion` is unavailable, or no answer comes — is a decline: nothing is created and nothing is pushed.
|
|
652
674
|
5. If `~/.devflow/preference-profile.md` was absent, note in your summary: "no preference profile found — N decisions surfaced that a profile might have auto-resolved; consider `/devflow:dynamic-profile`."
|
|
@@ -654,19 +676,19 @@ node "${DEVFLOW_DIR:-$HOME/.devflow}/scripts/verify-evidence.cjs" render --plan
|
|
|
654
676
|
```
|
|
655
677
|
Agent(subagent_type="Git"):
|
|
656
678
|
"OPERATION: ensure-pr-ready
|
|
657
|
-
WORKTREE_PATH:
|
|
658
|
-
PR_DESCRIPTION_GUIDANCE:
|
|
659
|
-
APPLY_CONVENTIONS:
|
|
660
|
-
PR_WAVE_BLOCK:
|
|
661
|
-
PR_TEST_PLAN_BLOCK:
|
|
679
|
+
WORKTREE_PATH: {integration worktree root}
|
|
680
|
+
PR_DESCRIPTION_GUIDANCE: {counts only — the wave slug and the merged, quarantined and blocked counts; never an issue title or body}
|
|
681
|
+
APPLY_CONVENTIONS: {APPLY_CONVENTIONS}
|
|
682
|
+
PR_WAVE_BLOCK: {PR_WAVE_BLOCK verbatim}
|
|
683
|
+
PR_TEST_PLAN_BLOCK: {PR_TEST_PLAN_BLOCK verbatim, or (none)}"
|
|
662
684
|
```
|
|
663
|
-
The Git agent pastes each block only behind its own check. Report its `**PR**` line and any `TRACEABILITY: DEGRADED (
|
|
685
|
+
The Git agent pastes each block only behind its own check. Report its `**PR**` line and any `TRACEABILITY: DEGRADED ({reason})` lines. The wave PR is opened here and nowhere else; it is never merged, and main is never touched — the user merges.
|
|
664
686
|
|
|
665
687
|
Do NOT ask questions mid-workflow — that is impossible (F4). The workflow only WRITES the report; you read it and ask.
|
|
666
688
|
|
|
667
|
-
7. **Wave PR evidence** — only when step 6 reported the wave PR, after it; it never blocks, and every outcome below goes into the run summary. Take
|
|
689
|
+
7. **Wave PR evidence** — only when step 6 reported the wave PR, after it; it never blocks, and every outcome below goes into the run summary. Take `{n}` from step 6's `- **PR**: #{n}` line when `{n}` matches `^[1-9][0-9]{0,9}$` as a whole; no such line ⇒ record `TRACEABILITY: DEGRADED (wave PR number not captured)` and skip this step. `PR_TEST_PLAN_BLOCK` `(none)` ⇒ record `Wave evidence: skipped (no wave test plan)` and skip it.
|
|
668
690
|
|
|
669
|
-
**(a) Test the wave.** Spawn one Test agent on the integration worktree with the wave test plan — the TP lines of the `## Test Plan` section step 3(b) wrote to
|
|
691
|
+
**(a) Test the wave.** Spawn one Test agent on the integration worktree with the wave test plan — the TP lines of the `## Test Plan` section step 3(b) wrote to `{integration worktree root}/.devflow/docs/evidence-wave-{slug}.md`:
|
|
670
692
|
|
|
671
693
|
```
|
|
672
694
|
Agent(subagent_type="Test"):
|
|
@@ -679,7 +701,7 @@ Cover every TEST_PLAN line on the integration branch as it stands. Report PASS o
|
|
|
679
701
|
|
|
680
702
|
Nothing is fixed here, PASS or FAIL: the wave is done and its PR is open. Report the Test agent's Status.
|
|
681
703
|
|
|
682
|
-
**(b) Claims.** Append its TP claims, PASS or FAIL alike, to the `## Claims` section of `"
|
|
704
|
+
**(b) Claims.** Append its TP claims, PASS or FAIL alike, 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:
|
|
683
705
|
|
|
684
706
|
```
|
|
685
707
|
- TP-<n> <PASS|FAIL|SKIP> sha:<head> by:test exit:<0-255>
|
|
@@ -697,7 +719,7 @@ git -C "{integration worktree root}" push origin HEAD; echo "exit=$?"
|
|
|
697
719
|
|
|
698
720
|
**(d) Refresh.** Resolve the publication value for the integration worktree:
|
|
699
721
|
|
|
700
|
-
{pub.publication_gate()}
|
|
722
|
+
{{pub.publication_gate()}}
|
|
701
723
|
|
|
702
724
|
Then spawn:
|
|
703
725
|
|
|
@@ -711,7 +733,7 @@ WORKTREE_PATH: {integration worktree root}
|
|
|
711
733
|
Update the wave PR's test-plan block and post its evidence comment."
|
|
712
734
|
```
|
|
713
735
|
|
|
714
|
-
`update-pr-evidence` decides what each publication value means for the evidence comment. Report its `## PR Evidence` block — its `EVIDENCE` line and its `**Body**:` / `**Comment**:` line — or its `TRACEABILITY: DEGRADED (
|
|
736
|
+
`update-pr-evidence` decides what each publication value means for the evidence comment. Report its `## PR Evidence` block — its `EVIDENCE` line and its `**Body**:` / `**Comment**:` line — or its `TRACEABILITY: DEGRADED ({reason})` line; a spawn that returns neither ⇒ `TRACEABILITY: DEGRADED (evidence refresh failed)`. Whatever it returns, the run ends here.
|
|
715
737
|
|
|
716
738
|
---
|
|
717
739
|
|
|
@@ -4,11 +4,11 @@ argument-hint: "[tickets-dir | issue-list]"
|
|
|
4
4
|
output-dir: dist/commands
|
|
5
5
|
---
|
|
6
6
|
@import { authoring_preamble } from "./_partials/_preamble.mds"
|
|
7
|
+
@import { docs_root } from "./_partials/_docs_root.mds"
|
|
7
8
|
@import { agent_roster, agent_caveats } from "./_partials/_roster.mds"
|
|
8
9
|
@import { acceptance_criteria_contract } from "./_partials/_plan_contract.mds"
|
|
9
10
|
@import { issue_ref_grammar, issue_capture_contract } from "./_partials/_tracker.mds"
|
|
10
|
-
|
|
11
|
-
{authoring_preamble()}
|
|
11
|
+
{{authoring_preamble()}}
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -16,14 +16,14 @@ output-dir: dist/commands
|
|
|
16
16
|
|
|
17
17
|
This command instructs you to construct and run a Claude Code dynamic Workflow that plans all tickets in parallel, challenges each plan (gaps, edge cases, side-effects), produces well-structured acceptance criteria and a test plan for each ticket (consumed by `/devflow:dynamic-build`'s Gate 2), runs a cross-plan conflict critic, auto-resolves decisions matching the user's preference profile, and writes per-ticket plan files + one `DECISIONS-NEEDED.md`.
|
|
18
18
|
|
|
19
|
-
{agent_roster()}
|
|
19
|
+
{{agent_roster()}}
|
|
20
20
|
|
|
21
|
-
{agent_caveats()}
|
|
21
|
+
{{agent_caveats()}}
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
**Requires:** ticket files directory or tracker issue list; optional `~/.devflow/preference-profile.md`
|
|
26
|
-
**Produces:** per-ticket plan files + `DECISIONS-NEEDED.md` at
|
|
26
|
+
**Produces:** per-ticket plan files + `DECISIONS-NEEDED.md` at `{worktree}/.devflow/docs/design/{slug}/{ts}/`
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -33,13 +33,17 @@ Before authoring, verify:
|
|
|
33
33
|
|
|
34
34
|
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-plan requires Claude Code's dynamic workflow runtime."
|
|
35
35
|
2. **`agentType` support:** confirmed available (spike F5, 2026-06-11).
|
|
36
|
-
3. **Tracker paths:** a list of issue references or URLs is read through the Git agent, which resolves the configured tracker and its access itself and reports `TRACEABILITY: DEGRADED (
|
|
36
|
+
3. **Tracker paths:** a list of issue references or URLs is read through the Git agent, which resolves the configured tracker and its access itself and reports `TRACEABILITY: DEGRADED ({reason})` when it cannot read an issue — then fall back to reading ticket `.md` files from a local path. No tracker CLI is checked here.
|
|
37
37
|
4. **No-remote path:** if the repo has no remote, read ticket files from the provided local path; the Git agent reports DEGRADED for any issue it cannot reach.
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
41
|
### Pre-authoring setup
|
|
42
42
|
|
|
43
|
+
{{docs_root()}}
|
|
44
|
+
|
|
45
|
+
Pass `{worktree}` to the workflow as its `root` argument.
|
|
46
|
+
|
|
43
47
|
**1. Apply decisions context**
|
|
44
48
|
|
|
45
49
|
Apply the `devflow:apply-decisions` algorithm to the DECISIONS_CONTEXT loaded per the preamble above: scan the index, Read relevant entries, note verbatim ADR/PF IDs to inject into Design agent and Evaluate agent prompts.
|
|
@@ -60,11 +64,11 @@ Determine the ticket source (in priority order):
|
|
|
60
64
|
- A list of candidate issue references or issue URLs
|
|
61
65
|
- Inline ticket descriptions passed as args
|
|
62
66
|
|
|
63
|
-
{issue_ref_grammar()}
|
|
67
|
+
{{issue_ref_grammar()}}
|
|
64
68
|
|
|
65
69
|
Read or note the tickets. The agents will read them in full; you need the list and any key constraints.
|
|
66
70
|
|
|
67
|
-
{issue_capture_contract()}
|
|
71
|
+
{{issue_capture_contract()}}
|
|
68
72
|
|
|
69
73
|
---
|
|
70
74
|
|
|
@@ -76,11 +80,11 @@ After the workflow completes:
|
|
|
76
80
|
1. **Check each plan's test plan.** For every path in `planPaths`, copy that plan's `## Test Plan` section — the heading and its TP lines, up to the next `## ` heading — byte for byte into a fresh `mktemp` file with the Write tool, never through an interpolated shell string, and run:
|
|
77
81
|
|
|
78
82
|
```bash
|
|
79
|
-
node "$
|
|
83
|
+
node "$HOME/.devflow/scripts/verify-evidence.cjs" check tp <that file>; echo "exit=$?"
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
Check the section, never the whole plan file: the plan's other `## ` headings are not evidence-file sections, so the script would parse the whole document as the plan. `exit=0` passes. Any other result names that plan `test plan malformed (<code>)` in your summary, `<code>` being the code the script printed on stderr; a plan with no `## Test Plan` section copies as an empty file, which the script refuses. Nothing is repaired: `/devflow:dynamic-build` passes no test plan from that plan.
|
|
83
|
-
2. Read the `decisionsNeededPath` returned by the workflow (e.g.
|
|
87
|
+
2. Read the `decisionsNeededPath` returned by the workflow (e.g. `{worktree}/.devflow/docs/design/<slug>/<ts>/DECISIONS-NEEDED.md`). Always use the OUTDIR-scoped path the workflow wrote — never the flat `{worktree}/.devflow/docs/design/DECISIONS-NEEDED.md`.
|
|
84
88
|
3. First surface the **Auto-Resolved Decisions** section (decision → resolution → source) for audit, then surface ALL open **Decisions Needed** to the user in ONE batched `AskUserQuestion` (never one-at-a-time).
|
|
85
89
|
4. The user's answers feed into their own plan edits or a follow-up `/devflow:dynamic-plan` run.
|
|
86
90
|
|
|
@@ -107,7 +111,8 @@ const PREFERENCE_PROFILE = args.preferenceProfile || ""; // injected before aut
|
|
|
107
111
|
const TP_CONTRACT = args.tpContract || ""; // the "Test-plan line (TP)" contract below — its paragraph and four bullets — passed verbatim as tpContract when invoking the workflow, never pasted into this script (it holds backticks)
|
|
108
112
|
const slug = args.slug || "wave";
|
|
109
113
|
const ts = new Date().toISOString().slice(0,16).replace(/[-:T]/g, (c) => c === 'T' ? '_' : c === ':' ? '' : c);
|
|
110
|
-
const
|
|
114
|
+
const ROOT = args.root; // {worktree} from Pre-authoring setup: the checkout's toplevel, never cwd
|
|
115
|
+
const OUTDIR = `${ROOT}/.devflow/docs/design/${slug}/${ts}`;
|
|
111
116
|
|
|
112
117
|
// Phase 1: Read all tickets
|
|
113
118
|
const tickets = await phase("read-tickets", () =>
|
|
@@ -230,17 +235,17 @@ Return: { planPaths (array), decisionsNeededPath (string), decisionsNeededCount
|
|
|
230
235
|
|
|
231
236
|
The plan-challenge step (Phase 3 above) MUST produce the acceptance criteria and test plan shape that `/devflow:dynamic-build`'s Gate 2 consumes:
|
|
232
237
|
|
|
233
|
-
{acceptance_criteria_contract()}
|
|
238
|
+
{{acceptance_criteria_contract()}}
|
|
234
239
|
|
|
235
240
|
---
|
|
236
241
|
|
|
237
242
|
### Artifact paths
|
|
238
243
|
|
|
239
|
-
Per-ticket plans →
|
|
244
|
+
Per-ticket plans → `{worktree}/.devflow/docs/design/{slug}/{ts}/{ticket-slug}-plan.md`
|
|
240
245
|
|
|
241
|
-
Decisions needed →
|
|
246
|
+
Decisions needed → `{worktree}/.devflow/docs/design/{slug}/{ts}/DECISIONS-NEEDED.md`
|
|
242
247
|
|
|
243
|
-
|
|
248
|
+
`{worktree}` is the docs root resolved in Pre-authoring setup (it honours `WORKTREE_PATH` when provided).
|
|
244
249
|
|
|
245
250
|
---
|
|
246
251
|
|
|
@@ -4,8 +4,7 @@ argument-hint: "[--dry-run]"
|
|
|
4
4
|
output-dir: dist/commands
|
|
5
5
|
---
|
|
6
6
|
@import { authoring_preamble } from "./_partials/_preamble.mds"
|
|
7
|
-
|
|
8
|
-
{authoring_preamble()}
|
|
7
|
+
{{authoring_preamble()}}
|
|
9
8
|
|
|
10
9
|
---
|
|
11
10
|
|
|
@@ -19,14 +18,26 @@ The profile is then consumed by `/devflow:dynamic-plan` to pre-resolve design de
|
|
|
19
18
|
|
|
20
19
|
---
|
|
21
20
|
|
|
22
|
-
**Requires:** read access to
|
|
21
|
+
**Requires:** read access to `{claude_dir}/projects/*/` session transcripts and `{claude_dir}/rules/`
|
|
23
22
|
**Produces:** `~/.devflow/preference-profile.md` — plain-prose decision-preference profile
|
|
24
23
|
|
|
25
24
|
---
|
|
26
25
|
|
|
26
|
+
### Claude Code's directory
|
|
27
|
+
|
|
28
|
+
`{claude_dir}` is Claude Code's directory, resolved once, the way the installer resolves it (D-CLAUDE-DIR-PROMPTS): `CLAUDE_CONFIG_DIR` when that is set to an absolute path, else `$HOME/.claude`. Run
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
d="${CLAUDE_CONFIG_DIR:-}"; case "$d" in /*) ;; *) d="$HOME/.claude" ;; esac; printf '%s\n' "$d"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
and use its one-line output. Pass it to the agent below as `CLAUDE_DIR`.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
27
38
|
### Privacy note
|
|
28
39
|
|
|
29
|
-
This command mines session transcripts across **all projects** on this machine —
|
|
40
|
+
This command mines session transcripts across **all projects** on this machine — `{claude_dir}/projects/*/*.jsonl`, `{claude_dir}/history.jsonl`, and feedback memories. The resulting profile is then injected into planning prompts as context. This is a cross-project surface: patterns from one project's decisions may influence planning in another.
|
|
30
41
|
|
|
31
42
|
Mitigation: the profile is plain prose that you review and edit before use. You can trim, redact, or rewrite any section. The profile is at `~/.devflow/preference-profile.md` — open it, read it, adjust it. It is never committed to any repo.
|
|
32
43
|
|
|
@@ -38,8 +49,8 @@ Session transcripts on a typical machine are gigabytes. **The agent MUST NOT ful
|
|
|
38
49
|
|
|
39
50
|
1. Use `rg` (ripgrep) or `grep` to search for `AskUserQuestion` occurrences across transcript files — extracting just the question text and the surrounding user response (a few lines each).
|
|
40
51
|
2. Sample the results — take up to ~200 instances spread across projects and time; do not feed everything into context at once.
|
|
41
|
-
3. Read
|
|
42
|
-
4. Read existing feedback memory files (
|
|
52
|
+
3. Read `{claude_dir}/rules/` files (these are small) to supplement with explicitly stated preferences.
|
|
53
|
+
4. Read existing feedback memory files (`{claude_dir}/projects/*/memory/*.md`) — these are small and already distilled.
|
|
43
54
|
|
|
44
55
|
This grep-and-sample approach is both efficient and Iron-Rule-safe: the agent uses `rg`/`grep` as tools — no extractor or clustering logic is authored.
|
|
45
56
|
|
|
@@ -47,7 +58,7 @@ This grep-and-sample approach is both efficient and Iron-Rule-safe: the agent us
|
|
|
47
58
|
|
|
48
59
|
### When --dry-run is passed
|
|
49
60
|
|
|
50
|
-
Print what the agent would do (a summary of which paths it would search, what it would write) and STOP — do not spawn the agent.
|
|
61
|
+
Print what the agent would do (a summary of which paths under the resolved `{claude_dir}` it would search, what it would write) and STOP — do not spawn the agent.
|
|
51
62
|
|
|
52
63
|
---
|
|
53
64
|
|
|
@@ -58,15 +69,17 @@ Spawn a single Knowledge agent with this task:
|
|
|
58
69
|
```
|
|
59
70
|
You are distilling a decision-preference profile from past session history.
|
|
60
71
|
|
|
72
|
+
CLAUDE_DIR: {claude_dir} — Claude Code's directory, already resolved; every path below is under it.
|
|
73
|
+
|
|
61
74
|
BOUNDED READING — MANDATORY: transcripts are gigabytes; never full-read them.
|
|
62
|
-
1. Run: rg -l "AskUserQuestion"
|
|
75
|
+
1. Run: rg -l "AskUserQuestion" "{claude_dir}/projects/" 2>/dev/null | head -50
|
|
63
76
|
to find transcript files that contain AskUserQuestion moments.
|
|
64
77
|
2. For each found file, run: rg -A 5 "AskUserQuestion" <file> | head -200
|
|
65
78
|
to extract the question + nearby user response context. Sample broadly —
|
|
66
79
|
aim for ~150-200 instances spread across projects and time windows.
|
|
67
|
-
3. Read
|
|
68
|
-
4. Read all files in
|
|
69
|
-
5. Read all *.md files in
|
|
80
|
+
3. Read {claude_dir}/history.jsonl if it exists (rg "AskUserQuestion" ... similarly).
|
|
81
|
+
4. Read all files in {claude_dir}/rules/ (small — read fully).
|
|
82
|
+
5. Read all *.md files in {claude_dir}/projects/*/memory/ (small — read fully).
|
|
70
83
|
|
|
71
84
|
From this evidence, identify the recurring patterns in how the user answers design
|
|
72
85
|
questions. Look for preferences about:
|