mandrel 1.81.0 → 1.83.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/.agents/README.md +46 -5
- package/.agents/docs/SDLC.md +97 -82
- package/.agents/docs/agentrc-reference.json +10 -2
- package/.agents/docs/configuration.md +4 -1
- package/.agents/docs/execution-reference.md +52 -0
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +85 -45
- package/.agents/personas/architect.md +8 -5
- package/.agents/personas/engineer-mobile.md +3 -2
- package/.agents/personas/engineer-web.md +3 -2
- package/.agents/personas/engineer.md +6 -5
- package/.agents/personas/product.md +19 -13
- package/.agents/personas/project-manager.md +9 -8
- package/.agents/personas/qa-engineer.md +10 -6
- package/.agents/personas/refactorer.md +3 -2
- package/.agents/personas/technical-writer.md +2 -1
- package/.agents/personas/ux-designer.md +2 -2
- package/.agents/schemas/agentrc.schema.json +41 -3
- package/.agents/schemas/qa-ledger.schema.json +2 -2
- package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
- package/.agents/scripts/epic-deliver-prepare.js +40 -31
- package/.agents/scripts/epic-plan-decompose.js +2 -5
- package/.agents/scripts/epic-plan-spec.js +16 -19
- package/.agents/scripts/hierarchy-gate.js +11 -11
- package/.agents/scripts/lib/ITicketingProvider.js +4 -3
- package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
- package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
- package/.agents/scripts/lib/cli-args.js +1 -5
- package/.agents/scripts/lib/codebase-snapshot.js +1 -1
- package/.agents/scripts/lib/config/explain.js +4 -1
- package/.agents/scripts/lib/config/temp-paths.js +1 -4
- package/.agents/scripts/lib/config-settings-schema.js +30 -1
- package/.agents/scripts/lib/epic-body-sections.js +310 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
- package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
- package/.agents/scripts/lib/findings/promote-finding.js +3 -3
- package/.agents/scripts/lib/findings/severity.js +5 -6
- package/.agents/scripts/lib/label-constants.js +7 -17
- package/.agents/scripts/lib/label-taxonomy.js +4 -21
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +65 -2
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +105 -9
- package/.agents/scripts/lib/orchestration/doc-reader.js +29 -0
- package/.agents/scripts/lib/orchestration/docs-digest.js +134 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
- package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +15 -1
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
- package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
- package/.agents/scripts/lib/qa/console-allowlist.js +5 -4
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +144 -8
- package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
- package/.agents/scripts/lifecycle-emit.js +1 -1
- package/.agents/scripts/lint-label-vocabulary.js +2 -3
- package/.agents/scripts/providers/github/mappers.js +0 -3
- package/.agents/scripts/providers/github/tickets.js +7 -18
- package/.agents/scripts/single-story-init.js +0 -1
- package/.agents/scripts/story-init.js +1 -29
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +43 -22
- package/.agents/skills/core/epic-plan-consolidate/examples.md +51 -0
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +27 -40
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +47 -0
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +15 -13
- package/.agents/skills/core/epic-plan-premortem/examples.md +53 -0
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +143 -151
- package/.agents/skills/core/epic-plan-spec-author/examples.md +91 -0
- package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
- package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
- package/.agents/skills/core/scope-triage/SKILL.md +2 -1
- package/.agents/skills/skills.index.json +8 -8
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +52 -38
- package/.agents/templates/epic-from-idea.md +4 -0
- package/.agents/workflows/audit-to-stories.md +2 -2
- package/.agents/workflows/helpers/code-review.md +11 -9
- package/.agents/workflows/helpers/deliver-epic-reference.md +514 -0
- package/.agents/workflows/helpers/deliver-epic.md +173 -490
- package/.agents/workflows/helpers/epic-audit.md +11 -8
- package/.agents/workflows/helpers/epic-deliver-story.md +45 -27
- package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
- package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
- package/.agents/workflows/helpers/parallel-tooling.md +2 -1
- package/.agents/workflows/helpers/plan-epic-reference.md +136 -0
- package/.agents/workflows/helpers/plan-epic.md +141 -256
- package/.agents/workflows/helpers/plan-story.md +31 -61
- package/.agents/workflows/helpers/qa-run-scenario.md +194 -0
- package/.agents/workflows/helpers/scope-triage-gate.md +97 -0
- package/.agents/workflows/helpers/single-story-deliver-reference.md +423 -0
- package/.agents/workflows/helpers/single-story-deliver.md +129 -393
- package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
- package/.agents/workflows/plan.md +8 -8
- package/.agents/workflows/qa-assist.md +2 -1
- package/.agents/workflows/qa-explore.md +63 -32
- package/.agents/workflows/qa-run.md +293 -130
- package/docs/CHANGELOG.md +35 -0
- package/package.json +1 -1
- package/.agents/schemas/qa-finding.schema.json +0 -133
- package/.agents/scripts/lib/issue-link-parser.js +0 -74
- package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
- package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
- package/.agents/scripts/lib/story-init/hierarchy-tracer.js +0 -57
|
@@ -44,12 +44,15 @@ change-set selection. Both lens sources fire through the **same**
|
|
|
44
44
|
2. Resolve `[EPIC_BRANCH]` — `epic/<epicId>`.
|
|
45
45
|
3. Resolve `[BASE_BRANCH]` from `baseBranch` in `.agentrc.json` (default:
|
|
46
46
|
`main`).
|
|
47
|
-
4. Fetch the Epic ticket
|
|
48
|
-
|
|
49
|
-
- **
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
4. Fetch the Epic ticket — the Epic body is the single planning
|
|
48
|
+
document:
|
|
49
|
+
- **Narrative sections** — Context / Goal / Scope / User Stories /
|
|
50
|
+
Acceptance Criteria.
|
|
51
|
+
- **Tech Spec** — the folded Tech Spec sections (opening with
|
|
52
|
+
`## Delivery Slicing`) inside the body's managed region.
|
|
53
|
+
5. Read the Epic body fully (including its Tech Spec sections) to
|
|
54
|
+
understand the intended
|
|
55
|
+
scope, selected lenses, and acceptance criteria.
|
|
53
56
|
|
|
54
57
|
## Step 1 — Prepare (`epic-audit-prepare.js`)
|
|
55
58
|
|
|
@@ -226,7 +229,7 @@ For each 🔴 / 🟠 finding, the host LLM MUST decide between two paths:
|
|
|
226
229
|
(path 2) and record the attempt context in Step 4.
|
|
227
230
|
2. **Escalate to the operator via Step 4.** Required when the finding
|
|
228
231
|
falls into any of the following classes:
|
|
229
|
-
- `spec-deviation` — the change diverges from the
|
|
232
|
+
- `spec-deviation` — the change diverges from the Epic/Tech Spec.
|
|
230
233
|
- `secrets` — credentials, tokens, or PII surfaced in the diff.
|
|
231
234
|
- `test-deletion` — coverage was removed without an explicit
|
|
232
235
|
decision in the spec.
|
|
@@ -282,7 +285,7 @@ The body MUST include:
|
|
|
282
285
|
|
|
283
286
|
- **Always** diff against `[BASE_BRANCH]`, not against individual Story
|
|
284
287
|
branches. The audit examines the cumulative effect of the entire Epic.
|
|
285
|
-
- **Always** read the
|
|
288
|
+
- **Always** read the Epic body and Tech Spec before walking lenses. Findings
|
|
286
289
|
without spec context are noise.
|
|
287
290
|
- **Always** cap focused fixes at one attempt per finding (Step 3). The
|
|
288
291
|
host LLM is the executor; there is no shared retry/anti-thrash module
|
|
@@ -77,21 +77,15 @@ the parent's permissions but have **no input channel** mid-run.
|
|
|
77
77
|
Run from the **main checkout** (the worktree does not exist yet):
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
node .agents/scripts/story-init.js --story <storyId>
|
|
81
|
-
--prd <prdId> --tech-spec <techSpecId>
|
|
80
|
+
node .agents/scripts/story-init.js --story <storyId>
|
|
82
81
|
```
|
|
83
82
|
|
|
84
|
-
**
|
|
85
|
-
the Epic
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
during wide fan-out). **Omit** whichever flag the prompt reported as `null`;
|
|
91
|
-
`story-init.js` then falls back to its own `getEpic` resolution for the
|
|
92
|
-
missing id (graceful degradation on a missing Epic linkage). When dispatched
|
|
93
|
-
interactively with neither flag, drop both — the legacy single-fetch path is
|
|
94
|
-
unchanged.
|
|
83
|
+
**No spec-ticket threading (Story #4324).** The Tech Spec lives as managed
|
|
84
|
+
sections of the Epic body — there is no separate Tech-Spec issue, no
|
|
85
|
+
`--tech-spec` flag, and no per-Story hierarchy trace to a spec ticket.
|
|
86
|
+
Your hydrated prompt already embeds the Epic body (with the
|
|
87
|
+
`## Acceptance Table` section stripped), which carries the folded Tech
|
|
88
|
+
Spec sections; do not fetch a Tech Spec issue.
|
|
95
89
|
|
|
96
90
|
> **Execution mode (sub-agents must read).** This command typically takes
|
|
97
91
|
> 3–6 minutes when the worktree's per-tree install runs. Invoke it
|
|
@@ -105,15 +99,15 @@ unchanged.
|
|
|
105
99
|
> partial state, so the recovery is to re-run it synchronously, but
|
|
106
100
|
> prevention is cheaper: just give Bash the 10-minute timeout and block.
|
|
107
101
|
|
|
108
|
-
The script validates `type::story`, checks blockers,
|
|
109
|
-
Epic
|
|
102
|
+
The script validates `type::story`, checks blockers, resolves the parent
|
|
103
|
+
Epic id, seeds `story-<id>` from the
|
|
110
104
|
Epic branch, and (when worktree isolation is on) runs `git worktree add`
|
|
111
105
|
at `.worktrees/story-<id>/`. The Story flips to `agent::executing`. A
|
|
112
106
|
`story-init` structured comment is upserted with the Story's inline
|
|
113
107
|
`acceptance[]` and `verify[]` arrays from the body.
|
|
114
108
|
|
|
115
109
|
Capture `workCwd`, `dependenciesInstalled` (tri-state), and
|
|
116
|
-
`context.
|
|
110
|
+
`context.parentId`. Add `--dry-run` to check
|
|
117
111
|
status without git or ticket changes.
|
|
118
112
|
|
|
119
113
|
### Step 0.5 — `cd` into the workCwd
|
|
@@ -139,11 +133,15 @@ in-process (retrying the install command when
|
|
|
139
133
|
`dependenciesInstalled === 'false'`, default `npm ci`) and rendered the
|
|
140
134
|
initial snapshot (`phase: "init"`). There is no separate command to run.
|
|
141
135
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
136
|
+
Step 0's init run already upserted the initial `story-run-progress`
|
|
137
|
+
snapshot (`phase: "init"`) as a structured comment on the Story — that
|
|
138
|
+
comment, refreshed by `story-phase.js` at each transition, is the
|
|
139
|
+
authoritative Story-level rollup the parent `/deliver` aggregator reads.
|
|
140
|
+
You do **not** relay `prepare.renderedBody` verbatim to chat. Instead,
|
|
141
|
+
relay **one line per phase transition** (e.g. `Story #<id>: init →
|
|
142
|
+
implementing`), and do the same after every transition in Step 1 / Step 3.
|
|
143
|
+
The snapshot CLI carries the full body; the chat line is a terse progress
|
|
144
|
+
delta, not a body dump.
|
|
147
145
|
|
|
148
146
|
---
|
|
149
147
|
|
|
@@ -168,6 +166,20 @@ Run a single Story-implementation phase against the inline `acceptance[]`
|
|
|
168
166
|
`context.verify`). Treat the acceptance items as the contract and
|
|
169
167
|
the verify items as the canonical at-keyboard checks.
|
|
170
168
|
|
|
169
|
+
**Docs context — read the digest, not the full set.** Do **not**
|
|
170
|
+
re-read every file in `project.docsContextFiles`. The parent prompt
|
|
171
|
+
passes a `docsDigestPath` (the per-Epic docs digest at
|
|
172
|
+
`temp/epic-<epicId>/docs-digest.md`, written by
|
|
173
|
+
`epic-deliver-prepare.js`). Read that digest — a compact per-file
|
|
174
|
+
outline (path, size, heading outline with line numbers, first
|
|
175
|
+
paragraph under each `##`) — to decide which docs bear on this Story,
|
|
176
|
+
then **pull the full file on demand** (jump to the section at the line
|
|
177
|
+
number the digest names) only when relevant. When `docsDigestPath` is
|
|
178
|
+
null (the project configured no `docsContextFiles`), there is no
|
|
179
|
+
digest and no per-Story docs mandate — read a full doc only if the
|
|
180
|
+
Story's own context points you at one. See
|
|
181
|
+
[`.agents/instructions.md` § 3](../../instructions.md).
|
|
182
|
+
|
|
171
183
|
3. Implement the work as one or more commits on `story-<storyId>`.
|
|
172
184
|
Author commits directly with the project's editor / `git commit`,
|
|
173
185
|
following
|
|
@@ -246,10 +258,14 @@ partially-implemented Story picks up from whatever commits are already
|
|
|
246
258
|
on `story-<storyId>`; the agent inspects `git log` to decide what work
|
|
247
259
|
remains.
|
|
248
260
|
|
|
249
|
-
After each `story-phase.js` call,
|
|
250
|
-
`
|
|
251
|
-
|
|
252
|
-
the
|
|
261
|
+
After each `story-phase.js` call, relay **one line naming the phase
|
|
262
|
+
transition** (e.g. `Story #<id>: implementing → closing`) as the Story's
|
|
263
|
+
progress update — not the envelope's `renderedBody` verbatim. The
|
|
264
|
+
`story-phase.js` CLI has already upserted the full body into the
|
|
265
|
+
`story-run-progress` snapshot; that comment is the authoritative rollup
|
|
266
|
+
the parent `/deliver` aggregator reads. Skip chat relay entirely when
|
|
267
|
+
running in a non-interactive sub-agent context where the parent will
|
|
268
|
+
aggregate.
|
|
253
269
|
|
|
254
270
|
> Rebase pauses on conflicts → follow
|
|
255
271
|
> [`_merge-conflict-template.md`](_merge-conflict-template.md).
|
|
@@ -344,8 +360,10 @@ regardless of the reap status.
|
|
|
344
360
|
`story-phase.js` (typically the `phase: 'done'` snapshot at close,
|
|
345
361
|
or the `phase: 'blocked'` snapshot on a blocker). The parent
|
|
346
362
|
`/deliver` may inline a digest of this in its wave-level Notable
|
|
347
|
-
section. When run interactively (no parent), omit it — the
|
|
348
|
-
|
|
363
|
+
section. When run interactively (no parent), omit it — the authoritative
|
|
364
|
+
body lives in the `story-run-progress` snapshot the phase CLI upserted,
|
|
365
|
+
and the chat already carries the per-transition progress lines from
|
|
366
|
+
Step 1 / Step 3.
|
|
349
367
|
|
|
350
368
|
---
|
|
351
369
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: >-
|
|
3
|
-
Phase 8 of sprint planning — decompose an Epic's
|
|
3
|
+
Phase 8 of sprint planning — decompose an Epic's sectioned body (which
|
|
4
|
+
carries the folded Tech Spec) into a
|
|
4
5
|
backlog of child Stories, persist the backlog, and flip the Epic to
|
|
5
6
|
`agent::ready`. Host-LLM authored; no external API calls.
|
|
6
7
|
---
|
|
@@ -18,8 +19,9 @@ Director / Architect
|
|
|
18
19
|
## Context
|
|
19
20
|
|
|
20
21
|
This helper is the **decompose phase** of the split planning pipeline. It
|
|
21
|
-
reads the
|
|
22
|
-
|
|
22
|
+
reads the Epic body — whose managed sections carry the Tech Spec previously
|
|
23
|
+
produced by the spec phase
|
|
24
|
+
helper ([`epic-plan-spec.md`](epic-plan-spec.md)) — generates the Epic's child
|
|
23
25
|
Story tickets, persists them to GitHub, and flips the Epic to
|
|
24
26
|
`agent::ready` (parking) so a human can run `/deliver` when
|
|
25
27
|
execution should begin.
|
|
@@ -38,9 +40,9 @@ skill.
|
|
|
38
40
|
|
|
39
41
|
## Constraint
|
|
40
42
|
|
|
41
|
-
- **Do not** run this skill until the spec phase is complete. The Epic
|
|
42
|
-
|
|
43
|
-
refuse to proceed otherwise.
|
|
43
|
+
- **Do not** run this skill until the spec phase is complete. The Epic body
|
|
44
|
+
must carry Tech Spec content (the managed section or a `## Delivery
|
|
45
|
+
Slicing` heading); the script will refuse to proceed otherwise.
|
|
44
46
|
- **Do not** restructure the Story set after the decomposition
|
|
45
47
|
writes — the `epic-plan-state` checkpoint records the structure as
|
|
46
48
|
committed. Use `--force` to rebuild from scratch.
|
|
@@ -52,7 +54,7 @@ skill.
|
|
|
52
54
|
## Prerequisites
|
|
53
55
|
|
|
54
56
|
1. **Epic is on `agent::review-spec`** — i.e. the spec phase has already run
|
|
55
|
-
and the
|
|
57
|
+
and the Epic body carries the Tech Spec sections.
|
|
56
58
|
2. **API keys** — `GITHUB_TOKEN` set in `.env`.
|
|
57
59
|
|
|
58
60
|
## Step 1 — Gather decomposition context
|
|
@@ -62,7 +64,8 @@ node .agents/scripts/epic-plan-decompose.js --epic [Epic_ID] --emit-context \
|
|
|
62
64
|
> temp/epic-[Epic_ID]/decomposer-context.json
|
|
63
65
|
```
|
|
64
66
|
|
|
65
|
-
The emitted JSON contains the
|
|
67
|
+
The emitted JSON contains the Epic body (`epicBody` — the spec sections and
|
|
68
|
+
acceptance table travel inside it), risk heuristics, the
|
|
66
69
|
decomposer system prompt, and the `maxTickets` **reviewability budget**
|
|
67
70
|
(Story #2798 — not a hard cap; over-budget plans require an explicit
|
|
68
71
|
`--allow-over-budget` override at persist time).
|
|
@@ -74,7 +77,7 @@ Story objects that conforms to the schema in the system prompt
|
|
|
74
77
|
and write it to `temp/epic-[Epic_ID]/tickets.json`.
|
|
75
78
|
|
|
76
79
|
When the Tech Spec carries a `## Delivery Slicing` section, author toward the
|
|
77
|
-
Architect's proposed shippable-Story clusters rather than mapping
|
|
80
|
+
Architect's proposed shippable-Story clusters rather than mapping Epic
|
|
78
81
|
capabilities 1:1; degrade gracefully (current behaviour) when it is absent.
|
|
79
82
|
|
|
80
83
|
## Step 2.5 — Phase 8.3: Holistic Consolidation (HITL diff gate)
|
|
@@ -87,7 +90,8 @@ deterministic validator and **before** the GitHub write.
|
|
|
87
90
|
Activate the
|
|
88
91
|
[`epic-plan-consolidate`](../../skills/core/epic-plan-consolidate/SKILL.md)
|
|
89
92
|
skill with `[Epic_ID]` as input. It reads the draft
|
|
90
|
-
`temp/epic-[Epic_ID]/tickets.json` plus the
|
|
93
|
+
`temp/epic-[Epic_ID]/tickets.json` plus the Epic body (with its folded
|
|
94
|
+
Tech Spec sections) from
|
|
91
95
|
`decomposer-context.json`, reconciles the draft against the Tech Spec
|
|
92
96
|
`## Delivery Slicing` target (degrading gracefully when absent), and emits:
|
|
93
97
|
|
|
@@ -187,8 +191,9 @@ is the single source of truth for which temp paths this phase owns.
|
|
|
187
191
|
|
|
188
192
|
## Troubleshooting
|
|
189
193
|
|
|
190
|
-
- "Epic #N
|
|
191
|
-
|
|
194
|
+
- "Epic #N body carries no Tech Spec sections (no ## Delivery Slicing)" —
|
|
195
|
+
run `/plan [Epic_ID]`
|
|
196
|
+
first (it will run the spec phase if the Tech Spec sections are missing).
|
|
192
197
|
- Validator rejects the tickets file — the most common causes are a
|
|
193
198
|
Story whose `parent_slug` does not point at a Feature, a missing
|
|
194
199
|
`acceptance[]` / `verify[]` array on a Story body, or a Story
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: >-
|
|
3
|
-
Phase 7 of sprint planning — generate the
|
|
4
|
-
persist them as
|
|
5
|
-
`agent::review-spec`. Host-LLM authored; no external API calls.
|
|
3
|
+
Phase 7 of sprint planning — generate the Tech Spec and Acceptance Table for
|
|
4
|
+
an Epic, persist them as managed sections of the Epic body, and flip the
|
|
5
|
+
Epic to `agent::review-spec`. Host-LLM authored; no external API calls.
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Sprint Plan — Spec Phase (helper)
|
|
@@ -18,22 +18,28 @@ Director / Architect
|
|
|
18
18
|
## Context
|
|
19
19
|
|
|
20
20
|
This helper is the **spec phase** of the split planning pipeline. It produces
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
reviewer can read the
|
|
21
|
+
two planning artifacts for an Epic — a Technical Specification and an
|
|
22
|
+
Acceptance Table — persists them as **marker-delimited managed sections of
|
|
23
|
+
the Epic body** (`<!-- mandrel:tech-spec:start/end -->` and
|
|
24
|
+
`<!-- mandrel:acceptance-table:start/end -->`), and flips the Epic to
|
|
25
|
+
`agent::review-spec` (parking) so a human reviewer can read the updated Epic
|
|
26
|
+
body on GitHub before decomposition. A `/plan` Epic run creates exactly
|
|
27
|
+
**one** issue — the Epic. The PRD artifact class was retired (Story #4314);
|
|
28
|
+
its one novel section, **User Stories**, lives inline in the Epic body.
|
|
29
|
+
Story #4324 retired the `context::tech-spec` / `context::acceptance-spec`
|
|
30
|
+
ticket classes the same way — the content semantics are unchanged, only
|
|
31
|
+
where the output lives moved.
|
|
26
32
|
|
|
27
33
|
> **Single prose home.** The canonical, full-detail spec-phase contract
|
|
28
|
-
> (idempotent
|
|
34
|
+
> (idempotent managed sections, the fold rationale, the
|
|
29
35
|
> `acceptance::n-a` waiver, the Epic-lease preflight) lives in
|
|
30
36
|
> [`epic-plan.md` § Phase 7](plan-epic.md). This helper carries only the
|
|
31
37
|
> operational step list; when the two disagree, `epic-plan.md` wins.
|
|
32
38
|
|
|
33
|
-
The
|
|
34
|
-
`epic-plan-spec.js` is a deterministic wrapper that (a) emits the
|
|
35
|
-
context you need and (b) persists the
|
|
36
|
-
lifecycle state.
|
|
39
|
+
The Tech Spec and Acceptance Table are authored **directly by you, the host
|
|
40
|
+
LLM**. `epic-plan-spec.js` is a deterministic wrapper that (a) emits the
|
|
41
|
+
authoring context you need and (b) persists the sections and transitions the
|
|
42
|
+
Epic lifecycle state.
|
|
37
43
|
|
|
38
44
|
The complementary Phase 8 helper is
|
|
39
45
|
[`epic-plan-decompose.md`](epic-plan-decompose.md). The `/plan`
|
|
@@ -41,14 +47,14 @@ wrapper chains both helpers with a confirmation gate in between.
|
|
|
41
47
|
|
|
42
48
|
## Constraint
|
|
43
49
|
|
|
44
|
-
- **Do not** create
|
|
45
|
-
|
|
50
|
+
- **Do not** create any tickets from this phase — the only GitHub write is
|
|
51
|
+
the section-scoped Epic body update (plus structured comments);
|
|
46
52
|
decomposition belongs to
|
|
47
53
|
[`epic-plan-decompose.md`](epic-plan-decompose.md).
|
|
48
54
|
- **Do not** flip the Epic to `agent::ready` from this skill. The terminal
|
|
49
55
|
label for the spec phase is `agent::review-spec`.
|
|
50
56
|
- **Every** temp file must include the Epic ID in its name. Multiple Epics may
|
|
51
|
-
be planned concurrently; bare names like `temp/
|
|
57
|
+
be planned concurrently; bare names like `temp/techspec.md` will collide.
|
|
52
58
|
- **Stop and hand back to the operator** after Step 4 when
|
|
53
59
|
`planningRisk.requiresReview` is true or the operator passed
|
|
54
60
|
`--force-review` — do not chain into decomposition. Low-risk Epics
|
|
@@ -58,7 +64,8 @@ wrapper chains both helpers with a confirmation gate in between.
|
|
|
58
64
|
## Prerequisites
|
|
59
65
|
|
|
60
66
|
1. **GitHub Epic** — an open issue with the `type::epic` label. The Epic's
|
|
61
|
-
body should contain enough narrative context
|
|
67
|
+
body should contain enough narrative context (including its `## User
|
|
68
|
+
Stories` section) to seed the Tech Spec.
|
|
62
69
|
2. **API keys** — `GITHUB_TOKEN` set in `.env`.
|
|
63
70
|
|
|
64
71
|
## Step 1 — Gather authoring context
|
|
@@ -71,23 +78,18 @@ node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] --emit-context \
|
|
|
71
78
|
> temp/epic-[Epic_ID]/planner-context.json
|
|
72
79
|
```
|
|
73
80
|
|
|
74
|
-
## Step 2 — Author the
|
|
81
|
+
## Step 2 — Author the Tech Spec
|
|
75
82
|
|
|
76
|
-
Read `temp/epic-[Epic_ID]/planner-context.json`. Using
|
|
77
|
-
|
|
78
|
-
`
|
|
79
|
-
|
|
80
|
-
`##
|
|
83
|
+
Read `temp/epic-[Epic_ID]/planner-context.json`. Using
|
|
84
|
+
`systemPrompts.techSpec`, the Epic body (its Context / Goal / Scope / User
|
|
85
|
+
Stories sections), and `docsContext`, write the Tech Spec to
|
|
86
|
+
`temp/epic-[Epic_ID]/techspec.md`. Open the document with the
|
|
87
|
+
`## Delivery Slicing` section (no `<h1>`); do not restate the Epic's
|
|
88
|
+
Context / Goal / Scope — the output lands as sections of the same Epic body.
|
|
81
89
|
|
|
82
|
-
## Step
|
|
90
|
+
## Step 2.5 — Author the risk verdict
|
|
83
91
|
|
|
84
|
-
|
|
85
|
-
write the Tech Spec to `temp/epic-[Epic_ID]/techspec.md`. Start with
|
|
86
|
-
`## Technical Overview` (no `<h1>`).
|
|
87
|
-
|
|
88
|
-
## Step 3.5 — Author the risk verdict
|
|
89
|
-
|
|
90
|
-
Judge the change described by the PRD and Tech Spec you just wrote and
|
|
92
|
+
Judge the change described by the Epic body and Tech Spec you just wrote and
|
|
91
93
|
write `temp/epic-[Epic_ID]/risk-verdict.json` conforming to
|
|
92
94
|
[`risk-verdict.schema.json`](../../schemas/risk-verdict.schema.json):
|
|
93
95
|
`{ axes: [{ axis, level, rationale }], summary }`. The authoritative
|
|
@@ -95,39 +97,36 @@ authoring rules (axis vocabulary, judgment-not-keywords, derivation
|
|
|
95
97
|
preview) live in the
|
|
96
98
|
[`epic-plan-spec-author` Skill, Step 4](../../skills/core/epic-plan-spec-author/SKILL.md).
|
|
97
99
|
|
|
98
|
-
## Step
|
|
100
|
+
## Step 2.6 — Author the Acceptance Table
|
|
99
101
|
|
|
100
|
-
Using `systemPrompts.acceptanceSpec`, the
|
|
101
|
-
Acceptance Spec to `temp/epic-[Epic_ID]/acceptance-spec.md`. It
|
|
102
|
-
stable-ID acceptance criteria
|
|
103
|
-
(`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that
|
|
104
|
-
close-time reconciliation in `/deliver` Phase 6.
|
|
102
|
+
Using `systemPrompts.acceptanceSpec`, the Epic body, and the Tech Spec, write
|
|
103
|
+
the Acceptance Spec to `temp/epic-[Epic_ID]/acceptance-spec.md`. It opens
|
|
104
|
+
with `## Acceptance Table` and captures the stable-ID acceptance criteria
|
|
105
|
+
table (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that
|
|
106
|
+
drives close-time reconciliation in `/deliver` Phase 6.
|
|
105
107
|
|
|
106
108
|
**Skip this step only** when the Epic carries the `acceptance::n-a` waiver
|
|
107
|
-
label (refactor-only or docs-only Epics); in that case omit
|
|
108
|
-
from Step
|
|
109
|
+
label (refactor-only or docs-only Epics); in that case omit
|
|
110
|
+
`--acceptance-table` from Step 3.
|
|
109
111
|
|
|
110
|
-
## Step
|
|
112
|
+
## Step 3 — Persist and transition
|
|
111
113
|
|
|
112
114
|
```bash
|
|
113
|
-
# Normal flow (
|
|
115
|
+
# Normal flow (both managed sections)
|
|
114
116
|
node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
|
|
115
|
-
--
|
|
116
|
-
--techspec temp/epic-[Epic_ID]/techspec.md \
|
|
117
|
+
--tech-spec temp/epic-[Epic_ID]/techspec.md \
|
|
117
118
|
--risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
|
|
118
|
-
--acceptance-
|
|
119
|
+
--acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md
|
|
119
120
|
|
|
120
|
-
# Re-plan (--force overwrites the
|
|
121
|
+
# Re-plan (--force overwrites the managed sections in place)
|
|
121
122
|
node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
|
|
122
|
-
--
|
|
123
|
-
--techspec temp/epic-[Epic_ID]/techspec.md \
|
|
123
|
+
--tech-spec temp/epic-[Epic_ID]/techspec.md \
|
|
124
124
|
--risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
|
|
125
|
-
--acceptance-
|
|
125
|
+
--acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md --force
|
|
126
126
|
|
|
127
|
-
# Waived (acceptance::n-a label on Epic — no Acceptance
|
|
127
|
+
# Waived (acceptance::n-a label on Epic — no Acceptance Table authored)
|
|
128
128
|
node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
|
|
129
|
-
--
|
|
130
|
-
--techspec temp/epic-[Epic_ID]/techspec.md \
|
|
129
|
+
--tech-spec temp/epic-[Epic_ID]/techspec.md \
|
|
131
130
|
--risk-verdict temp/epic-[Epic_ID]/risk-verdict.json
|
|
132
131
|
```
|
|
133
132
|
|
|
@@ -136,22 +135,21 @@ On success the script:
|
|
|
136
135
|
- Validates the risk verdict against `risk-verdict.schema.json` (a
|
|
137
136
|
malformed verdict fails closed before any GitHub mutation) and derives
|
|
138
137
|
the `planningRisk` envelope from it.
|
|
139
|
-
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
omitted under the `acceptance::n-a` waiver.
|
|
143
|
-
- Appends a `## Planning Artifacts` section to the Epic body.
|
|
138
|
+
- Upserts the Tech Spec content and (unless waived) the `## Acceptance
|
|
139
|
+
Table` as managed sections of the Epic body, stripping any legacy
|
|
140
|
+
`## Planning Artifacts` section. The Acceptance Table is skipped when
|
|
141
|
+
`--acceptance-table` is omitted under the `acceptance::n-a` waiver.
|
|
144
142
|
- Upserts the `risk-verdict` structured comment recording the verdict and
|
|
145
143
|
the derived envelope.
|
|
146
144
|
- Upserts the `epic-plan-state` structured comment with the current phase,
|
|
147
|
-
|
|
148
|
-
timestamps.
|
|
145
|
+
the persisted-section flags (`techSpecPersisted`, `acceptanceTable`),
|
|
146
|
+
the `riskVerdict` field, and timestamps.
|
|
149
147
|
- Flips the Epic to `agent::review-spec`.
|
|
150
148
|
|
|
151
|
-
## Step
|
|
149
|
+
## Step 4 — Cleanup
|
|
152
150
|
|
|
153
151
|
The wrapper script deletes the phase-scoped temp files automatically when
|
|
154
|
-
Step
|
|
152
|
+
Step 3 succeeds — no operator action required. The cleanup contract lives in
|
|
155
153
|
[`lib/plan-phase-cleanup.js`](../../scripts/lib/plan-phase-cleanup.js), which
|
|
156
154
|
is the single source of truth for which temp paths this phase owns. If you
|
|
157
155
|
need to inspect the temp artefacts after the fact, re-run
|
|
@@ -162,12 +160,13 @@ need to inspect the temp artefacts after the fact, re-run
|
|
|
162
160
|
Branch on the shared planning risk decision surfaced in the persist stdout
|
|
163
161
|
JSON (`planningRisk`, `reviewRouting`):
|
|
164
162
|
|
|
165
|
-
- **High risk or `--force-review` — STOP.** Surface the
|
|
166
|
-
|
|
163
|
+
- **High risk or `--force-review` — STOP.** Surface the Epic URL to the
|
|
164
|
+
operator:
|
|
167
165
|
|
|
168
|
-
> "Spec phase complete for Epic #[ID]. Review
|
|
169
|
-
> on GitHub. When you're
|
|
170
|
-
>
|
|
166
|
+
> "Spec phase complete for Epic #[ID]. Review the updated Epic body
|
|
167
|
+
> (Tech Spec sections + `## Acceptance Table`) on GitHub. When you're
|
|
168
|
+
> ready, re-run `/plan [Epic_ID]` — the wrapper will pick up where it
|
|
169
|
+
> left off and run the decompose phase."
|
|
171
170
|
|
|
172
171
|
- **Low risk — auto-proceed.** Relay `reviewRouting.operatorMessage` and
|
|
173
172
|
continue directly to Phase 8 decomposition without waiting for verbal
|
|
@@ -177,8 +176,9 @@ JSON (`planningRisk`, `reviewRouting`):
|
|
|
177
176
|
|
|
178
177
|
- If `--emit-context` fails with "Epic not found", confirm the ID matches the
|
|
179
178
|
GitHub issue number and the token has `issues:read`.
|
|
180
|
-
- If the persist call fails after
|
|
181
|
-
re-run with `--force` (the
|
|
179
|
+
- If the persist call fails after writing the Tech Spec section but before
|
|
180
|
+
the Acceptance Table, re-run with `--force` (the section upsert is
|
|
181
|
+
idempotent — it replaces the managed regions in place).
|
|
182
182
|
- If the Epic does not flip to `agent::review-spec` after the script claims
|
|
183
183
|
success, the label write likely races with a concurrent mutation — re-run the
|
|
184
|
-
persist step; it's idempotent against the
|
|
184
|
+
persist step; it's idempotent against the already-persisted sections.
|
|
@@ -20,7 +20,8 @@ them in one assistant turn rather than serially. The host runtime executes
|
|
|
20
20
|
the batch in parallel; serial calls cost N round-trips for no gain.
|
|
21
21
|
|
|
22
22
|
- **Tool primitives:** `Read`, `Grep`, `Glob`, MCP `list_*` / `get_*` calls.
|
|
23
|
-
- **When:** reading the
|
|
23
|
+
- **When:** reading the Epic body (with its folded Tech Spec sections)
|
|
24
|
+
and Story body up front; grepping
|
|
24
25
|
for multiple unrelated patterns; globbing several directory trees;
|
|
25
26
|
fetching independent GitHub tickets.
|
|
26
27
|
- **Anti-pattern:** sequential `Read` → wait → `Read` → wait → `Grep` chains
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >-
|
|
3
|
+
Reference companion to plan-epic.md — the recovery procedures, --resume
|
|
4
|
+
mechanics, troubleshooting, and background rationale blocks moved out of the
|
|
5
|
+
runtime core so every /plan run ingests only the phase flow. Read on demand
|
|
6
|
+
from the trigger-point pointers in plan-epic.md.
|
|
7
|
+
caller: plan-epic.md
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# helpers/plan-epic-reference — Epic-planning reference & recovery
|
|
11
|
+
|
|
12
|
+
> **Not a slash command.** This file lives in `helpers/` and is a
|
|
13
|
+
> path-included reference module (not projected into the plugin command
|
|
14
|
+
> tree). [`plan-epic.md`](plan-epic.md) is the runtime core — the phase
|
|
15
|
+
> flow, commands, and gate contracts. This file holds the secondary
|
|
16
|
+
> material a run needs only when it hits an edge (a recovery path, a
|
|
17
|
+
> troubleshooting symptom) or wants the design rationale behind a phase.
|
|
18
|
+
> Each section below is reached from a one-line pointer at its trigger
|
|
19
|
+
> point in the core.
|
|
20
|
+
|
|
21
|
+
## Phase 7 — background rationale
|
|
22
|
+
|
|
23
|
+
The Phase 7 (Tech Spec & Acceptance Spec) core carries only the commands and
|
|
24
|
+
the gate contract. The design rationale for the phase's guards and managed
|
|
25
|
+
sections lives here.
|
|
26
|
+
|
|
27
|
+
### Epic-lease preflight (workflow guard)
|
|
28
|
+
|
|
29
|
+
Before any Phase 7 mutation, `epic-plan-spec.js` acquires the Epic-lease via
|
|
30
|
+
the assignee-as-lease primitive (`lib/orchestration/ticket-lease.js`, wired
|
|
31
|
+
through `lib/orchestration/epic-plan-lease-guard.js`). The lease rides the
|
|
32
|
+
Epic's single assignee: the operator (`github.operatorHandle` in
|
|
33
|
+
`.agentrc.json`) claims the Epic for the duration of the plan. The guard
|
|
34
|
+
**fails closed**: `/plan` emits no `story.heartbeat` during its run
|
|
35
|
+
(heartbeats are a delivery-time signal), so there is no live-heartbeat source
|
|
36
|
+
to judge a concurrent plan's liveness from. Any **foreign assignee** is
|
|
37
|
+
therefore treated as a live claim — the persist half **exits non-zero and
|
|
38
|
+
names the current owner**, so two `/plan` runs cannot drive the same Epic
|
|
39
|
+
concurrently. Pass **`--steal`** to forcibly transfer a foreign claim once you
|
|
40
|
+
have confirmed the other run is dead. An **unassigned** Epic, or one **already
|
|
41
|
+
held by this operator**, is taken (or re-affirmed) silently. The lease is
|
|
42
|
+
**released after Phase 8** (decompose) completes.
|
|
43
|
+
|
|
44
|
+
### Idempotent managed sections
|
|
45
|
+
|
|
46
|
+
The persist half is section-scoped and keyed on the Epic body: a re-run that
|
|
47
|
+
finds the requested sections already present
|
|
48
|
+
(`<!-- mandrel:tech-spec:start/end -->` /
|
|
49
|
+
`<!-- mandrel:acceptance-table:start/end -->`) short-circuits as
|
|
50
|
+
`already-planned` instead of duplicating content. Pass `--force` to overwrite
|
|
51
|
+
the managed sections in place (same Epic issue, refreshed section bodies).
|
|
52
|
+
|
|
53
|
+
### One planning document
|
|
54
|
+
|
|
55
|
+
A `/plan` Epic run creates exactly **one** issue — the Epic. The planning
|
|
56
|
+
artifacts land as marker-delimited managed sections of the Epic body: the Tech
|
|
57
|
+
Spec (opening with `## Delivery Slicing`) inside
|
|
58
|
+
`<!-- mandrel:tech-spec:start/end -->`, and the Acceptance Spec's AC-ID table
|
|
59
|
+
(headed `## Acceptance Table`) inside
|
|
60
|
+
`<!-- mandrel:acceptance-table:start/end -->`. The PRD artifact class was
|
|
61
|
+
retired (Story #4314) — its one novel section, **User Stories**, lives inline
|
|
62
|
+
in the Epic body as a `## User Stories` section — and Story #4324 retired the
|
|
63
|
+
`context::tech-spec` / `context::acceptance-spec` ticket classes the same way.
|
|
64
|
+
The `## Acceptance Table` section captures the stable-ID acceptance criteria
|
|
65
|
+
table (`| AC ID | Outcome | Feature File | Scenario | Disposition |`) that
|
|
66
|
+
drives close-time reconciliation during `/deliver` Phase 6. Operators may opt
|
|
67
|
+
out for refactor-only or docs-only Epics by applying the `acceptance::n-a`
|
|
68
|
+
label to the Epic ticket — when present, the `epic-plan-spec-author` skill
|
|
69
|
+
skips the Acceptance Table output and the runtime gates (start gate, finalize
|
|
70
|
+
reconciler) honour the waiver — the section need not be authored when the
|
|
71
|
+
waiver is set. See [SDLC § Acceptance Table — the second folded planning
|
|
72
|
+
section](../../docs/SDLC.md#acceptance-table--the-second-folded-planning-section)
|
|
73
|
+
for the full lifecycle.
|
|
74
|
+
|
|
75
|
+
### Parallel-safe file naming (per-Epic tree)
|
|
76
|
+
|
|
77
|
+
Multiple Epics may be planned or decomposed concurrently. Every temp file
|
|
78
|
+
written in the workflow lives under the per-Epic tree
|
|
79
|
+
(`temp/epic-[Epic_ID]/<artifact>`) — e.g.
|
|
80
|
+
`temp/epic-[Epic_ID]/planner-context.json`,
|
|
81
|
+
`temp/epic-[Epic_ID]/techspec.md`,
|
|
82
|
+
`temp/epic-[Epic_ID]/decomposer-context.json`,
|
|
83
|
+
`temp/epic-[Epic_ID]/tickets.json`. The directory namespace is the isolation
|
|
84
|
+
boundary; basenames inside it are stable. Do **not** reuse bare flat names
|
|
85
|
+
like `temp/techspec.md` or the legacy `temp/<artifact>-epic-<id>.<ext>` shape
|
|
86
|
+
— both have been retired.
|
|
87
|
+
|
|
88
|
+
**Durability.** The per-Epic tree is durable across runs: only the wrapper
|
|
89
|
+
scripts perform intra-phase cleanup of files they wrote in the same invocation
|
|
90
|
+
(see [`lib/plan-phase-cleanup.js`](../../scripts/lib/plan-phase-cleanup.js)).
|
|
91
|
+
Nothing else garbage-collects the tree, so cross-Epic artifacts — retros, perf
|
|
92
|
+
reports, signals, manifests — accumulate until an operator explicitly removes
|
|
93
|
+
them.
|
|
94
|
+
|
|
95
|
+
## Phase 8 — `--resume` recovery (secondary rate limit)
|
|
96
|
+
|
|
97
|
+
The Phase 8 (Work Breakdown Decomposition) core carries the normal-path and
|
|
98
|
+
`--force` persist commands. The `--resume` recovery path — reached when a
|
|
99
|
+
large decomposition aborts mid-persist — lives here.
|
|
100
|
+
|
|
101
|
+
**Secondary rate limit on large Epics.** For backlogs over ~60 tickets,
|
|
102
|
+
GitHub's secondary rate limit (HTTP 403, body contains "secondary rate limit")
|
|
103
|
+
can trip mid-decomposition after ~80 issue creations. The http-client retries
|
|
104
|
+
automatically with a 30–120s backoff and the decomposer drops `concurrencyCap`
|
|
105
|
+
to 1 for the rest of the run on the first observation. If the run still aborts
|
|
106
|
+
(network drop, exhausted retries, etc.), resume from the partial backlog with:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
node .agents/scripts/epic-plan-decompose.js --epic [Epic_ID] \
|
|
110
|
+
--tickets temp/epic-[Epic_ID]/tickets.json --resume
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`--resume` is idempotent: the reconciler recovers the slug→issue map from
|
|
114
|
+
`temp/epic-[Epic_ID]/[Epic_ID].state.json`, and when that file is missing or
|
|
115
|
+
incomplete it **reseeds the map from live GitHub state** by matching each spec
|
|
116
|
+
slug against the open children of the Epic by title. Slugs that resolve to an
|
|
117
|
+
existing open child diff as Updates/no-ops; only the genuinely-missing children
|
|
118
|
+
are created — the existing tree is never duplicated. To force-throttle from the
|
|
119
|
+
first call on a known-large Epic, set `(framework constant: decomposer
|
|
120
|
+
concurrency): 1` in `.agentrc.json`.
|
|
121
|
+
|
|
122
|
+
## Troubleshooting
|
|
123
|
+
|
|
124
|
+
- If `epic-plan-spec.js --emit-context` fails, confirm the Epic exists and
|
|
125
|
+
has a body with enough initial context.
|
|
126
|
+
- If `epic-plan-decompose.js` rejects the tickets file, re-read the
|
|
127
|
+
validator's error message — the most common causes are a ticket whose
|
|
128
|
+
`type` is not `story`, a Story missing its inline `acceptance[]` /
|
|
129
|
+
`verify[]` contract, or a dependency cycle in the Story `depends_on`
|
|
130
|
+
graph.
|
|
131
|
+
- If decomposition persisted the tickets but the Epic is not on `agent::ready`,
|
|
132
|
+
you likely called `runDecomposePhase` from `epic-plan-decompose.js`
|
|
133
|
+
directly without completing the persist flow — only the CLI surface
|
|
134
|
+
(`node epic-plan-decompose.js --tickets ...`) drives the full
|
|
135
|
+
reconciler pipeline and flips the lifecycle label. Apply `agent::ready`
|
|
136
|
+
by hand and re-run via the CLI next time.
|