mandrel 1.80.0 → 1.82.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.
Files changed (101) hide show
  1. package/.agents/README.md +5 -5
  2. package/.agents/docs/SDLC.md +93 -80
  3. package/.agents/docs/configuration.md +11 -1
  4. package/.agents/docs/quality-gates.md +61 -0
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +9 -7
  7. package/.agents/personas/architect.md +8 -5
  8. package/.agents/personas/engineer-mobile.md +3 -2
  9. package/.agents/personas/engineer-web.md +3 -2
  10. package/.agents/personas/engineer.md +6 -5
  11. package/.agents/personas/product.md +19 -13
  12. package/.agents/personas/project-manager.md +9 -8
  13. package/.agents/personas/qa-engineer.md +10 -6
  14. package/.agents/personas/refactorer.md +3 -2
  15. package/.agents/personas/technical-writer.md +2 -1
  16. package/.agents/personas/ux-designer.md +2 -2
  17. package/.agents/schemas/agentrc.schema.json +10 -0
  18. package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
  19. package/.agents/scripts/epic-deliver-prepare.js +0 -31
  20. package/.agents/scripts/epic-plan-decompose.js +2 -5
  21. package/.agents/scripts/epic-plan-spec.js +16 -19
  22. package/.agents/scripts/hierarchy-gate.js +11 -11
  23. package/.agents/scripts/lib/ITicketingProvider.js +4 -3
  24. package/.agents/scripts/lib/baselines/env-overrides.js +35 -0
  25. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  26. package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
  27. package/.agents/scripts/lib/cli-args.js +1 -5
  28. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  29. package/.agents/scripts/lib/config/temp-paths.js +1 -4
  30. package/.agents/scripts/lib/config-settings-schema.js +5 -0
  31. package/.agents/scripts/lib/epic-body-sections.js +222 -0
  32. package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
  33. package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
  34. package/.agents/scripts/lib/label-constants.js +7 -17
  35. package/.agents/scripts/lib/label-taxonomy.js +4 -21
  36. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +47 -1
  37. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +7 -0
  38. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +1 -1
  39. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +2 -1
  40. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +19 -8
  41. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
  42. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
  43. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
  44. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
  45. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
  46. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
  47. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
  48. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
  49. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
  50. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
  51. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
  52. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
  53. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
  54. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
  55. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
  56. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
  57. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  58. package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
  59. package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
  60. package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
  61. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  62. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
  63. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
  64. package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
  65. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
  66. package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
  67. package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
  68. package/.agents/scripts/lifecycle-emit.js +1 -1
  69. package/.agents/scripts/lint-label-vocabulary.js +2 -3
  70. package/.agents/scripts/providers/github/mappers.js +0 -3
  71. package/.agents/scripts/providers/github/tickets.js +7 -18
  72. package/.agents/scripts/single-story-init.js +0 -1
  73. package/.agents/scripts/story-init.js +1 -29
  74. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +37 -18
  75. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +23 -18
  76. package/.agents/skills/core/epic-plan-premortem/SKILL.md +7 -6
  77. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +161 -109
  78. package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
  79. package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
  80. package/.agents/skills/core/scope-triage/SKILL.md +2 -1
  81. package/.agents/skills/skills.index.json +6 -6
  82. package/.agents/templates/epic-from-idea.md +4 -0
  83. package/.agents/workflows/audit-to-stories.md +2 -2
  84. package/.agents/workflows/helpers/code-review.md +11 -9
  85. package/.agents/workflows/helpers/deliver-epic.md +32 -44
  86. package/.agents/workflows/helpers/epic-audit.md +11 -8
  87. package/.agents/workflows/helpers/epic-deliver-story.md +10 -16
  88. package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
  89. package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
  90. package/.agents/workflows/helpers/parallel-tooling.md +2 -1
  91. package/.agents/workflows/helpers/plan-epic.md +114 -99
  92. package/.agents/workflows/helpers/single-story-deliver.md +1 -1
  93. package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
  94. package/.agents/workflows/plan.md +8 -8
  95. package/.agents/workflows/qa-assist.md +2 -1
  96. package/docs/CHANGELOG.md +28 -0
  97. package/package.json +1 -1
  98. package/.agents/scripts/lib/issue-link-parser.js +0 -74
  99. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
  100. package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
  101. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +0 -57
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description:
3
- Orchestrates end-to-end Epic planning (PRD, Tech Spec, Acceptance Spec, and
3
+ Orchestrates end-to-end Epic planning (Tech Spec, Acceptance Spec, and
4
4
  Work Breakdown) for a GitHub Epic.
5
5
  ---
6
6
 
@@ -22,7 +22,7 @@ phase helpers — [`helpers/epic-plan-spec.md`](epic-plan-spec.md) and
22
22
  both phases sequentially with a human confirmation gate between them. The Epic
23
23
  ID is the single positional argument.
24
24
 
25
- As of v5.6, planning artifacts (PRD, Tech Spec, ticket decomposition) are
25
+ As of v5.6, planning artifacts (Tech Spec, ticket decomposition) are
26
26
  authored **directly by you, the host LLM** — no external Gemini / Anthropic /
27
27
  OpenAI API is called. The Node scripts are deterministic GitHub I/O wrappers
28
28
  that (a) emit the authoring context you need and (b) validate and persist the
@@ -207,7 +207,7 @@ new Epic is genuinely distinct).
207
207
 
208
208
  2. **Label discipline**: The Issue is opened with **only** the
