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
package/.agents/README.md CHANGED
@@ -361,8 +361,8 @@ rule:
361
361
  > GitHub I/O, label transitions, JSON validators, NDJSON readers,
362
362
  > diff-vs-baseline gates, template renderers.
363
363
  >
364
- > **Prompt + judgment → make it a Skill.** Examples: composing a PRD
365
- > from an Epic body, classifying friction signals from a failed shell
364
+ > **Prompt + judgment → make it a Skill.** Examples: composing a Tech
365
+ > Spec from an Epic body, classifying friction signals from a failed shell
366
366
  > command, decomposing a Tech Spec into a ticket hierarchy.
367
367
 
368
368
  The rule is two-sided on purpose. "Has an LLM step adjacent" is *not*
@@ -377,9 +377,9 @@ judgment (Skill) or of a parseable transform (script).
377
377
  **split**: the deterministic halves stay as a script, the judgment middle
378
378
  moves to a Skill.
379
379
 
380
- - **`--emit-context`** (script half) — fetches the PRD and Tech Spec
381
- bodies, scrapes project docs, emits a JSON envelope. Parseable in,
382
- parseable out. Stays a script.
380
+ - **`--emit-context`** (script half) — fetches the Epic body (which
381
+ carries the folded Tech Spec sections), scrapes project docs, emits a
382
+ JSON envelope. Parseable in, parseable out. Stays a script.
383
383
  - **Authoring middle** (Skill half) — given the envelope, author the
384
384
  ticket hierarchy JSON. Pure prompt + judgment. Migrates to a Skill
385
385
  under `.agents/skills/core/` so it ships with declarative