209
209
  `type::epic` label. **Do not** add any `state::*` label at creation
210
- time — the Epic carries only `type::epic` until PRD authoring
210
+ time — the Epic carries only `type::epic` until spec authoring
211
211
  advances it to `agent::review-spec` in Phase 7. The
212
212
  `openEpicFromOnePager` helper already enforces this; the workflow
213
213
  prose codifies the intent so future label-set tweaks don't silently
@@ -215,30 +215,36 @@ new Epic is genuinely distinct).
215
215
 
216
216
  3. **Continue to Phase 5**: The captured Epic ID becomes the new
217
217
  `[Epic_ID]` for the rest of the planning pipeline. Re-Plan Detection
218
- (Phase 5) will short-circuit because no PRD/Tech Spec is linked yet,
219
- so the run flows naturally into Phase 6 (Epic Clarity Gate) and then
220
- Phase 7.
218
+ (Phase 5) will short-circuit because the fresh Epic body carries no
219
+ Tech Spec sections yet, so the run flows naturally into Phase 6
220
+ (Epic Clarity Gate) and then Phase 7.
221
221
 
222
222
  ## Phase 5: Re-Plan Detection
223
223
 
224
224
  Before generating any artifacts, check whether the Epic has already been
225
225
  planned.
226
226
 
227
- 1. **Fetch Epic**: Read the Epic issue body and check for a
228
- `## Planning Artifacts` section containing PRD and Tech Spec references.
229
- 2. **If already planned**: Inform the user that this Epic already has planning
230
- artifacts. Ask:
231
-
232
- > "Epic #[ID] already has PRD (#XX) and Tech Spec (#XX) with YY decomposed
233
- > tickets. Do you want to **re-plan**? This will **overwrite the PRD,
234
- > Tech Spec, and Acceptance Spec in place** (same issue numbers, refreshed
235
- > bodies, comment history preserved) and **close-and-recreate** all
236
- > child Story tickets."
227
+ 1. **Fetch Epic**: Read the Epic issue body and check for Tech Spec
228
+ content the managed `<!-- mandrel:tech-spec:start/end -->` section or
229
+ a bare `## Delivery Slicing` heading (`hasTechSpecContent` in
230
+ [`lib/epic-body-sections.js`](../../scripts/lib/epic-body-sections.js)).
231
+ The Tech Spec sections alone are the already-planned signal. Historical
232
+ Epics may still carry a legacy `## Planning Artifacts` section linking
233
+ retired `context::*` tickets those links are **ignored** (never
234
+ fetched); only the body sections count.
235
+ 2. **If already planned**: Inform the user that this Epic already carries
236
+ planning sections. Ask:
237
+
238
+ > "Epic #[ID] already carries a Tech Spec (`## Delivery Slicing`) with
239
+ > YY decomposed tickets. Do you want to **re-plan**? This will
240
+ > **overwrite the Tech Spec and Acceptance Table sections of the Epic
241
+ > body in place** (comment history preserved) and **close-and-recreate**
242
+ > all child Story tickets."
237
243
 
238
244
  3. **If user confirms re-plan**: Pass `--force` to all subsequent script
239
- invocations. Under `--force`, the three context tickets (PRD, Tech Spec,
240
- Acceptance Spec) are overwritten in place — their issue numbers, Epic
241
- sub-issue links, and prior discussion are preserved, and each receives a
245
+ invocations. Under `--force`, the Epic body's managed sections (Tech
246
+ Spec, Acceptance Table) are overwritten in place — the Epic's issue
247
+ number and prior discussion are preserved, and the Epic receives a
242
248
  one-line regeneration audit comment. Child Story tickets are still
243
249
  closed and recreated, because a re-decomposition can legitimately produce a
244
250
  different ticket set.
@@ -257,16 +263,16 @@ clarity gate does not make.
257
263
 
258
264
  The advisory runs **only** when **both** hold:
259
265
 
260
- 1. **Phase 5 found no planning artifacts** — the Epic body has no
261
- `## Planning Artifacts` section linking a PRD / Tech Spec (i.e. Phase 5
262
- did **not** enter its re-plan branch).
266
+ 1. **Phase 5 found no planning sections** — the Epic body carries no Tech
267
+ Spec content (no managed section, no `## Delivery Slicing` heading
268
+ i.e. Phase 5 did **not** enter its re-plan branch).
263
269
  2. **The Epic has no open Story children** — no open `type::story`
264
270
  sub-issues are linked to this Epic.
265
271
 
266
272
  If **either** condition fails, **skip this phase silently** and continue to
267
273
  Phase 6. It must **never** fire on the re-plan path: recommending a "downgrade
268
- to a Story" on an Epic that already carries a PRD and a ticket tree is
269
- nonsense and would collide with the `--force` re-plan flow. The advisory also
274
+ to a Story" on an Epic that already carries folded Tech Spec sections and a
275
+ ticket tree is nonsense and would collide with the `--force` re-plan flow. The advisory also
270
276
  does not fire on the ideation path — that path already ran the Phase 1.5 scope
271
277
  triage on the one-pager before the Epic existed.
272
278
 
@@ -352,11 +358,13 @@ via [`/single-story-deliver`](single-story-deliver.md) or
352
358
 
353
359
  Runs on every existing-Epic invocation, after Phase 5 (Re-Plan
354
360
  Detection) and the Phase 5.5 story-sized advisory, and before Phase 7
355
- (PRD, Tech Spec & Acceptance Spec). The gate scores the Epic body
356
- against the five canonical
361
+ (Tech Spec & Acceptance Spec). The gate scores the Epic body
362
+ against the five clarity-scored canonical
357
363
  sections from
358
364
  [`.agents/templates/epic-from-idea.md`](../../templates/epic-from-idea.md)
359
- (Context, Goal, Non-Goals, Scope, Acceptance Criteria) and either
365
+ (Context, Goal, Non-Goals, Scope, Acceptance Criteria the template
366
+ also carries a `## User Stories` section, which the clarity rubric does
367
+ not score) and either
360
368
  skips fast (when the Epic body is already clear) or drops into a
361
369
  refinement loop seeded from the current Epic body. The scorer also
362
370
  accepts common heading variants for back-compat (e.g. `## Problem`,
@@ -406,8 +414,8 @@ for the scoring logic.
406
414
  5. **HITL stop — confirm the diff**: Display the diff between the
407
415
  current Epic body and the sharpened body and **STOP**. Operator
408
416
  approves, edits, or aborts. Flag the blast radius in the
409
- confirmation prompt: an approved body change feeds **three**
410
- downstream artifacts (PRD, Tech Spec, Acceptance Spec) — treat
417
+ confirmation prompt: an approved body change feeds **two**
418
+ downstream artifacts (Tech Spec, Acceptance Spec) — treat
411
419
  this gate as a one-shot rewrite, not an iterative draft. The
412
420
  Constraint ("Do not modify existing issues without explicit
413
421
  permission") is honored — no `gh issue edit` call until the
@@ -443,7 +451,7 @@ for the scoring logic.
443
451
  remediation hint to the operator. Do not loop — one refinement
444
452
  pass per invocation, matching the `--force` re-plan pattern.
445
453
 
446
- ## Phase 7: Epic Planning (PRD, Tech Spec & Acceptance Spec)
454
+ ## Phase 7: Epic Planning (Tech Spec & Acceptance Spec)
447
455
 
448
456
  > **Epic-lease preflight (workflow guard).** Before any Phase 7 mutation,
449
457
  > `epic-plan-spec.js` acquires the Epic-lease via the assignee-as-lease
@@ -464,28 +472,36 @@ for the scoring logic.
464
472
 
465
473
  <!-- separator: adjacent blockquotes -->
466
474
 
467
- > **Idempotent context tickets.** The persist half is find-or-create keyed on
468
- > the Epic's `linkedIssues`: a re-run **reuses the already-linked PRD and Tech
469
- > Spec issues** (and Acceptance Spec, when present) instead of creating
470
- > duplicates. Pass `--force` to overwrite the canonical context tickets in
471
- > place (same issue numbers, refreshed bodies).
475
+ > **Idempotent managed sections.** The persist half is section-scoped and
476
+ > keyed on the Epic body: a re-run that finds the requested sections already
477
+ > present (`<!-- mandrel:tech-spec:start/end -->` /
478
+ > `<!-- mandrel:acceptance-table:start/end -->`) short-circuits as
479
+ > `already-planned` instead of duplicating content. Pass `--force` to
480
+ > overwrite the managed sections in place (same Epic issue, refreshed
481
+ > section bodies).
472
482
 
473
483
  <!-- separator: adjacent blockquotes -->
474
484
 
475
- > **Three context tickets, not two.** Every Epic carries three planning
476
- > artifacts as linked GitHub sub-issues: PRD (`context::prd`), Tech Spec
477
- > (`context::tech-spec`), and Acceptance Spec
478
- > (`context::acceptance-spec`). The Acceptance Spec captures the
479
- > stable-ID acceptance criteria table (`| AC ID | Outcome | Feature
480
- > File | Scenario | Disposition |`) that drives close-time
481
- > reconciliation during `/deliver` Phase 6. Operators may opt out
482
- > for refactor-only or docs-only Epics by applying the
483
- > `acceptance::n-a` label to the Epic ticket when present, the
484
- > `epic-plan-spec-author` skill skips the Acceptance Spec output and
485
- > the runtime gates (start gate, finalize reconciler) honour the
486
- > waiver the spec ticket itself need not be authored or approved when
487
- > the waiver is set. See [SDLC § Acceptance Spec — the third planning
488
- > context ticket](../../docs/SDLC.md#acceptance-spec--the-third-planning-context-ticket)
485
+ > **One planning document.** A `/plan` Epic run creates exactly **one**
486
+ > issue the Epic. The planning artifacts land as marker-delimited
487
+ > managed sections of the Epic body: the Tech Spec (opening with
488
+ > `## Delivery Slicing`) inside `<!-- mandrel:tech-spec:start/end -->`,
489
+ > and the Acceptance Spec's AC-ID table (headed `## Acceptance Table`)
490
+ > inside `<!-- mandrel:acceptance-table:start/end -->`. The PRD artifact
491
+ > class was retired (Story #4314) its one novel section, **User
492
+ > Stories**, lives inline in the Epic body as a `## User Stories`
493
+ > section and Story #4324 retired the `context::tech-spec` /
494
+ > `context::acceptance-spec` ticket classes the same way. The
495
+ > `## Acceptance Table` section captures the stable-ID acceptance
496
+ > criteria table (`| AC ID | Outcome | Feature File | Scenario |
497
+ > Disposition |`) that drives close-time reconciliation during
498
+ > `/deliver` Phase 6. Operators may opt out for refactor-only or
499
+ > docs-only Epics by applying the `acceptance::n-a` label to the Epic
500
+ > ticket — when present, the `epic-plan-spec-author` skill skips the
501
+ > Acceptance Table output and the runtime gates (start gate, finalize
502
+ > reconciler) honour the waiver — the section need not be authored when
503
+ > the waiver is set. See [SDLC § Acceptance Table — the second folded
504
+ > planning section](../../docs/SDLC.md#acceptance-table--the-second-folded-planning-section)
489
505
  > for the full lifecycle.
490
506
 
491
507
  <!-- separator: adjacent blockquotes -->
@@ -495,11 +511,11 @@ for the scoring logic.
495
511
  > workflow lives under the per-Epic tree
496
512
  > (`temp/epic-[Epic_ID]/<artifact>`) — e.g.
497
513
  > `temp/epic-[Epic_ID]/planner-context.json`,
498
- > `temp/epic-[Epic_ID]/prd.md`, `temp/epic-[Epic_ID]/techspec.md`,
514
+ > `temp/epic-[Epic_ID]/techspec.md`,
499
515
  > `temp/epic-[Epic_ID]/decomposer-context.json`,
500
516
  > `temp/epic-[Epic_ID]/tickets.json`. The directory namespace is the
501
517
  > isolation boundary; basenames inside it are stable. Do **not** reuse
502
- > bare flat names like `temp/prd.md` or the legacy
518
+ > bare flat names like `temp/techspec.md` or the legacy
503
519
  > `temp/<artifact>-epic-<id>.<ext>` shape — both have been retired.
504
520
  >
505
521
  > **Durability.** The per-Epic tree is durable across runs: only the
@@ -523,18 +539,18 @@ for the scoring logic.
523
539
  via the `Read` tool (resolve `<agentRoot>` from
524
540
  `project.paths.agentRoot` — default `.agents`) and execute its
525
541
  procedure with `[Epic_ID]` as input. The skill reads
526
- `temp/epic-[Epic_ID]/planner-context.json`, authors the PRD, Tech
542
+ `temp/epic-[Epic_ID]/planner-context.json`, authors the Tech
527
543
  Spec, **risk verdict**, and **Acceptance Spec** against the embedded
528
- system prompts, and writes them to `temp/epic-[Epic_ID]/prd.md`,
544
+ system prompts, and writes them to
529
545
  `temp/epic-[Epic_ID]/techspec.md`,
530
546
  `temp/epic-[Epic_ID]/risk-verdict.json`, and
531
547
  `temp/epic-[Epic_ID]/acceptance-spec.md`. The skill is the
532
- authoritative authoring step — do **not** inline the PRD / Tech
548
+ authoritative authoring step — do **not** inline the Tech
533
549
  Spec / risk-verdict / Acceptance Spec drafting in the workflow
534
550
  body. The skill front-matter declares
535
551
  `allowed_tools: [Read, Write, Bash]`; it never calls GitHub.
536
552
 
537
- The skill body carries the authoritative PRD, Tech Spec, and
553
+ The skill body carries the authoritative Tech Spec and
538
554
  Acceptance Spec system prompts. The `systemPrompts` field on the
539
555
  `--emit-context` envelope is a backstop for legacy callers; the
540
556
  skill body wins when the two surfaces diverge.
@@ -546,59 +562,55 @@ for the scoring logic.
546
562
  (`deriveRiskEnvelope`), records a `risk-verdict` structured comment
547
563
  on the Epic, flips the Epic to `agent::review-spec`, and writes the
548
564
  `epic-plan-state` checkpoint (including the `riskVerdict` field).
549
- The `--acceptance-spec` flag persists the third planning ticket
550
- (`context::acceptance-spec`) alongside the PRD and Tech Spec; the
551
- persist half fails loudly if any file is missing or empty. Omit
552
- `--acceptance-spec` only when the Epic carries the `acceptance::n-a`
553
- waiver label.
565
+ The `--acceptance-table` flag persists the AC-ID table as the Epic
566
+ body's `## Acceptance Table` managed section alongside the Tech Spec
567
+ sections; the persist half fails loudly if any file is missing or
568
+ empty. Omit `--acceptance-table` only when the Epic carries the
569
+ `acceptance::n-a` waiver label.
554
570
 
555
571
  ```bash
556
- # Normal planning (three context tickets)
572
+ # Normal planning (both managed sections)
557
573
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
558
- --prd temp/epic-[Epic_ID]/prd.md \
559
- --techspec temp/epic-[Epic_ID]/techspec.md \
574
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
560
575
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
561
- --acceptance-spec temp/epic-[Epic_ID]/acceptance-spec.md
576
+ --acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md
562
577
 
563
- # Re-planning (--force overwrites the three context tickets IN PLACE —
564
- # same PRD / Tech Spec / Acceptance Spec issue numbers, refreshed bodies,
565
- # tickets kept open, one regeneration audit comment each. Child Story
566
- # tickets are still close-and-recreate at decomposition time.)
578
+ # Re-planning (--force overwrites the Epic body's managed sections
579
+ # IN PLACE same Epic issue, refreshed section bodies, one
580
+ # regeneration audit comment on the Epic. Child Story tickets are
581
+ # still close-and-recreate at decomposition time.)
567
582
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
568
- --prd temp/epic-[Epic_ID]/prd.md \
569
- --techspec temp/epic-[Epic_ID]/techspec.md \
583
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
570
584
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json \
571
- --acceptance-spec temp/epic-[Epic_ID]/acceptance-spec.md --force
585
+ --acceptance-table temp/epic-[Epic_ID]/acceptance-spec.md --force
572
586
 
573
- # Waived (acceptance::n-a label on Epic — no spec authored)
587
+ # Waived (acceptance::n-a label on Epic — no acceptance table authored)
574
588
  node .agents/scripts/epic-plan-spec.js --epic [Epic_ID] \
575
- --prd temp/epic-[Epic_ID]/prd.md \
576
- --techspec temp/epic-[Epic_ID]/techspec.md \
589
+ --tech-spec temp/epic-[Epic_ID]/techspec.md \
577
590
  --risk-verdict temp/epic-[Epic_ID]/risk-verdict.json
578
591
  ```
579
592
 
580
593
  4. **Verification and review routing**:
581
- - Verify that the PRD, Technical Specification, and (when not waived)
582
- Acceptance Specification have been posted as linked issues under
583
- the Epic.
594
+ - Verify that the Technical Specification sections and (when not
595
+ waived) the `## Acceptance Table` section have landed as managed
596
+ sections of the Epic body.
584
597
  - Read `planningRisk` from the persist stdout JSON (or the
585
598
  `epic-plan-state` checkpoint). Branch on
586
599
  `planningRisk.requiresReview` unless the operator passed
587
600
  `--force-review`:
588
601
  - **High risk** (`requiresReview === true`) or **operator override**
589
602
  (`--force-review`) — **gate #2**: **STOP**. Ask the USER to review the
590
- generated PRD, Tech Spec, and Acceptance Spec on GitHub. Approval is
591
- the user's verbal OK in this session — the three context tickets stay
592
- **open** through delivery and are closed automatically by
593
- `/deliver` when the Epic PR opens. Do NOT proceed
603
+ updated Epic body (its Tech Spec sections and `## Acceptance
604
+ Table`) on GitHub. Approval is the user's verbal OK in this
605
+ session the sections live on the Epic itself, so there is
606
+ nothing to close at delivery time. Do NOT proceed
594
607
  to decomposition until the user confirms the plan is accurate.
595
608
 
596
609
  > **`--yes` (headless) auto-proceed.** When `/plan` was invoked with
597
610
  > `--yes`, this review gate does **not** STOP, even when
598
611
  > `requiresReview === true` or `--force-review` was also passed: the
599
612
  > review resolves as **approved** and the run **continues directly to
600
- > Phase 8**, exactly as the low-risk auto-proceed branch below. The
601
- > three context tickets stay **open** through delivery as usual; only
613
+ > Phase 8**, exactly as the low-risk auto-proceed branch below; only
602
614
  > the operator *wait* is suppressed. This is `/plan`'s **gate #2** —
603
615
  > the second and last HITL STOP `--yes` suppresses. `--yes` does
604
616
  > **not** alter risk routing or the review criteria themselves; it
@@ -612,8 +624,8 @@ for the scoring logic.
612
624
  decision is recorded in the `epic-plan-state` checkpoint. (`--yes` is
613
625
  a no-op on this branch — there is no STOP to suppress.)
614
626
 
615
- 5. **Tech Spec freshness check (advisory)**: After the Tech Spec issue
616
- is created, `epic-plan-spec.js` runs
627
+ 5. **Tech Spec freshness check (advisory)**: After the Tech Spec sections
628
+ are persisted, `epic-plan-spec.js` runs
617
629
  [`validateSpecFreshness`](../../scripts/lib/orchestration/spec-freshness.js)
618
630
  against the authored Tech Spec body, probing every cited path-shape
619
631
  reference (backticked paths, `// header` lines in code blocks, and
@@ -628,14 +640,14 @@ for the scoring logic.
628
640
  reference the Architect inherited from drift-stale docs.
629
641
 
630
642
  When ≥1 stale reference is detected, a `spec-freshness` structured
631
- comment is upserted on the Tech Spec issue listing each citation
643
+ comment is upserted on the **Epic** listing each citation
632
644
  with its line number. The full report is also written to
633
645
  `<tempRoot>/epic-<id>-spec-freshness.json` for downstream tooling.
634
646
  The check is **advisory and non-blocking** — Phase 7 completes even
635
647
  when stale references are present, so the operator retains final
636
648
  judgment on edge cases. If the run summary shows
637
- `⚠️ Spec freshness: N stale / M ambiguous`, review the Tech Spec
638
- issue's `spec-freshness` comment and correct the cited spec body
649
+ `⚠️ Spec freshness: N stale / M ambiguous`, review the Epic's
650
+ `spec-freshness` comment and correct the cited spec sections
639
651
  before approving the plan for Phase 8.
640
652
 
641
653
  6. **BDD scenario cross-reference (advisory)**: When the project has
@@ -716,8 +728,8 @@ node .agents/scripts/epic-plan-spec-validate.js \
716
728
 
717
729
  **STOP** on a non-zero exit: do not advance to Phase 8. Re-author the Tech
718
730
  Spec (re-run the Phase 7 spec-author step) or add a `## Delivery Slicing`
719
- section to the Tech Spec issue body by hand, then re-run the gate until it
720
- exits 0.
731
+ section by hand (to the temp spec file and the Epic body's tech-spec
732
+ section), then re-run the gate until it exits 0.
721
733
 
722
734
  ## Phase 8: Work Breakdown Decomposition
723
735
 
@@ -735,7 +747,7 @@ node .agents/scripts/epic-plan-spec-validate.js \
735
747
  > **Hierarchy.** The decomposer emits a flat Story backlog under the Epic.
736
748
  > Acceptance criteria and verification steps are inlined on each Story
737
749
  > body (`acceptance[]` / `verify[]` fields) and resolved against the
738
- > Acceptance Spec context ticket at close time. See
750
+ > Epic body's `## Acceptance Table` section at close time. See
739
751
  > [`.agents/instructions.md` § 5.D](../../instructions.md) for the full
740
752
  > contract.
741
753
 
@@ -750,8 +762,9 @@ node .agents/scripts/epic-plan-spec-validate.js \
750
762
  via the `Read` tool (resolve `<agentRoot>` from
751
763
  `project.paths.agentRoot` — default `.agents`) and execute its
752
764
  procedure with `[Epic_ID]` as input. The skill reads
753
- `temp/epic-[Epic_ID]/decomposer-context.json` (PRD body, Tech Spec
754
- body, risk heuristics, `maxTickets` cap, `contextMode`), applies its
765
+ `temp/epic-[Epic_ID]/decomposer-context.json` (`epicBody` carrying
766
+ the folded Tech Spec sections and Acceptance Table — risk
767
+ heuristics, `maxTickets` cap, `contextMode`), applies its
755
768
  embedded decomposer system prompt + ticket schema, and writes the
756
769
  ticket array to `temp/epic-[Epic_ID]/tickets.json`. Do **not** inline
757
770
  the JSON authoring in the workflow body.
@@ -781,8 +794,9 @@ node .agents/scripts/epic-plan-spec-validate.js \
781
794
  [`epic-plan-consolidate`](../../skills/core/epic-plan-consolidate/SKILL.md)
782
795
  skill with `[Epic_ID]` as input. This is a **separate critic pass with
783
796
  fresh context** (not a self-review appended to the author skill): it reads
784
- the draft array plus the PRD / Tech Spec, reconciles the draft against the
785
- Tech Spec `## Delivery Slicing` target, and emits a **consolidated**
797
+ the draft array plus the Epic body (which carries the Tech Spec
798
+ sections), reconciles the draft against
799
+ the Tech Spec `## Delivery Slicing` target, and emits a **consolidated**
786
800
  `tickets.json` plus a human-readable
787
801
  `temp/epic-[Epic_ID]/consolidation-report.md`. Its operations are
788
802
  scope-preserving only — **merge sibling Stories and rewire
@@ -838,8 +852,9 @@ node .agents/scripts/epic-plan-spec-validate.js \
838
852
  reachability critic (8.4) and **before** the persist call below, activate the
839
853
  [`epic-plan-premortem`](../../skills/core/epic-plan-premortem/SKILL.md)
840
854
  skill with `[Epic_ID]` as input. This is a **fresh-context critic** sibling
841
- to `epic-plan-consolidate`: it reads the drafted `tickets.json`, the PRD /
842
- Tech Spec, **and the actual cited code surfaces** (the files each Story's
855
+ to `epic-plan-consolidate`: it reads the drafted `tickets.json`, the Epic
856
+ body (with its folded Tech Spec sections), **and the actual cited code
857
+ surfaces** (the files each Story's
843
858
  `changes[]` / `references[]` name), then emits predicted-rework findings —
844
859
  unverifiable acceptance criteria, over- or under-specified Stories, and
845
860
  semantically-wrong assumptions the structural file-assumption gate (step 7)
@@ -1032,8 +1047,8 @@ forcing the walkthrough.
1032
1047
 
1033
1048
  Activate the
1034
1049
  [`core/knowledge-transfer`](../../skills/core/knowledge-transfer/SKILL.md) skill
1035
- with the **plan** as the subject — the Epic body, the linked PRD / Tech Spec
1036
- context tickets, the decomposition (Stories with inline
1050
+ with the **plan** as the subject — the Epic body (whose managed sections
1051
+ carry the Tech Spec), the decomposition (Stories with inline
1037
1052
  `acceptance[]` / `verify[]`), and the Phase 9 wave roadmap. The skill owns the
1038
1053
  method (restate-first, the why-ladder, mastery gates, depth levels, optional
1039
1054
  quizzing, the persistent `temp/comprehension-*.md` checklist).
@@ -13,7 +13,7 @@ description:
13
13
  [`/deliver`](deliver-stories.md). Use it for a Story that is **not**
14
14
  attached to an Epic — refactors carved out of closed Epics, framework
15
15
  maintenance, or any work small enough that the Epic-Centric ceremony
16
- (PRD + Tech Spec + decomposition + dispatch manifest + cascade) would be
16
+ (sectioned Epic body + decomposition + dispatch manifest + cascade) would be
17
17
  overhead rather than help.
18
18
 
19
19
  ```text
@@ -353,7 +353,7 @@ Human reviewers should **keep using the main checkout** — not a worktree:
353
353
  the main checkout, not in any per-story worktree.
354
354
  - Opening a worktree in an IDE can mislead: the working directory looks like the
355
355
  main repo but carries a different HEAD. The main checkout is the canonical
356
- place to read PRDs, Tech Specs, and run the `helpers/code-review.md`
356
+ place to read Epic planning bodies and run the `helpers/code-review.md`
357
357
  procedure.
358
358
  - `git worktree list --porcelain` on the main checkout enumerates any still
359
359
  in-flight story worktrees if you need to inspect one — prefer read-only
@@ -2,8 +2,8 @@
2
2
  description:
3
3
  Unified planning entry point. Routes a seed idea (via scope triage) or an
4
4
  existing Epic ID to the right planning path — the full Epic pipeline
5
- (PRD, Tech Spec, Acceptance Spec, decomposition) or the standalone-Story
6
- authoring path — and absorbs every planning flag.
5
+ (sectioned Epic body: Tech Spec + Acceptance Table, then decomposition)
6
+ or the standalone-Story authoring path — and absorbs every planning flag.
7
7
  ---
8
8
 
9
9
  # /plan [Epic ID] | --idea "<seed>" | --from-notes <path>
@@ -14,8 +14,8 @@ Router. `/plan` owns argument parsing and path selection only — all phase
14
14
  content lives in the two path helpers:
15
15
 
16
16
  - [`helpers/plan-epic.md`](helpers/plan-epic.md) — the full Epic planning
17
- pipeline (PRD, Tech Spec, Acceptance Spec, work breakdown, healthcheck,
18
- handoff).
17
+ pipeline (Tech Spec + Acceptance Table folded into the Epic body, work
18
+ breakdown, healthcheck, handoff).
19
19
  - [`helpers/plan-story.md`](helpers/plan-story.md) — the standalone-Story
20
20
  authoring path (context envelope → host-LLM draft → HITL → issue create).
21
21
 
@@ -93,10 +93,10 @@ without waiting for operator input:
93
93
  forces a review (`planningRisk.requiresReview === true`, or the operator
94
94
  also passed `--force-review`),
95
95
  [`helpers/plan-epic.md`](helpers/plan-epic.md) Phase 7 STOPs for operator
96
- approval of the PRD / Tech Spec / Acceptance Spec before decomposition.
97
- Under `--yes` this review auto-proceeds straight to Phase 8 — the three
98
- context tickets stay **open** through delivery exactly as on the low-risk
99
- auto-proceed path.
96
+ approval of the updated Epic body (its Tech Spec sections and
97
+ `## Acceptance Table`) before decomposition.
98
+ Under `--yes` this review auto-proceeds straight to Phase 8 exactly as
99
+ on the low-risk auto-proceed path.
100
100
 
101
101
  **Composition.** `--yes` is orthogonal to the other planning flags and
102
102
  composes cleanly:
@@ -226,7 +226,8 @@ every decision to the shared core helpers; never re-derive them in prose.
226
226
 
227
227
  3. **Hydrate the QA context** to locate code precisely, via
228
228
  [`qa-context-hydrator.js`](../scripts/lib/qa/qa-context-hydrator.js) — it
229
- resolves the Epic/Feature context tickets, the feature-file set, the surface
229
+ resolves the Epic (whose body carries the planning sections), the
230
+ feature-file set, the surface
230
231
  map, and recent git log:
231
232
 
232
233
  ```js
package/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.82.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.81.0...mandrel-v1.82.0) (2026-07-04)
6
+
7
+
8
+ ### Added
9
+
10
+ * **decomposer:** add soft envelope-floor guidance to sizing prompt (refs [#4313](https://github.com/dsj1984/mandrel/issues/4313)) ([#4321](https://github.com/dsj1984/mandrel/issues/4321)) ([e95c9e4](https://github.com/dsj1984/mandrel/commit/e95c9e4b39b7549f2f83ee104e19a9824f9bab00))
11
+ * **epic-plan-spec:** key Acceptance Spec Outcomes to Epic AC bullets (refs [#4315](https://github.com/dsj1984/mandrel/issues/4315)) ([#4323](https://github.com/dsj1984/mandrel/issues/4323)) ([4d4103c](https://github.com/dsj1984/mandrel/commit/4d4103c79500e5704b1fa79e70f6efb985e06994))
12
+ * **plan:** recalibrate Delivery Slicing to a ceiling, not a target (refs [#4311](https://github.com/dsj1984/mandrel/issues/4311)) ([#4317](https://github.com/dsj1984/mandrel/issues/4317)) ([b37596b](https://github.com/dsj1984/mandrel/commit/b37596b8f739da52f568cb025b84ada84ce90355))
13
+ * **ticket-validator-sizing:** add merge-candidate under-size soft finding (refs [#4312](https://github.com/dsj1984/mandrel/issues/4312)) ([#4319](https://github.com/dsj1984/mandrel/issues/4319)) ([2b84e49](https://github.com/dsj1984/mandrel/commit/2b84e49022f9745549cb02a1237d24ab194af92c))
14
+
15
+
16
+ ### Fixed
17
+
18
+ * retire the context-ticket classes: fold Tech Spec and Acceptance Spec into the sectioned Epic body ([#4324](https://github.com/dsj1984/mandrel/issues/4324)) ([#4325](https://github.com/dsj1984/mandrel/issues/4325)) ([f8cfec7](https://github.com/dsj1984/mandrel/commit/f8cfec79f1aa59fc86c51e9ced6dda2bd06f2cb3))
19
+
20
+
21
+ ### Changed
22
+
23
+ * **epic-plan-spec:** open Tech Spec with Delivery Slicing, drop Epic-context restatement (refs [#4316](https://github.com/dsj1984/mandrel/issues/4316)) ([#4320](https://github.com/dsj1984/mandrel/issues/4320)) ([b20d10a](https://github.com/dsj1984/mandrel/commit/b20d10a2e61b1940ebffe0bc595d3b6bfedec604))
24
+ * fold the PRD into the Epic body and retire the context::prd artifact class ([#4314](https://github.com/dsj1984/mandrel/issues/4314)) ([#4322](https://github.com/dsj1984/mandrel/issues/4322)) ([9c9bc7d](https://github.com/dsj1984/mandrel/commit/9c9bc7deb19ce04de1aebcaefb2eeebf949f61d5))
25
+
26
+ ## [1.81.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.80.0...mandrel-v1.81.0) (2026-07-01)
27
+
28
+
29
+ ### Fixed
30
+
31
+ * **baselines:** add one-shot BUNDLE_SIZE_REFRESH acknowledge for the bundle-size ratchet ([#4309](https://github.com/dsj1984/mandrel/issues/4309)) ([bc466b9](https://github.com/dsj1984/mandrel/commit/bc466b98f6c7521c3a24bbb4d93ee5169c163839))
32
+
5
33
  ## [1.80.0](https://github.com/dsj1984/mandrel/compare/mandrel-v1.79.0...mandrel-v1.80.0) (2026-07-01)
6
34
 
7
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandrel",
3
- "version": "1.80.0",
3
+ "version": "1.82.0",
4
4
  "description": "Claude Code-first opinionated workflow framework: instructions, personas, skills, and SDLC workflows that govern AI coding assistants.",
5
5
  "files": [
6
6
  ".agents/",
@@ -1,74 +0,0 @@
1
- /**
2
- * Parse PRD / Tech-Spec / Acceptance-Spec references from a GitHub epic body.
3
- * Extracted from providers/github.js so link-parsing is not mixed with HTTP
4
- * transport.
5
- *
6
- * Expected markdown conventions in an epic body (case-insensitive, tolerant
7
- * of the `- [ ]` / `- [x]` checkbox prefix that `epic-plan-spec.js` emits in
8
- * the `## Planning Artifacts` section):
9
- * - "PRD: #42" or "prd #42"
10
- * - "Tech Spec: #43" / "Technical Spec: #43" / "tech-spec: #43"
11
- * - "Acceptance Spec: #44" / "acceptance-spec: #44" / "accept spec: #44"
12
- *
13
- * Story #2091 added the `acceptanceSpec` slot so the
14
- * `closePlanningArtifacts()` cascade in `epic-deliver-finalize.js` can close
15
- * the `context::acceptance-spec` ticket Epic #2001 introduces alongside the
16
- * existing PRD / Tech-Spec pair.
17
- *
18
- * Story #3848: regexes are now scoped to the `## Planning Artifacts` section
19
- * only. Prose elsewhere in the body (e.g. bundled-follow-up notes that
20
- * mention a foreign Epic's spec ticket by number) can no longer collide with
21
- * the machine-managed list items.
22
- */
23
-
24
- const PRD_RE = /(?:PRD|prd)[:\s]+#(\d+)/;
25
- const TECH_SPEC_RE = /(?:Tech Spec|tech.?spec|technical.?spec)[:\s]+#(\d+)/i;
26
- const ACCEPTANCE_SPEC_RE =
27
- /(?:Acceptance Spec|acceptance.?spec|accept.?spec)[:\s]+#(\d+)/i;
28
-
29
- /**
30
- * Extract the `## Planning Artifacts` section text from an Epic body.
31
- * Returns the slice from just after the heading line to the next `##`-level
32
- * heading (exclusive), or to end-of-string when no following heading is
33
- * present. Returns an empty string when the section is absent.
34
- *
35
- * @param {string} body
36
- * @returns {string}
37
- */
38
- function extractPlanningArtifactsSection(body) {
39
- // Step 1: locate the heading.
40
- const startMatch = body.match(/^##\s+Planning Artifacts[^\n]*/m);
41
- if (!startMatch) return '';
42
- // Step 2: slice from just after the heading to the next ## heading (or EOB).
43
- const afterHeading = body.slice(startMatch.index + startMatch[0].length);
44
- const nextHeadingMatch = afterHeading.match(/\n##\s/);
45
- return nextHeadingMatch
46
- ? afterHeading.slice(0, nextHeadingMatch.index)
47
- : afterHeading;
48
- }
49
-
50
- /**
51
- * @param {string|null|undefined} body
52
- * @returns {{ prd: number|null, techSpec: number|null, acceptanceSpec: number|null }}
53
- */
54
- export function parseLinkedIssues(body) {
55
- const result = { prd: null, techSpec: null, acceptanceSpec: null };
56
- if (typeof body !== 'string' || body.length === 0) return result;
57
-
58
- // Scope all regex matching to the canonical Planning Artifacts section so
59
- // prose references elsewhere in the body do not shadow the machine-managed
60
- // list items. When the section is absent every slot stays null — the caller
61
- // (plan-epic.js) treats null as "not yet linked" and creates fresh tickets.
62
- const section = extractPlanningArtifactsSection(body);
63
- if (section.length === 0) return result;
64
-
65
- const prdMatch = section.match(PRD_RE);
66
- if (prdMatch) result.prd = Number.parseInt(prdMatch[1], 10);
67
- const specMatch = section.match(TECH_SPEC_RE);
68
- if (specMatch) result.techSpec = Number.parseInt(specMatch[1], 10);
69
- const acceptanceMatch = section.match(ACCEPTANCE_SPEC_RE);
70
- if (acceptanceMatch) {
71
- result.acceptanceSpec = Number.parseInt(acceptanceMatch[1], 10);
72
- }
73
- return result;
74
- }