@@ -19,9 +19,11 @@ ADR 20260512-coupling-stance in [`../docs/decisions.md`](../../docs/decisions.md
19
19
  From zero to shipped:
20
20
 
21
21
  1. **Plan the work.** Run `/plan` in your agentic IDE. The framework
22
- generates a PRD, a Tech Spec, and an Acceptance Spec, decomposes the
23
- work into the flat Story backlog under the Epic, and
24
- transitions the Epic to `agent::ready`.
22
+ authors a Tech Spec and an Acceptance Table and folds both into the
23
+ Epic body as managed sections (the Epic is the single planning
24
+ document the PRD and context-ticket artifact classes were
25
+ retired), decomposes the work into the flat Story backlog under the
26
+ Epic, and transitions the Epic to `agent::ready`.
25
27
 
26
28
  The entry point you use selects where the run begins:
27
29
  - With **no arguments** (or `--idea "<seed>"`), the workflow enters at
@@ -50,19 +52,22 @@ From zero to shipped:
50
52
  4. **Phase 4 — open the Epic Issue** *(ideation entry only)* — opens
51
53
  the GitHub Issue with **only** the `type::epic` label; the captured
52
54
  id flows into the rest of the pipeline.
53
- 5. **Phase 5 — re-plan detection** — checks whether the Epic already
54
- carries planning artifacts and, if so, prompts before overwriting
55
- the PRD / Tech Spec / Acceptance Spec in place and recreating the
56
- child Story tickets.
55
+ 5. **Phase 5 — re-plan detection** — checks whether the Epic body
56
+ already carries the folded Tech Spec sections (keyed on the
57
+ `## Delivery Slicing` managed section Story #4324) and, if so,
58
+ prompts before overwriting the Tech Spec / Acceptance Table
59
+ sections in place and recreating the child Story tickets. Legacy
60
+ context tickets on historical Epics are ignored (never fetched).
57
61
  6. **Phase 6 — Epic clarity gate** — scores the Epic body against the
58
62
  five canonical sections. A `clear` verdict requires ≥ 4 of 5
59
63
  sections present **and** the Acceptance Criteria section present (AC
60
64
  is required, not optional). A `clear` verdict proceeds silently;
61
65
  `needs-refinement` drops into a one-shot refinement loop with a HITL
62
66
  diff before persisting the sharpened body.
63
- 7. **Phase 7 — PRD, Tech Spec & Acceptance Spec** — the
64
- `epic-plan-spec-author` skill authors all three planning artifacts
65
- as linked context tickets, flips the Epic to `agent::review-spec`,
67
+ 7. **Phase 7 — Tech Spec & Acceptance Spec** — the
68
+ `epic-plan-spec-author` skill authors both planning artifacts;
69
+ the persist half folds them into the Epic body's managed
70
+ sections, flips the Epic to `agent::review-spec`,
66
71
  and routes high-risk Epics to a HITL review stop (low-risk Epics
67
72
  auto-proceed).
68
73
  8. **Phase 8 — work-breakdown decomposition** — the
@@ -240,7 +245,7 @@ graph LR
240
245
 
241
246
  subgraph Phase2 ["Phase 2: Planning"]
242
247
  direction TB
243
- C["🤖 PRD + Tech Spec authoring"]:::agentic
248
+ C["🤖 Tech Spec authoring"]:::agentic
244
249
  D["🤖 Ticket Decomposer"]:::agentic
245
250
  C --> D
246
251
  D -.-> D_Art["📄 GitHub Issue Hierarchy"]:::artifact
@@ -346,7 +351,7 @@ mode:
346
351
  the canonical Epic-from-idea template; the operator confirms before
347
352
  the GitHub Issue is opened.
348
353
  5. **Open the Epic.** The Issue is opened with **only** the `type::epic`
349
- label — no `state::*` label is applied at creation. PRD authoring in
354
+ label — no `state::*` label is applied at creation. Spec authoring in
350
355
  Phase 1b advances it to `agent::review-spec`.
351
356
 
352
357
  #### Scope triage
@@ -354,7 +359,7 @@ mode:
354
359
  `/plan` Phase 1.5 runs the
355
360
  [`core/scope-triage`](../skills/core/scope-triage/SKILL.md) rubric over the
356
361
  sharpened one-pager so a story-sized scope is not pushed through the full Epic
357
- ceremony (PRD + Tech Spec + Acceptance Spec + Story backlog +
362
+ ceremony (Tech Spec + Acceptance Spec + Story backlog +
358
363
  `epic/<id>` integration branch) only to land as a degenerate one-Story
359
364
  output. The rubric anchors its sizing judgment **by reference** to
360
365
  the existing sizing SSOT (`DELIVERABLE_GRANULARITY_GUIDANCE` /
@@ -376,7 +381,7 @@ The same rubric also guards the **existing-Epic entry** (1b) as the
376
381
  hand-opened directly as a `type::epic` issue (the Phase 6 Epic Clarity Gate
377
382
  scores section *presence*, not scope *size*, so a clear-but-thin Epic would
378
383
  otherwise sail through). The advisory fires **only** when Phase 5 found no
379
- linked PRD / Tech Spec **and** the Epic has no open Story children, so
384
+ folded Tech Spec sections **and** the Epic has no open Story children, so
380
385
  it never re-triages an Epic that is being re-planned. An `epic` verdict
381
386
  proceeds silently; a `story` / `borderline` verdict STOPs with the same
382
387
  three-way choice (convert to a standalone Story / proceed as Epic anyway /
@@ -420,7 +425,7 @@ Epic id.
420
425
 
421
426
  The framework reads the Epic and autonomously builds the entire work breakdown.
422
427
 
423
- > **Epic Clarity Gate (`/plan` `planning.clarity-gate` state).** Before PRD / Tech Spec /
428
+ > **Epic Clarity Gate (`/plan` `planning.clarity-gate` state).** Before Tech Spec /
424
429
  > Acceptance Spec authoring kicks off, `/plan` scores the Epic body
425
430
  > against the five canonical sections from
426
431
  > [`templates/epic-from-idea.md`](../templates/epic-from-idea.md) (Context,
@@ -441,27 +446,32 @@ The framework reads the Epic and autonomously builds the entire work breakdown.
441
446
 
442
447
  1. **Epic Planner** (`epic-plan-spec.js`):
443
448
  - Synthesizes the Epic body with project documentation.
444
- - Generates a **PRD** (`context::prd`), **Tech Spec**
445
- (`context::tech-spec`), and **Acceptance Spec**
446
- (`context::acceptance-spec`) as linked GitHub Issues.
447
-
448
- > [!TIP] **PRD authoring acceptance criteria phrasing.** Write acceptance
449
+ - Folds the authored **Tech Spec** (opening with `## Delivery
450
+ Slicing`) and the **Acceptance Table** (the AC-ID table) into
451
+ marker-delimited managed sections of the Epic body. The Epic body
452
+ carries its `## User Stories` section inline — the PRD artifact
453
+ class was retired (Story #4314), and the `context::tech-spec` /
454
+ `context::acceptance-spec` ticket classes were retired the same way
455
+ (Story #4324): a `/plan` Epic run creates exactly **one** GitHub
456
+ issue.
457
+
458
+ > [!TIP] **Acceptance criteria phrasing.** Write the Epic's acceptance
449
459
  > criteria in Gherkin-compatible `Given / When / Then` form so the QA
450
460
  > acceptance suite can lift them directly into executable `.feature` files. See
451
461
  > [`rules/gherkin-standards.md`](../rules/gherkin-standards.md) for the canonical
452
462
  > clause grammar, tag taxonomy, and forbidden patterns.
453
463
 
454
- ### Acceptance Spec — the third planning context ticket
464
+ ### Acceptance Table — the second folded planning section
455
465
 
456
- Every Epic carries **three** planning context tickets, not two:
466
+ Every planned Epic body carries **two** managed planning sections
467
+ (Story #4324 — no separate context tickets):
457
468
 
458
- | Label | Artifact | Authored by | Drives |
459
- | --------------------------- | ---------------- | --------------------------------------------------- | -------------------------------------------------------- |
460
- | `context::prd` | PRD | `epic-plan-spec-author` skill (PRD persona) | What we're shipping and why. |
461
- | `context::tech-spec` | Tech Spec | `epic-plan-spec-author` skill (Architect persona) | How we're shipping it. |
462
- | `context::acceptance-spec` | Acceptance Spec | `epic-plan-spec-author` skill (Acceptance Engineer) | The AC ID table that gates close-time reconciliation. |
469
+ | Section | Artifact | Authored by | Drives |
470
+ | ---------------------- | ---------------- | --------------------------------------------------- | ----------------------------------------------------- |
471
+ | `## Delivery Slicing`… | Tech Spec | `epic-plan-spec-author` skill (Architect persona) | How we're shipping it. |
472
+ | `## Acceptance Table` | Acceptance Table | `epic-plan-spec-author` skill (Acceptance Engineer) | The AC ID table that gates close-time reconciliation. |
463
473
 
464
- The Acceptance Spec body is a single Markdown table —
474
+ The Acceptance Table section is a single Markdown table —
465
475
  `| AC ID | Outcome | Feature File | Scenario | Disposition |` — with
466
476
  stable `AC-<n>` IDs assigned in document order. IDs are reused across
467
477
  re-plans when an Outcome is materially unchanged so scenario tags
@@ -472,16 +482,20 @@ BDD runner + pending-tag (e.g. `playwright-bdd supports @skip`) for the
472
482
  features-first Story to consume.
473
483
 
474
484
  The spec is persisted by
475
- `epic-plan-spec.js --epic [Epic_ID] --prd ... --techspec ... --acceptance-spec ...`
476
- — the persist half writes all three artifacts in one atomic step and
477
- fails loudly if any is missing or empty.
485
+ `epic-plan-spec.js --epic [Epic_ID] --tech-spec ... --acceptance-table ...`
486
+ — the persist half folds both artifacts into the Epic body's managed
487
+ sections in one atomic, section-scoped write (everything outside the
488
+ managed regions is byte-preserved) and fails loudly if any input is
489
+ missing or empty. At delivery time, hydration strips the
490
+ `## Acceptance Table` section from story prompts — it is
491
+ authoring/close-time machinery, not delivery context.
478
492
 
479
493
  #### Adaptive planning risk routing
480
494
 
481
495
  `/plan`'s `planning.spec-authoring` state derives a deterministic
482
496
  **`planningRisk`** envelope from a **planner-authored risk verdict**
483
- (`risk-verdict.json`, the fourth planning artifact the
484
- `epic-plan-spec-author` Skill writes from the PRD / Tech Spec it just
497
+ (`risk-verdict.json`, the third planning artifact the
498
+ `epic-plan-spec-author` Skill writes from the Epic body / Tech Spec it just
485
499
  authored). The persist half of `epic-plan-spec.js` validates the verdict
486
500
  against `risk-verdict.schema.json` — a malformed verdict fails closed —
487
501
  then derives the envelope via `deriveRiskEnvelope`
@@ -500,8 +514,8 @@ downstream decisions:
500
514
  Epics (visible behavior, public API, security, billing, data
501
515
  migration, destructive mutation, critical workflow) trigger a HITL
502
516
  stop after `planning.spec-authoring` so the operator can read the
503
- PRD / Tech Spec / Acceptance Spec on GitHub before decomposition
504
- starts. Low-risk Epics (docs-only, internal refactor, pure test
517
+ Epic body's Tech Spec / Acceptance Table sections on GitHub before
518
+ decomposition starts. Low-risk Epics (docs-only, internal refactor, pure test
505
519
  harness, cleanup) print the auto-proceed message from
506
520
  `reviewRouting.operatorMessage` and chain directly into the
507
521
  `planning.decompose` state. The operator can force the review
@@ -528,7 +542,8 @@ on the Epic ticket records the waiver. There are two routes to the label:
528
542
  (see § Adaptive planning risk routing) and,
529
543
  when `acceptanceDisposition === 'not-applicable'`, the persist half
530
544
  of `epic-plan-spec.js` applies `acceptance::n-a` on the Epic and skips
531
- the Acceptance Spec artifact for that run. The disposition is also
545
+ the Acceptance Table section for that run (stripping a stale one on a
546
+ re-plan). The disposition is also
532
547
  recorded in the `epic-plan-state` checkpoint so the decision is
533
548
  auditable.
534
549
 
@@ -537,9 +552,11 @@ by both runtime gates:
537
552
 
538
553
  - The `/deliver` **start gate** (`delivery.snapshot` state) skips
539
554
  the acceptance-spec presence check when the label is set.
540
- - The finalize-time **acceptance-spec reconciler** returns
555
+ - The finalize-time **acceptance reconciler** returns
541
556
  `status: 'waived'` without scanning `tests/features/**` and the
542
- finalize step proceeds.
557
+ finalize step proceeds. (The waiver now waives the Epic body's
558
+ `## Acceptance Table` section — Story #4324 — with unchanged
559
+ meaning.)
543
560
 
544
561
  The waiver is binary — there is no partial opt-out. If an Epic later
545
562
  warrants spec coverage, remove the label and run `/plan`'s
@@ -550,9 +567,8 @@ warrants spec coverage, remove the label and run `/plan`'s
550
567
  (Epic → Story):
551
568
 
552
569
  ```text
553
- Epic (type::epic)
554
- ├── PRD (context::prd)
555
- ├── Tech Spec (context::tech-spec)
570
+ Epic (type::epic) ← body carries the folded Tech Spec
571
+ │ sections + ## Acceptance Table
556
572
  ├── Story (type::story)
557
573
  │ ├── acceptance[] ← inline on Story body
558
574
  │ └── verify[] ← inline on Story body
@@ -569,7 +585,7 @@ warrants spec coverage, remove the label and run `/plan`'s
569
585
  Story. The wave-loop fan-out in `/deliver` and the
570
586
  Story-branch → Epic-branch merge model are unchanged; the Feature and
571
587
  Task layers are gone, and thematic grouping lives as prose in the Epic
572
- body / Tech Spec.
588
+ body (which also carries the folded Tech Spec sections).
573
589
 
574
590
  When decomposition completes the Epic flips to `agent::ready` and the
575
591
  dispatch manifest is posted as a structured comment on the Epic. That
@@ -585,9 +601,9 @@ contract is enforced at the planner boundary so `/deliver` can
585
601
  treat `agent::ready` as a load-bearing precondition rather than a
586
602
  hopeful signal.
587
603
 
588
- - **Planning artifacts linked or waived.** The Epic body lists a
589
- linked `context::prd` and `context::tech-spec` ticket, and either a
590
- linked `context::acceptance-spec` ticket **or** the
604
+ - **Planning sections present or waived.** The Epic body carries the
605
+ folded Tech Spec sections (`## Delivery Slicing` onward), and either
606
+ the `## Acceptance Table` managed section **or** the
591
607
  `acceptance::n-a` waiver label. Missing-without-waiver fails the
592
608
  handoff.
593
609
  - **Decomposition persisted.** The structural reconciler has applied
@@ -641,19 +657,14 @@ side-effects rather than inline calls at phase boundaries; the
641
657
  "merge-lockout" lint rule keeps `gh pr merge` confined to the
642
658
  `AutomergeArmer` listener.
643
659
 
644
- > **Acceptance-spec start gate.** Before a single wave fans out,
660
+ > **Acceptance start gate.** Before a single wave fans out,
645
661
  > `/deliver`'s `delivery.snapshot` state
646
662
  > ([`lib/orchestration/epic-runner/phases/snapshot.js`](../scripts/lib/orchestration/epic-runner/phases/snapshot.js))
647
663
  > asserts that the Epic either (a) carries the `acceptance::n-a`
648
- > waiver label, or (b) has a linked `context::acceptance-spec`
649
- > ticket. The ticket's GitHub state (open / closed) is not checked
650
- > presence is sufficient, matching the PRD and Tech Spec contract.
651
- > The reviewer's OK during `/plan`'s `planning.spec-authoring`
652
- > state is the approval
653
- > signal, not a manual ticket-close action; the three planning
654
- > context tickets are closed automatically by the
655
- > `Finalizer` listener subscribed to `epic.close.end` once the
656
- > Epic PR opens. Neither
664
+ > waiver label, or (b) carries the `## Acceptance Table` managed
665
+ > section in its body (Story #4324). Presence is sufficient — the
666
+ > reviewer's OK during `/plan`'s `planning.spec-authoring` state is
667
+ > the approval signal. Neither
657
668
  > condition met → the snapshot throws a clear error naming the
658
669
  > missing precondition and `runAsCli` maps it to `process.exit(1)`.
659
670
  > This refuses to launch Epics that skipped acceptance-spec
@@ -748,7 +759,9 @@ standalone Stories), the Context Hydrator assembles a self-contained prompt:
748
759
 
749
760
  1. `agent-protocol.md` (universal rules).
750
761
  2. Persona and skill directives (from Task labels).
751
- 3. Hierarchy context (Story → Epic PRD Tech Spec).
762
+ 3. Hierarchy context (Story → Epic the Epic body carries the folded
763
+ Tech Spec sections; the `## Acceptance Table` section is stripped
764
+ from delivery prompts).
752
765
  4. **Story branch context.** Automatic checkouts to the Story branch. Under
753
766
  worktree isolation, each Story runs in its own `.worktrees/story-<id>/` so
754
767
  branch swaps, staging, and reflog activity are isolated per-story. See
@@ -902,15 +915,19 @@ watch / auto-merge / cleanup tail that drives the PR to merge:
902
915
  listener chain owns every close-time side effect end to end
903
916
  (Story #2894 — bus-owned finalize). The chain runs three
904
917
  responsibilities in order:
905
- 1. **Acceptance-spec reconciliation.** Invokes
918
+ 1. **Acceptance reconciliation.** Invokes
906
919
  `acceptance-spec-reconciler.js` to diff the AC IDs declared in
907
- the linked `context::acceptance-spec` body against `@ac-*` /
908
- `@pending` tags in `tests/features/**`. A non-OK reconciliation
909
- throws (per `.agents/rules/orchestration-error-handling.md`),
910
- aborting finalize **before** the planning artifacts are closed —
911
- so the PRD / Tech Spec / Acceptance Spec stay open until the AC
912
- coverage gap is fixed. Skipped (`status: 'waived'`) when the Epic
913
- carries `acceptance::n-a`.
920
+ the Epic body's `## Acceptance Table` managed section
921
+ (Story #4324) against `@epic-<id>-ac-*` / `@pending` tags in
922
+ `tests/features/**`. A non-OK reconciliation throws (per
923
+ `.agents/rules/orchestration-error-handling.md`), aborting
924
+ finalize **before** the PR opens the Epic blocks until the AC
925
+ coverage gap is fixed. On a clean run the reconciler records
926
+ each row's verification outcome (`satisfied | pending |
927
+ missing`) into the table's Disposition column — a
928
+ section-scoped write that touches only the managed region.
929
+ Skipped (`status: 'waived'`) when the Epic carries
930
+ `acceptance::n-a`.
914
931
  2. **PR open (bus-owned, Story #2894).** On
915
932
  `acceptance.reconcile.ok`, the `Finalizer` listener invokes
916
933
  `openOrLocatePr({ epicId, headBranch: 'epic/<id>', baseBranch:
@@ -925,19 +942,15 @@ watch / auto-merge / cleanup tail that drives the PR to merge:
925
942
  (enforced by the merge-lockout rule in
926
943
  `.agents/scripts/check-lifecycle-lint.js`); the
927
944
  `delivery.finalize` state never shells the merge command.
928
- 3. **Planning-artifact close + hand-off (bus-owned, Story #2894).**
929
- The `Finalizer` chains `closePlanningTickets({ epicId,
930
- provider })` to close the three planning context tickets
931
- (`context::prd`, `context::tech-spec`,
932
- `context::acceptance-spec`) so the Epic's `Closes #<id>`
933
- auto-close path is not blocked by open sub-issues, then
945
+ 3. **Hand-off (bus-owned, Story #2894).** The `Finalizer` runs
934
946
  `postHandoffComment({ epicId, prNumber, prUrl, provider })` to
935
947
  upsert the canonical `epic-handoff` structured comment naming
936
- the PR. Both helpers are idempotent re-running finalize
937
- after a crash counts already-closed tickets under
938
- `alreadyClosed` and edits the existing handoff comment in
939
- place rather than appending a duplicate. The Epic stays at
940
- `agent::executing` until the PR merges.
948
+ the PR. (Story #4324 retired the `closePlanningTickets` sweep
949
+ with the context-ticket classes there are no planning tickets
950
+ to close.) The helper is idempotent re-running finalize after
951
+ a crash edits the existing handoff comment in place rather than
952
+ appending a duplicate. The Epic stays at `agent::executing`
953
+ until the PR merges.
941
954
  6. **Watch-and-iterate (Phase 8).** `/deliver` watches the open PR's
942
955
  required checks until they turn green. Transient failures trigger an
943
956
  automated re-run loop; durable failures surface for human remediation
@@ -982,7 +995,7 @@ required checks fail.
982
995
  `code-review` comment, and the retro before merging by hand, or
983
996
  (b) checks fail and need remediation on the Epic branch. There is
984
997
  no separate close command — the close-out side effects (PR open,
985
- planning-ticket close, handoff comment) are owned by `/deliver`'s
998
+ handoff comment) are owned by `/deliver`'s
986
999
  `delivery.finalize` state (the lifecycle Finalizer listener), whose
987
1000
  replay is idempotent.
988
1001
 
@@ -1068,7 +1081,7 @@ action.
1068
1081
  integration target.
1069
1082
  2. **Completion.** Each Story flips to `agent::done` at its own closure
1070
1083
  (`story-close.js`); the wave loop tracks Epic-level progress as
1071
- Stories complete. There is no upward auto-cascade — Epics, PRDs, and
1084
+ Stories complete. There is no upward auto-cascade — Epics and
1072
1085
  Tech Specs are never flipped by Story closure; the Epic only flips to
1073
1086
  `agent::done` when the operator merges the PR to `main`.
1074
1087
 
@@ -1205,7 +1218,7 @@ on so re-runs short-circuit when state has not changed.
1205
1218
  | Close-validation | `/deliver` `delivery.close-validation` state | lint + test + maintainability + CRAP + coverage ratchets via `evidence-gate.js` | blocking | `evidence-gate` cache entry keyed by `git rev-parse HEAD` |
1206
1219
  | Pre-push | Local `.husky/pre-push` hook on every push | Diff-scoped quality preview + coverage/CRAP ratchet | blocking | Working-tree SHA + staged-diff hash (per push) |
1207
1220
  | Acceptance reconciliation | `/deliver` `delivery.finalize` state | `acceptance-spec-reconciler.js` diffs AC IDs against `@ac-*` / `@pending` feature tags | blocking | `acceptance-reconcile` structured comment on Epic, keyed by spec-body SHA |
1208
- | Spec freshness | `/plan` `planning.spec-authoring` state | Re-derives PRD / Tech Spec / Acceptance Spec staleness against Epic body checksum | advisory | `epic-plan-state` checkpoint entry per spec artifact body SHA |
1221
+ | Spec freshness | `/plan` `planning.spec-authoring` state | Re-derives Tech Spec / Acceptance Spec staleness against Epic body checksum | advisory | `epic-plan-state` checkpoint entry per spec artifact body SHA |
1209
1222
 
1210
1223
  ### Review & feedback loop
1211
1224
 
@@ -1411,9 +1424,9 @@ For Stories already in flight, use one of the three options above.
1411
1424
  | Command | Purpose |
1412
1425
  | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1413
1426
  | `npx mandrel init` | Cold-start command — install `mandrel` (if absent), `mandrel sync`, bootstrap.js (provisions repo + Projects V2 board, labels, branch protection), then onboarding tail (stack detection, docs scaffolding, doctor gate, `/plan` handoff). |
1414
- | `/plan` | Ideation entry — sharpen idea, search duplicates, open Epic, then PRD + Tech Spec + decomposition. |
1427
+ | `/plan` | Ideation entry — sharpen idea, search duplicates, open Epic, then Tech Spec + decomposition. |
1415
1428
  | `/plan --idea "<seed>"` | Same ideation entry with pre-supplied seed. |
1416
- | `/plan <epicId>` | Existing-Epic mode — PRD + Tech Spec + decomposition for an Epic Issue already opened. |
1429
+ | `/plan <epicId>` | Existing-Epic mode — Tech Spec + decomposition for an Epic Issue already opened. |
1417
1430
  | `/deliver <epicId>` | Drive an Epic end-to-end. Wave loop → close-validation → code-review → retro → opens PR to `main` with auto-merge armed. |
1418
1431
  | `/deliver <storyId> [<storyId>...]` | Deliver one or more standalone Stories (no `Epic: #N` reference). Builds a dependency-aware wave plan and fans out one worker per Story per wave. |
1419
1432
  | `/plan` | Plan a one-off Story outside an Epic backlog. |
@@ -110,6 +110,8 @@ top-level keys are validation errors.
110
110
  | `taskSizing.hardFiles` | No | `integer` | — | File-count hard ceiling: a Story exceeding it is rejected unless it declares `wide` with a reason (default 30). |
111
111
  | `taskSizing.maxAcceptance` | No | `integer` | — | Hard ceiling on acceptance[] item count (default 14). |
112
112
  | `taskSizing.softAcceptanceCount` | No | `integer` | — | Soft-warn threshold on acceptance[] item count (default 10). |
113
+ | `taskSizing.mergeCandidateMaxFiles` | No | `integer` | — | Under-size threshold (Story #4312): a Story with at most this many declared changes[] files, at most mergeCandidateMaxAcceptance acceptance items, and at least one depends_on edge to a sibling trips the advisory `merge-candidate` soft finding (default 3). |
114
+ | `taskSizing.mergeCandidateMaxAcceptance` | No | `integer` | — | Under-size threshold (Story #4312): the acceptance[] item ceiling of the `merge-candidate` soft finding heuristic (default 4). |
113
115
  | `failOnSharedEditors` | No | `boolean` | — | — |
114
116
  | `requireExplicitCrossStoryDeps` | No | `boolean` | — | — |
115
117
  | `failOnRegistryConflicts` | No | `boolean` | — | — |
@@ -448,7 +450,8 @@ suppress a channel entirely, set its array to `[]`.
448
450
  ### `planning.context`
449
451
 
450
452
  Caps the size of `--emit-context` JSON payloads emitted during `/plan`
451
- so a runaway PRD / Tech Spec can't blow the planning agent's context budget.
453
+ so a runaway Epic body (with its folded Tech Spec sections) can't blow the
454
+ planning agent's context budget.
452
455
 
453
456
  | Field | Required | Default | Purpose |
454
457
  | ------------- | -------- | -------- | --------------------------------------------------------------------------------------------- |
@@ -627,6 +630,12 @@ No tier-specific knobs beyond the common shape.
627
630
  | --------- | -------- | ------- | ---------------------------------------------------------------------------------------- |
628
631
  | `bundles` | No | `[]` | Array of `{ name, path, limit }` entries (e.g. `{ "name": "app", "path": "dist/app.js", "limit": "100kB" }`). |
629
632
 
633
+ Unlike `crap` / `maintainability`, this gate has no `refreshTag` config
634
+ field — there is no scorer to regenerate the baseline from source, so the
635
+ one-shot refresh/acknowledge mechanism is an env var, not a config knob.
636
+ See [`.agents/docs/quality-gates.md` § Bundle-size ratchet](quality-gates.md#bundle-size-ratchet--one-shot-refreshacknowledge-story-151)
637
+ for `BUNDLE_SIZE_REFRESH=1` usage.
638
+
630
639
  #### `delivery.quality.formatAutofix`
631
640
 
632
641
  | Field | Required | Default | Purpose |
@@ -791,6 +800,7 @@ the lint ratchet, and the CRAP/MI gates.
791
800
  | `baselines/lint.json` | `lint-baseline.js` | `node .agents/scripts/lint-baseline.js capture` |
792
801
  | `baselines/crap.json` | `update-crap-baseline.js` | `npm run crap:update` |
793
802
  | `baselines/maintainability.json` | `update-maintainability-baseline.js` | `npm run maintainability:update` |
803
+ | `baselines/bundle-size.json` | consumer's own build/measure step | Commit the build's measured sizes; for an intentional growth, run the check with `BUNDLE_SIZE_REFRESH=1` (see [Bundle-size ratchet](quality-gates.md#bundle-size-ratchet--one-shot-refreshacknowledge-story-151)) |
794
804
 
795
805
  These files are the contract. They are read by every gate (Story close, push
796
806
  hook, CI) and are regenerated only via tagged `baseline-refresh:` commits
@@ -452,6 +452,67 @@ watch loop — an unjustified baseline ratchet is no longer caught by CI.
452
452
 
453
453
  ---
454
454
 
455
+ ## Bundle-size ratchet — one-shot refresh/acknowledge (Story #151)
456
+
457
+ > Baseline envelope, axes, and component model: see the
458
+ > [Baseline reference](#baseline-reference) section below.
459
+
460
+ `check-baselines --gate bundle-size` is a **strict** ratchet: it diffs the
461
+ branch's committed `baselines/bundle-size.json` (head) against the base
462
+ ref's copy (`origin/main` by default) using the gate's configured
463
+ `tolerance`, and separately checks the head aggregate against `floors`.
464
+ Unlike `coverage` / `crap` / `maintainability`, bundle-size has **no
465
+ scorer of its own** — the measured `rawKb` / `gzippedKb` numbers come from
466
+ whatever build step the consumer already runs, not a source-tree rescan —
467
+ so there is no `refreshBaseline({ kind: 'bundle-size', ... })` path to
468
+ regenerate a "corrected" baseline the way `npm run crap:update` does.
469
+
470
+ This makes an **intentional** bundle-size growth (a framework major bump,
471
+ a new dependency, an SSR runtime swap) impossible to land cleanly with the
472
+ usual levers: permanently raising `tolerance` in `.agentrc.json` disables
473
+ the ratchet for every *future* PR too, not just the one that legitimately
474
+ grew.
475
+
476
+ ### `BUNDLE_SIZE_REFRESH=1`
477
+
478
+ Set the environment variable for the one CI/local run that needs to land
479
+ the growth:
480
+
481
+ ```bash
482
+ BUNDLE_SIZE_REFRESH=1 npm run bundle-size:check
483
+ # or, calling the dispatcher directly:
484
+ BUNDLE_SIZE_REFRESH=1 node .agents/scripts/check-baselines.js --gate bundle-size
485
+ ```
486
+
487
+ When set (`1` or `true`, case-insensitive), every `bundle-size`
488
+ head-vs-base regression is demoted to `unchanged` **for that invocation
489
+ only** — the gate compares head-vs-head in effect, so it passes even
490
+ though the committed baseline grew. **Floors still apply**: an
491
+ acknowledged PR can still fail if the head aggregate breaches the
492
+ configured `floors` budget, so a genuinely runaway regression isn't
493
+ silently waved through under the guise of "intentional".
494
+
495
+ Commit the regenerated `baselines/bundle-size.json` (reflecting the real,
496
+ larger sizes) in the same PR so the new numbers become the base for the
497
+ *next* PR's diff.
498
+
499
+ ### The ratchet returns to full strength automatically
500
+
501
+ `BUNDLE_SIZE_REFRESH` is read fresh on every invocation and is **never
502
+ persisted** — no config write, no committed tag, no lingering state. The
503
+ very next `check-baselines --gate bundle-size` run (i.e. the next PR),
504
+ without the env var set, re-enforces the ratchet at full strength against
505
+ the now-larger committed baseline. There is nothing to remember to reset.
506
+
507
+ This mirrors the `CRAP_TOLERANCE` env-override precedent (see
508
+ [CRAP gate — Consumer onboarding](#crap-gate--consumer-onboarding) above),
509
+ but as a true one-shot acknowledgment rather than a run-scoped tolerance
510
+ override: `CRAP_TOLERANCE` changes the *threshold*, `BUNDLE_SIZE_REFRESH`
511
+ demotes the *outcome* of an already-flagged regression, which is the
512
+ correct shape for a gate with no rescoring path of its own.
513
+
514
+ ---
515
+
455
516
  ## HITL blocker escalation
456
517
 
457
518
  `risk::high` is informational/planning metadata only. Runtime execution
@@ -57,7 +57,7 @@ description, edit the workflow file’s front-matter and regenerate.
57
57
  | `/git-deliver` | Single ad-hoc delivery command for working-tree changes. Detects the git setup and escalates to the right terminal step — commit only, commit + push, or commit + push + open a PR with native auto-merge — picking the default from observable state and letting flags pin any level explicitly. Replaces the retired git-commit-all, git-push, and git-pr-all trio. |
58
58
  | `/git-merge-pr` | Analyze, validate, resolve conflicts, and merge a given pull request by number. |
59
59
  | `/mandrel-update` | npm-era upgrade wraparound for a Mandrel consumer. Runs `npx mandrel update` (resolve newest published version → install → re-materialize `.agents/` → migrate → doctor → surface changelog) as the single mechanical step, then walks the operator through the judgment wraparound the CLI deliberately leaves unowned: reconcile `.agentrc.json`, install the Epic #1386 quality-gate surface, refresh the harness permission allowlist, reconcile the consumer's `AGENTS.md` / runbooks against the surfaced changelog, and stage + commit the staged lockfile bump. |
60
- | `/plan` | Unified planning entry point. Routes a seed idea (via scope triage) or an existing Epic ID to the right planning path — the full Epic pipeline (PRD, Tech Spec, Acceptance Spec, decomposition) or the standalone-Story authoring path — and absorbs every planning flag. |
60
+ | `/plan` | Unified planning entry point. Routes a seed idea (via scope triage) or an existing Epic ID to the right planning path — the full Epic pipeline (sectioned Epic body: Tech Spec + Acceptance Table, then decomposition) or the standalone-Story authoring path — and absorbs every planning flag. |
61
61
  | `/qa-assist` | Human-led QA assist loop — set up, then ride a rolling multi-observation intake session. The operator reports observations in any order; the agent enriches each (repro + root-cause file:line + coverage verdict for bugs; analysis + options + recommendation for enhancements), asks clarifying questions only when ambiguous, and appends a redacted ledger item — recording, never planning — to a persistent, resumable session under temp/qa/. Only when the operator says they are done does it review the full ledger and hand off to /plan. |
62
62
  | `/qa-explore` | Agent-led exploratory-QA loop — the agent Plans a surface with an explicit static-vs-drive method choice, drives it (browser MCP or static), and captures ledger items read-only, then Triages — a bounded per-surface session, HITL-gated at every phase transition, routed through the shared dedup/coverage/classification/missing-test/redaction/session core under temp/qa/ |
63
63
  | `/qa-run` | Drive Gherkin scenarios through a real browser as an agent-driven QA sweep |
@@ -263,16 +263,18 @@ stops.
263
263
  read `docs/style-guide.md` and `docs/web-routes.md`. Skip both when
264
264
  absent or unrelated to the task — they are not part of the universal
265
265
  mandatory set.
266
- - **Epic Context**: Additionally, read the context tickets (PRD, Tech
267
- Spec) linked in the current Epic's body and the task-specific
268
- instructions.
266
+ - **Epic Context**: Additionally, read the current Epic's body — the
267
+ single planning document (ideation sections plus the folded Tech
268
+ Spec sections; Story #4324 retired the separate context tickets) —
269
+ and the task-specific instructions.
269
270
  - **Optimization**: For large projects, prioritize targeted retrieval
270
271
  (semantic code search or focused text search) to isolate specific
271
272
  schemas or decisions before reading broad files.
272
273
  2. **Plan First:** For non-trivial tasks (3+ steps or architectural
273
- decisions), enter **Plan Mode**. Update the Tech Spec issue or create a
274
- new Technical Specification document in the `docs/` root (if not already
275
- handled by a ticket) before touching code.
274
+ decisions), enter **Plan Mode**. Update the Epic body's Tech Spec
275
+ sections (via `/plan`) or create a new Technical Specification document
276
+ in the `docs/` root (if not already handled by a ticket) before
277
+ touching code.
276
278
  3. **Artifacts over Chat:** Create log files for test results, build
277
279
  outputs, or debug sessions rather than pasting large code blocks in
278
280
  chat.
@@ -350,7 +352,7 @@ Mandrel uses a **2-tier ticket hierarchy** (Epic → Story).
350
352
  Acceptance criteria and verification steps live inline on the Story
351
353
  body (`acceptance[]` / `verify[]`); there is no Feature tier and no
352
354
  `type::task` ticket layer. Thematic grouping lives as prose in the
353
- Epic body / Tech Spec.
355
+ Epic body (which also carries the folded Tech Spec sections).
354
356
 
355
357
  - The decomposer emits only `type::epic` and `type::story` issues;
356
358
  Stories attach directly to the Epic.
@@ -14,8 +14,10 @@ _specifications_ that the Engineer personas will implement.
14
14
 
15
15
  Before permitting any code generation, you must enforce this workflow:
16
16
 
17
- 1. **Interrogate Context:** Read the Epic's linked PRD (`context::prd`) and
18
- Tech Spec (`context::tech-spec`) GitHub Issues, plus every file listed in
17
+ 1. **Interrogate Context:** Read the Epic body including its `## User
18
+ Stories` section and the folded Tech Spec sections (`## Delivery
19
+ Slicing` onward; Story #4324 retired the separate Tech Spec ticket) —
20
+ plus every file listed in
19
21
  `project.docsContextFiles` (typically `architecture.md` and
20
22
  `data-dictionary.md`). Ask clarifying questions about scale, budget, or
21
23
  edge cases.
@@ -76,10 +78,11 @@ Before permitting any code generation, you must enforce this workflow:
76
78
  - **Context:** A brief summary of what files will be touched.
77
79
  - **Pseudo-code:** High-level logic flow.
78
80
 
79
- ### Level 2: Complex Feature (Output to the Epic's Tech Spec GitHub Issue)
81
+ ### Level 2: Complex Feature (Output to the Epic body's Tech Spec sections)
80
82
 
81
- Open or update the GitHub Issue labelled `context::tech-spec` and linked to
82
- the parent Epic. The body must contain:
83
+ Update the parent Epic body's managed Tech Spec sections (the
84
+ `## Delivery Slicing`-led region via `/plan` Phase 7, which owns the
85
+ section-scoped write). The content must contain:
83
86
 
84
87
  1. **Goal:** One sentence summary.
85
88
  2. **Proposed Changes:** List of files to create/modify.
@@ -8,12 +8,13 @@ specifications within the `@repo/mobile` workspace. You value **native feel**,
8
8
  **offline resilience**, and **cross-platform consistency**.
9
9
 
10
10
  **Golden Rule:** Never guess. If a requirement is missing from the Architect's
11
- plan or the PRD's Acceptance Criteria, stop and ask. Do not invent business
11
+ plan or the Epic's Acceptance Criteria, stop and ask. Do not invent business
12
12
  logic or UX decisions.
13
13
 
14
14
  ## 2. Interaction Protocol
15
15
 
16
- 1. **Read Context:** Before writing a single line, read the relevant tech spec
16
+ 1. **Read Context:** Before writing a single line, read the parent Epic
17
+ body's Tech Spec sections
17
18
  and the project's architectural guidelines. Understand the screen/navigation
18
19
  hierarchy.
19
20
  2. **Workspace Scope:** You operate exclusively within `@repo/mobile`. All
@@ -8,12 +8,13 @@ Architect's design specifications within the `@repo/web` workspace. You value
8
8
  **component reusability**, **semantic HTML**, and **progressive enhancement**.
9
9
 
10
10
  **Golden Rule:** Never guess. If a requirement is missing from the Architect's
11
- plan or the PRD's Acceptance Criteria, stop and ask. Do not invent business
11
+ plan or the Epic's Acceptance Criteria, stop and ask. Do not invent business
12
12
  logic or UX decisions.
13
13
 
14
14
  ## 2. Interaction Protocol
15
15
 
16
- 1. **Read Context:** Before writing a single line, read the relevant tech spec
16
+ 1. **Read Context:** Before writing a single line, read the parent Epic
17
+ body's Tech Spec sections
17
18
  and the project's architectural guidelines. Understand the page/component
18
19
  hierarchy.
19
20
  2. **Workspace Scope:** You operate exclusively within `@repo/web`. All commands
@@ -16,11 +16,12 @@ plan, stop and ask. Do not invent business logic.
16
16
 
17
17
  ## 2. Interaction Protocol
18
18
 
19
- 1. **Read Context:** Before writing a single line, read the parent Epic's
20
- linked Tech Spec GitHub Issue (`context::tech-spec`) and PRD
21
- (`context::prd`), plus every file listed in
22
- `project.docsContextFiles` (typically `architecture.md` and the
23
- project's architectural guidelines).
19
+ 1. **Read Context:** Before writing a single line, read the parent Epic
20
+ body the single planning document, including its `## User Stories`
21
+ section and the folded Tech Spec sections (`## Delivery Slicing`
22
+ onward; Story #4324 retired the separate Tech Spec ticket) — plus
23
+ every file listed in `project.docsContextFiles` (typically
24
+ `architecture.md` and the project's architectural guidelines).
24
25
  2. **Workspace Awareness:** Identify if you are working in a monorepo or a
25
26
  standard repo. Ensure all commands (installing packages, running scripts) are
26
27
  executed in the correct workspace/directory. Check `package.json` or the