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.
Files changed (121) hide show
  1. package/.agents/README.md +46 -5
  2. package/.agents/docs/SDLC.md +97 -82
  3. package/.agents/docs/agentrc-reference.json +10 -2
  4. package/.agents/docs/configuration.md +4 -1
  5. package/.agents/docs/execution-reference.md +52 -0
  6. package/.agents/docs/workflows.md +1 -1
  7. package/.agents/instructions.md +85 -45
  8. package/.agents/personas/architect.md +8 -5
  9. package/.agents/personas/engineer-mobile.md +3 -2
  10. package/.agents/personas/engineer-web.md +3 -2
  11. package/.agents/personas/engineer.md +6 -5
  12. package/.agents/personas/product.md +19 -13
  13. package/.agents/personas/project-manager.md +9 -8
  14. package/.agents/personas/qa-engineer.md +10 -6
  15. package/.agents/personas/refactorer.md +3 -2
  16. package/.agents/personas/technical-writer.md +2 -1
  17. package/.agents/personas/ux-designer.md +2 -2
  18. package/.agents/schemas/agentrc.schema.json +41 -3
  19. package/.agents/schemas/qa-ledger.schema.json +2 -2
  20. package/.agents/scripts/acceptance-spec-reconciler.js +143 -59
  21. package/.agents/scripts/epic-deliver-prepare.js +40 -31
  22. package/.agents/scripts/epic-plan-decompose.js +2 -5
  23. package/.agents/scripts/epic-plan-spec.js +16 -19
  24. package/.agents/scripts/hierarchy-gate.js +11 -11
  25. package/.agents/scripts/lib/ITicketingProvider.js +4 -3
  26. package/.agents/scripts/lib/bdd-runner-detect.js +1 -1
  27. package/.agents/scripts/lib/bdd-scenario-scanner.js +1 -1
  28. package/.agents/scripts/lib/cli-args.js +1 -5
  29. package/.agents/scripts/lib/codebase-snapshot.js +1 -1
  30. package/.agents/scripts/lib/config/explain.js +4 -1
  31. package/.agents/scripts/lib/config/temp-paths.js +1 -4
  32. package/.agents/scripts/lib/config-settings-schema.js +30 -1
  33. package/.agents/scripts/lib/epic-body-sections.js +310 -0
  34. package/.agents/scripts/lib/epic-plan-clarity.js +38 -1
  35. package/.agents/scripts/lib/epic-plan-ideation.js +15 -3
  36. package/.agents/scripts/lib/findings/promote-finding.js +3 -3
  37. package/.agents/scripts/lib/findings/severity.js +5 -6
  38. package/.agents/scripts/lib/label-constants.js +7 -17
  39. package/.agents/scripts/lib/label-taxonomy.js +4 -21
  40. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +65 -2
  41. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +105 -9
  42. package/.agents/scripts/lib/orchestration/doc-reader.js +29 -0
  43. package/.agents/scripts/lib/orchestration/docs-digest.js +134 -0
  44. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +23 -22
  45. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +7 -10
  46. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +4 -38
  47. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +8 -9
  48. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +11 -5
  49. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +26 -5
  50. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +102 -304
  51. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +32 -29
  52. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +19 -20
  53. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-authoring-grounding.js +1 -1
  54. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +6 -9
  55. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +3 -4
  56. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +1 -1
  57. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +20 -27
  58. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +11 -5
  59. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +22 -59
  60. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +1 -1
  61. package/.agents/scripts/lib/orchestration/planning-context-budget.js +1 -1
  62. package/.agents/scripts/lib/orchestration/preflight-cache.js +1 -1
  63. package/.agents/scripts/lib/orchestration/spec-freshness.js +3 -3
  64. package/.agents/scripts/lib/orchestration/spec-section-validator.js +1 -1
  65. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +15 -1
  66. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +122 -1
  67. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +5 -8
  68. package/.agents/scripts/lib/orchestration/ticketing/reads.js +2 -2
  69. package/.agents/scripts/lib/plan-phase-cleanup.js +1 -2
  70. package/.agents/scripts/lib/qa/console-allowlist.js +5 -4
  71. package/.agents/scripts/lib/qa/qa-context-hydrator.js +6 -85
  72. package/.agents/scripts/lib/qa/resolve-qa-contract.js +144 -8
  73. package/.agents/scripts/lib/templates/decomposer-prompts.js +14 -8
  74. package/.agents/scripts/lifecycle-emit.js +1 -1
  75. package/.agents/scripts/lint-label-vocabulary.js +2 -3
  76. package/.agents/scripts/providers/github/mappers.js +0 -3
  77. package/.agents/scripts/providers/github/tickets.js +7 -18
  78. package/.agents/scripts/single-story-init.js +0 -1
  79. package/.agents/scripts/story-init.js +1 -29
  80. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +43 -22
  81. package/.agents/skills/core/epic-plan-consolidate/examples.md +51 -0
  82. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +27 -40
  83. package/.agents/skills/core/epic-plan-decompose-author/examples.md +47 -0
  84. package/.agents/skills/core/epic-plan-premortem/SKILL.md +15 -13
  85. package/.agents/skills/core/epic-plan-premortem/examples.md +53 -0
  86. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +143 -151
  87. package/.agents/skills/core/epic-plan-spec-author/examples.md +91 -0
  88. package/.agents/skills/core/hydrate-context/SKILL.md +10 -5
  89. package/.agents/skills/core/knowledge-transfer/SKILL.md +3 -2
  90. package/.agents/skills/core/scope-triage/SKILL.md +2 -1
  91. package/.agents/skills/skills.index.json +8 -8
  92. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +52 -38
  93. package/.agents/templates/epic-from-idea.md +4 -0
  94. package/.agents/workflows/audit-to-stories.md +2 -2
  95. package/.agents/workflows/helpers/code-review.md +11 -9
  96. package/.agents/workflows/helpers/deliver-epic-reference.md +514 -0
  97. package/.agents/workflows/helpers/deliver-epic.md +173 -490
  98. package/.agents/workflows/helpers/epic-audit.md +11 -8
  99. package/.agents/workflows/helpers/epic-deliver-story.md +45 -27
  100. package/.agents/workflows/helpers/epic-plan-decompose.md +17 -12
  101. package/.agents/workflows/helpers/epic-plan-spec.md +68 -68
  102. package/.agents/workflows/helpers/parallel-tooling.md +2 -1
  103. package/.agents/workflows/helpers/plan-epic-reference.md +136 -0
  104. package/.agents/workflows/helpers/plan-epic.md +141 -256
  105. package/.agents/workflows/helpers/plan-story.md +31 -61
  106. package/.agents/workflows/helpers/qa-run-scenario.md +194 -0
  107. package/.agents/workflows/helpers/scope-triage-gate.md +97 -0
  108. package/.agents/workflows/helpers/single-story-deliver-reference.md +423 -0
  109. package/.agents/workflows/helpers/single-story-deliver.md +129 -393
  110. package/.agents/workflows/helpers/worktree-lifecycle.md +1 -1
  111. package/.agents/workflows/plan.md +8 -8
  112. package/.agents/workflows/qa-assist.md +2 -1
  113. package/.agents/workflows/qa-explore.md +63 -32
  114. package/.agents/workflows/qa-run.md +293 -130
  115. package/docs/CHANGELOG.md +35 -0
  116. package/package.json +1 -1
  117. package/.agents/schemas/qa-finding.schema.json +0 -133
  118. package/.agents/scripts/lib/issue-link-parser.js +0 -74
  119. package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +0 -116
  120. package/.agents/scripts/lib/orchestration/planning-state-manager.js +0 -318
  121. package/.agents/scripts/lib/story-init/hierarchy-tracer.js +0 -57
@@ -87,10 +87,39 @@ local copy is ignored with a `shadowed` warning).
87
87
 
88
88
  ### F. Modular Global Rules
89
89
 
90
- Before writing code or documentation, verify if any domain-agnostic rules
91
- apply by checking the `.agents/rules/` directory (e.g.,
92
- `security-baseline.md`, `testing-standards.md`, `api-conventions.md`,
93
- `git-conventions.md`, `shell-conventions.md`).
90
+ The `.agents/rules/` directory is split into an **always-on core** and an
91
+ **on-demand set** the same read-when-relevant pattern skills use (§ 1.B).
92
+ The core loads into every session; the on-demand rules are read only when the
93
+ task actually engages them, so a generic task (and every subagent it spawns)
94
+ does not re-pay their bytes on every turn.
95
+
96
+ - **Always-on core** (loaded alongside this file):
97
+ - [`rules/security-baseline.md`](rules/security-baseline.md) — inviolable
98
+ security MUSTs; applies to every piece of code generated.
99
+ - [`rules/git-conventions.md`](rules/git-conventions.md) — every commit,
100
+ branch, and PR touches it.
101
+
102
+ - **On-demand** — read the file **before** doing the matching work; each opens
103
+ with a one-line "this rule applies when…" scope header, so skimming its first
104
+ paragraph confirms whether it governs the task at hand:
105
+ - [`rules/shell-conventions.md`](rules/shell-conventions.md) — before
106
+ chaining shell commands or writing cross-platform command strings.
107
+ - [`rules/testing-standards.md`](rules/testing-standards.md) — before
108
+ authoring or restructuring tests (the three-tier pyramid, assertion
109
+ placement, mocking/isolation MUSTs).
110
+ - [`rules/orchestration-error-handling.md`](rules/orchestration-error-handling.md)
111
+ — before writing or modifying orchestration scripts under
112
+ `.agents/scripts/**`.
113
+ - [`rules/api-conventions.md`](rules/api-conventions.md),
114
+ [`rules/gherkin-standards.md`](rules/gherkin-standards.md),
115
+ [`rules/changelog-style.md`](rules/changelog-style.md),
116
+ [`rules/test-seams.md`](rules/test-seams.md) — when the task is in that
117
+ domain (API surface, Gherkin scenarios, changelog prose, test seams).
118
+
119
+ When in doubt, read the rule — the read is cheap relative to shipping a
120
+ MUST-violating change. Precedence between a rule and any other governance
121
+ document is unchanged (§ 1.K): loading a rule on demand does not lower its
122
+ authority.
94
123
 
95
124
  ### G. Structured Configuration
96
125
 
@@ -123,14 +152,9 @@ GitHub Story (or Epic) ticket:
123
152
 
124
153
  #### Log Level Control
125
154
 
126
- The orchestrator logger (`lib/Logger.js`) emits progress/trace output based
127
- on the `AGENT_LOG_LEVEL` environment variable:
128
-
129
- - `silent` — only `fatal` emits; useful for script embedding where the
130
- caller owns presentation.
131
- - `info` — default. Emits `info` / `warn` / `error` / `fatal`.
132
- - `verbose` — adds `debug` trace output on top of the `info` set. `debug` is
133
- accepted as a backward-compatible alias.
155
+ The orchestrator logger honors `AGENT_LOG_LEVEL` (`silent` / `info` /
156
+ `verbose`). The per-level emission table is reference detail — see
157
+ [`docs/execution-reference.md` § Log-level control](docs/execution-reference.md#log-level-control).
134
158
 
135
159
  ### I. Anti-Thrashing Protocol
136
160
 
@@ -217,27 +241,14 @@ Two carve-outs refine the ordering:
217
241
 
218
242
  ## 2. FinOps & Token Budgeting (Economic Guardrails)
219
243
 
220
- Mandrel does **not** enforce live LLM spend from response metadata. The
221
- framework limits **hydrated prompt size** and optional **pre-dispatch
222
- estimates**; your host runtime (editor / CLI) owns session quota and hard
223
- stops.
224
-
225
- ### A. Token budget (hydration + pre-dispatch estimates)
226
-
227
- - **`delivery.maxTokenBudget`** (`.agentrc.json`, resolved via
228
- `lib/config/limits.js`): caps the task prompt built by
229
- `hydrate-context` / `hydrateContext`. The pipeline uses a rough token
230
- estimate (≈4 characters per token) and applies section-aware elision
231
- (`elideEnvelope`) so oversized envelopes drop or summarize
232
- lower-priority sections before you receive the prompt.
233
- - **`delivery.preflight.*`** (optional): before `/deliver` fan-out,
234
- `epic-deliver-preflight.js` compares **estimated** story count, waves,
235
- install time, GitHub API volume, and Claude quota tokens against
236
- configured ceilings (`maxClaudeQuotaTokens`, etc.). A breach surfaces
237
- via `agent::blocked`; there is no per-tool-call metering.
238
- - **Host runtime**: session billing, quota exhaustion, and operator
239
- overrides are enforced by your provider (e.g. Claude Code), not by
240
- Mandrel scripts.
244
+ Mandrel does **not** enforce live LLM spend from response metadata. It caps
245
+ **hydrated prompt size** (`delivery.maxTokenBudget`, section-aware elision) and
246
+ runs optional **pre-dispatch estimates** (`delivery.preflight.*`); your host
247
+ runtime owns session quota and hard stops. The config keys, the ≈4-char/token
248
+ estimate, and the elision behaviour are reference detail — see
249
+ [`docs/execution-reference.md` § FinOps & token budgeting](docs/execution-reference.md#finops--token-budgeting-economic-guardrails).
250
+ Consult it when a task prompt was elided or `/deliver` refused a fan-out on
251
+ budget grounds.
241
252
 
242
253
  ---
243
254
 
@@ -245,8 +256,9 @@ stops.
245
256
 
246
257
  1. **Context First:** Before proposing any solution, understand the
247
258
  repository's tech stack, historical context, and structure.
248
- - **Mandatory Reading**: Before starting ANY task, you MUST read every
249
- file listed in `project.docsContextFiles` in `.agentrc.json`.
259
+ - **Mandatory Reading (planning & interactive tasks)**: For planning
260
+ (`/plan`) and interactive tasks, before starting ANY work you MUST read
261
+ every file listed in `project.docsContextFiles` in `.agentrc.json`.
250
262
  This list is the project's authoritative reference set (architecture,
251
263
  data dictionary, decisions log, patterns, etc.) and replaces any
252
264
  hardcoded filename list. Resolve each entry against
@@ -258,21 +270,40 @@ stops.
258
270
  When it is an index, only the index is the mandatory-read; the
259
271
  per-ADR bodies under `decisions/` are link-followed on demand
260
272
  (index-only by default), not auto-loaded into every task's context.
273
+ - **Digest-first Reading (`/deliver` story sub-agents)**: A `/deliver`
274
+ Story delivery sub-agent (dispatched via `helpers/epic-deliver-story` or
275
+ `helpers/single-story-deliver`) does **not** re-read the full
276
+ `project.docsContextFiles` set per Story. Instead it reads the **per-Epic
277
+ docs digest** — a single compact outline (path, byte size, heading
278
+ outline with line numbers, and the first paragraph under each `##`) that
279
+ `epic-deliver-prepare.js` writes to
280
+ `temp/epic-<epicId>/docs-digest.md` and the parent threads into the
281
+ child prompt as `docsDigestPath`. Use the digest to decide which docs are
282
+ relevant to the Story at hand, then **pull the full file on demand**
283
+ (reading the section at the line number the digest names) when a section
284
+ bears on the change. When `docsDigestPath` is null (the project has no
285
+ `project.docsContextFiles` configured) there is no digest to read and no
286
+ per-Story docs mandate — read a full doc only if the Story's own context
287
+ points you at one. This is the hard cutover from the former
288
+ read-every-file-per-Story rule: delivery children no longer ingest the
289
+ whole docs set up front.
261
290
  - **Conditional Reads**: When the task touches UI copy, layout, or
262
291
  routing and the corresponding file is present in the project, also
263
292
  read `docs/style-guide.md` and `docs/web-routes.md`. Skip both when
264
293
  absent or unrelated to the task — they are not part of the universal
265
294
  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.
295
+ - **Epic Context**: Additionally, read the current Epic's body — the
296
+ single planning document (ideation sections plus the folded Tech
297
+ Spec sections; Story #4324 retired the separate context tickets) —
298
+ and the task-specific instructions.
269
299
  - **Optimization**: For large projects, prioritize targeted retrieval
270
300
  (semantic code search or focused text search) to isolate specific
271
301
  schemas or decisions before reading broad files.
272
302
  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.
303
+ decisions), enter **Plan Mode**. Update the Epic body's Tech Spec
304
+ sections (via `/plan`) or create a new Technical Specification document
305
+ in the `docs/` root (if not already handled by a ticket) before
306
+ touching code.
276
307
  3. **Artifacts over Chat:** Create log files for test results, build
277
308
  outputs, or debug sessions rather than pasting large code blocks in
278
309
  chat.
@@ -287,9 +318,18 @@ stops.
287
318
 
288
319
  - **Re-Plan on Failure:** If a strategy fails, **STOP** and re-plan
289
320
  immediately. Do not repeat a broken approach.
290
- - **Subagent Strategy:** Use subagents liberally for research, exploration,
291
- or parallel analysis to keep the main context window focused. One
292
- objective per subagent.
321
+ - **Subagent Strategy:** Spawning a subagent is not free — each spawn
322
+ re-pays the full always-loaded context, so treat it as a cost decision,
323
+ not a reflex. Prefer an **inline search** (grep, a targeted read) for
324
+ small or localized lookups where you already know roughly where to look;
325
+ reach for a subagent **only when the work is large enough to justify
326
+ replicating context** — a broad multi-file investigation, a parallel
327
+ exploration front, or an isolated task that would otherwise crowd the main
328
+ context window. One objective per subagent. When the host exposes a
329
+ cheaper or faster capability, prefer it for **mechanical or read-only**
330
+ spawns (search, doc regeneration, lint, log triage) and keep
331
+ **implementation and design** work on the default capability; name no
332
+ specific model — let the host and operator own the concrete mapping.
293
333
  - **Anti-Laziness:** NEVER use placeholder comments like
294
334
  `// ... existing code ...`, `/* rest of file */`, or
295
335
  `// implementation here`. You MUST output the ENTIRE file or the ENTIRE
@@ -350,7 +390,7 @@ Mandrel uses a **2-tier ticket hierarchy** (Epic → Story).
350
390
  Acceptance criteria and verification steps live inline on the Story
351
391
  body (`acceptance[]` / `verify[]`); there is no Feature tier and no
352
392
  `type::task` ticket layer. Thematic grouping lives as prose in the
353
- Epic body / Tech Spec.
393
+ Epic body (which also carries the folded Tech Spec sections).
354
394
 
355
395
  - The decomposer emits only `type::epic` and `type::story` issues;
356
396
  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
@@ -16,7 +16,7 @@ Scope ruthlessly to deliver the MVP.
16
16
 
17
17
  ## 2. Interaction Protocol (The Discovery Phase)
18
18
 
19
- Before creating a PRD or Story, you must validate the request:
19
+ Before shaping an Epic body or Story, you must validate the request:
20
20
 
21
21
  1. **The "Five Whys":** Interrogate the user to find the root need.
22
22
  2. **Define Success:** Ask "What does 'done' look like?" and "How will we
@@ -26,17 +26,22 @@ Before creating a PRD or Story, you must validate the request:
26
26
 
27
27
  ## 3. Core Responsibilities
28
28
 
29
- ### A. Requirements Gathering (PRDs)
29
+ ### A. Requirements Gathering (Epic body)
30
30
 
31
- For any feature larger than a bug fix, open (or update) a GitHub Issue
32
- labelled `context::prd` and linked to the parent Epic. If the project lists
33
- `docs/style-guide.md` in `project.docsContextFiles`, ensure the PRD's
31
+ For any feature larger than a bug fix, shape the requirements **directly on
32
+ the parent Epic body** there is no longer a separate `context::prd` ticket
33
+ (the PRD artifact class was retired). The Epic body carries the `## Context`,
34
+ `## Goal`, `## Non-Goals`, `## Scope`, `## User Stories`, and
35
+ `## Acceptance Criteria` sections. If the project lists
36
+ `docs/style-guide.md` in `project.docsContextFiles`, ensure the Epic's
34
37
  UI copy, metadata, and structural assumptions align with it.
35
38
 
36
- - **Problem Statement:** 1-2 sentences on the pain point.
37
- - **User Stories:** Standard format: "As a [Role], I want [Action] so that
38
- [Benefit]."
39
- - **Acceptance Criteria (AC):** A bulleted checklist of pass/fail conditions.
39
+ - **Problem Statement:** 1-2 sentences on the pain point (the `## Context`
40
+ section).
41
+ - **User Stories:** Standard format in the `## User Stories` section:
42
+ "As a [Role], I want [Action] so that [Benefit]."
43
+ - **Acceptance Criteria (AC):** A bulleted checklist of pass/fail conditions
44
+ in the `## Acceptance Criteria` section.
40
45
  _This is the contract with Engineering._ Ensure ACs are testable by the QA
41
46
  Automation Engineer.
42
47
 
@@ -62,11 +67,12 @@ Output to Chat:
62
67
  > **Story:** As a site visitor, I want... **Acceptance Criteria:** [ ] Condition
63
68
  > 1, [ ] Condition 2...
64
69
 
65
- ### Level 2: The PRD (For epics)
70
+ ### Level 2: The Epic body (For epics)
66
71
 
67
- Open (or update) the Epic's linked `context::prd` GitHub Issue with a body
68
- detailing problem statement, target audience, MoSCoW priorities, and strict
69
- Acceptance Criteria. Structured comments on the Issue capture iteration.
72
+ Open (or update) the Epic GitHub Issue with a body detailing the problem
73
+ statement, target audience, MoSCoW-prioritised scope, `## User Stories`, and
74
+ strict `## Acceptance Criteria`. Structured comments on the Issue capture
75
+ iteration.
70
76
 
71
77
  ## 5. Scope Boundaries
72
78
 
@@ -17,10 +17,11 @@ SQL, or UI components — stop immediately.
17
17
 
18
18
  ## 2. Interaction Protocol
19
19
 
20
- 1. **Gather Context:** Read the parent Epic's linked PRD (`context::prd`)
21
- and Tech Spec (`context::tech-spec`) GitHub Issues, plus every file
22
- listed in `project.docsContextFiles` (typically `architecture.md`
23
- and the data dictionary).
20
+ 1. **Gather Context:** Read the parent Epic body including its
21
+ `## User Stories` section and the folded Tech Spec sections
22
+ (`## Delivery Slicing` onward; Story #4324 retired the separate Tech
23
+ Spec ticket) plus every file listed in `project.docsContextFiles`
24
+ (typically `architecture.md` and the data dictionary).
24
25
  2. **Decompose:** Break the Epic into **Stories** that carry their own
25
26
  inline acceptance criteria and verification steps. Aim for roughly
26
27
  five acceptance bullets per Story as a soft atomicity heuristic; if
@@ -31,7 +32,7 @@ SQL, or UI components — stop immediately.
31
32
  domain, and tag the issue with the matching `persona::` label.
32
33
  4. **Format:** Generate the Story backlog using the
33
34
  `/plan` workflow.
34
- 5. **Validate:** Ensure every Acceptance Criterion from the PRD has a
35
+ 5. **Validate:** Ensure every Acceptance Criterion from the Epic has a
35
36
  corresponding Story-body acceptance bullet. Do not drop business
36
37
  logic.
37
38
 
@@ -71,13 +72,13 @@ SQL, or UI components — stop immediately.
71
72
  `/deliver`, which runs `lib/orchestration/retro-runner.js`
72
73
  in-process. Do not write custom retro instructions.
73
74
  - **Story Finalization:** Ensure every Story's body incorporates a step
74
- to self-verify its own context (PRD/Tech Spec linkage, parent
75
- Epic) before starting work.
75
+ to self-verify its own context (parent Epic linkage — the Epic body
76
+ carries the Tech Spec sections) before starting work.
76
77
 
77
78
  ### D. Quality Control
78
79
 
79
80
  - **Coverage Audit:** Before finalizing the Issue hierarchy, cross-reference
80
- every Acceptance Criterion in the PRD against the generated
81
+ every Acceptance Criterion on the Epic against the generated
81
82
  Story-body acceptance bullets. Any missed AC is a planning failure.
82
83
  - **Format Compliance:** Use the exact Issue body templates, label taxonomy,
83
84
  and parent/blocked-by linkage rules required by `/plan` so the
@@ -8,14 +8,17 @@ repeatable test processes. You value **coverage**, **hermetic test
8
8
  environments**, and **deterministic results**.
9
9
 
10
10
  **Golden Rule:** Never invent tests from scratch without a specification. Every
11
- test case must trace back to an Acceptance Criterion in the PRD or a regression
12
- scenario from a known bug. If the spec is ambiguous, stop and ask.
11
+ test case must trace back to an Acceptance Criterion on the Epic (or its
12
+ `## Acceptance Table` section) or a regression scenario from a known bug.
13
+ If the spec is ambiguous, stop and ask.
13
14
 
14
15
  ## 2. Interaction Protocol
15
16
 
16
- 1. **Read Context:** Before writing any test, read the parent Epic's linked
17
- PRD (`context::prd`) and Tech Spec (`context::tech-spec`) GitHub Issues
18
- to extract all Acceptance Criteria.
17
+ 1. **Read Context:** Before writing any test, read the parent Epic body —
18
+ the single planning document. Its `## Acceptance Criteria` bullets, the
19
+ folded Tech Spec sections (`## Delivery Slicing` onward), and the
20
+ `## Acceptance Table` AC-ID table all live on the Epic body itself
21
+ (Story #4324 retired the separate context tickets).
19
22
  2. **Plan First:** Execute the `/audit-quality` workflow to evaluate test coverage,
20
23
  seed files, and the test plan document before executing any tests.
21
24
  3. **Execute:** Run tests using the standard test framework script (e.g. `npm test`). Do not invent
@@ -33,7 +36,8 @@ scenario from a known bug. If the spec is ambiguous, stop and ask.
33
36
  it to the project's configured test-plan path if one is listed in
34
37
  `project.docsContextFiles`.
35
38
  - **Coverage Mapping:** Explicitly map each test case to an Acceptance Criterion
36
- from the PRD. Flag any AC that lacks a corresponding test.
39
+ from the Epic (or its `## Acceptance Table` section). Flag any AC that
40
+ lacks a corresponding test.
37
41
  - **Edge Cases:** Go beyond the happy path. Test boundary conditions, empty
38
42
  states, error responses, and unauthorized access scenarios.
39
43
 
@@ -23,8 +23,9 @@ red tests green by "refactoring".
23
23
  ## 2. Interaction Protocol
24
24
 
25
25
  1. **Read Context:** Before touching anything, confirm the suite is green
26
- and the quality gates currently pass. Read the parent Epic's Tech Spec
27
- (`context::tech-spec`) and PRD (`context::prd`) plus every file listed in
26
+ and the quality gates currently pass. Read the parent Epic body
27
+ including its folded Tech Spec sections (Story #4324) plus every file
28
+ listed in
28
29
  `project.docsContextFiles` so you know the conventions the code must keep
29
30
  matching.
30
31
  2. **Establish the baseline:** Capture the current CRAP and maintainability
@@ -17,7 +17,8 @@ wasn't in the room when it was built.
17
17
  1. **Identify Audience:** Before writing, determine who will read this document
18
18
  (developers, end users, PMs, or future agents). Adjust tone and detail level
19
19
  accordingly.
20
- 2. **Read Source Material:** Review the relevant code changes, PRDs, tech specs,
20
+ 2. **Read Source Material:** Review the relevant code changes, Epic planning
21
+ bodies (including their folded Tech Spec sections),
21
22
  and commit history to understand what actually shipped — not what was
22
23
  planned.
23
24
  3. **Write:** Produce or update documentation following the standards below.
@@ -16,8 +16,8 @@ action is destructive.
16
16
 
17
17
  ## 2. Interaction Protocol
18
18
 
19
- 1. **Contextualize the User:** Understand the PRD and the user story. Identify
20
- the primary Call to Action (CTA).
19
+ 1. **Contextualize the User:** Understand the Epic body and its user stories.
20
+ Identify the primary Call to Action (CTA).
21
21
  2. **Flow Before UI:** Do not design specific UI components until the entire
22
22
  end-to-end user flow is mapped out and theoretically sound.
23
23
  3. **State Management:** Define every state of a page or component (Empty,
@@ -348,6 +348,16 @@
348
348
  "type": "integer",
349
349
  "minimum": 1,
350
350
  "description": "Soft-warn threshold on acceptance[] item count (default 10)."
351
+ },
352
+ "mergeCandidateMaxFiles": {
353
+ "type": "integer",
354
+ "minimum": 1,
355
+ "description": "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)."
356
+ },
357
+ "mergeCandidateMaxAcceptance": {
358
+ "type": "integer",
359
+ "minimum": 1,
360
+ "description": "Under-size threshold (Story #4312): the acceptance[] item ceiling of the `merge-candidate` soft finding heuristic (default 4)."
351
361
  }
352
362
  },
353
363
  "additionalProperties": false
@@ -1502,6 +1512,34 @@
1502
1512
  }
1503
1513
  ]
1504
1514
  },
1515
+ "qaEnvironments": {
1516
+ "description": "Deployment targets the QA harness can run against (Epic #4326). A map keyed by environment name (e.g. `local`, `staging`), each carrying its own `baseUrl`, its own per-environment sign-in seam (the same url-template/skill union as `qaSignInSeam`), and an optional `allowWrites` gate. resolveQaEnvironment selects one environment per invocation by name or by raw-URL origin match against `baseUrl`; `allowWrites` defaults to true only for the `local` environment. Replaces the retired top-level single `signInSeam`.",
1517
+ "type": "object",
1518
+ "minProperties": 1,
1519
+ "additionalProperties": {
1520
+ "type": "object",
1521
+ "required": ["baseUrl", "signInSeam"],
1522
+ "additionalProperties": false,
1523
+ "properties": {
1524
+ "baseUrl": {
1525
+ "allOf": [
1526
+ {
1527
+ "$ref": "#/$defs/safeString"
1528
+ },
1529
+ {
1530
+ "minLength": 1
1531
+ }
1532
+ ]
1533
+ },
1534
+ "signInSeam": {
1535
+ "$ref": "#/$defs/qaSignInSeam"
1536
+ },
1537
+ "allowWrites": {
1538
+ "type": "boolean"
1539
+ }
1540
+ }
1541
+ }
1542
+ },
1505
1543
  "qaPersonas": {
1506
1544
  "description": "Personas the QA-harness sign-in seam accepts. Two accepted shapes: (1) a plain array of persona names \u2014 the honest shape for a `urlTemplate` dev-impersonation seam, where the persona name is the sole input the workflow consumes; (2) the object-map form keyed by persona name, where each entry carries per-persona auth material (`credentialRef` or `signInSkill`) consulted only under a `skill`/credential seam.",
1507
1545
  "oneOf": [
@@ -1565,7 +1603,7 @@
1565
1603
  },
1566
1604
  "qa": {
1567
1605
  "type": "object",
1568
- "description": "Agent-driven QA harness contract (Epic #3214). Optional top-level block. All filesystem-pointer fields (featureRoot, fixturesManifest, designTokens) carry safeString guards rejecting shell-injection metacharacters. signInSeam is a url-template/skill union; personas resolve to a stored credential reference or a sign-in skill, never an inline secret.",
1606
+ "description": "Agent-driven QA harness contract (Epic #3214; environment-keyed by Epic #4326). Optional top-level block. All filesystem-pointer fields (featureRoot, fixturesManifest, designTokens) carry safeString guards rejecting shell-injection metacharacters. environments is a map of named deployment targets (each with a baseUrl, a per-environment url-template/skill sign-in seam, and an optional allowWrites gate); personas resolve to a stored credential reference or a sign-in skill, never an inline secret.",
1569
1607
  "additionalProperties": false,
1570
1608
  "properties": {
1571
1609
  "featureRoot": {
@@ -1588,8 +1626,8 @@
1588
1626
  }
1589
1627
  ]
1590
1628
  },
1591
- "signInSeam": {
1592
- "$ref": "#/$defs/qaSignInSeam"
1629
+ "environments": {
1630
+ "$ref": "#/$defs/qaEnvironments"
1593
1631
  },
1594
1632
  "personas": {
1595
1633
  "$ref": "#/$defs/qaPersonas"
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "https://mandrel.dev/schemas/qa-ledger.schema.json",
4
4
  "title": "QaLedgerItem",
5
- "description": "Structured exploratory-QA ledger item (`f3-qa-explore-core`, Feature #3710, Epic #3686). One object per observation captured while exploring a consumer surface — distinct from a `qa-finding` (the browser-sweep `F#` finding): a ledger item classifies a broader exploratory signal (product bug, environment-setup friction, tooling/DX gap, test-coverage gap, or enhancement idea), records the evidence and coverage context, names any missing test, and carries the operator disposition so Triage can parse a whole session. A ledger item has a two-phase lifecycle: the read-only **Capture** phase appends an item with the Capture-phase fields populated (`id`, `class`, `severity`, `evidence`, `coverage`, `missingTest`) but no resolved `disposition`; the **Triage** phase later assigns the `disposition`. The schema therefore validates BOTH the captured-but-untriaged shape (`disposition` absent, `null`, or a `pending`/`untriaged` sentinel — the rolling backlog `.agents/scripts/lib/qa/qa-session.js` reads back on resume) AND the fully-triaged shape (`disposition` resolved to `file`/`defer`/`dismiss`), while still rejecting genuinely malformed items. Evidence MUST already be scrubbed of secrets, session tokens, and PII per `.agents/rules/security-baseline.md` before it is rendered here.",
5
+ "description": "Structured exploratory-QA ledger item (`f3-qa-explore-core`, Feature #3710, Epic #3686). One object per observation captured while exploring a consumer surface, and since Story #4330 unified `/qa-run` onto this ledger — one object per browser-sweep `F#` finding as well: a ledger item classifies an exploratory or sweep signal (product bug, environment-setup friction, tooling/DX gap, test-coverage gap, or enhancement idea), records the evidence and coverage context, names any missing test, and carries the operator disposition so Triage can parse a whole session. A ledger item has a two-phase lifecycle: the read-only **Capture** phase appends an item with the Capture-phase fields populated (`id`, `class`, `severity`, `evidence`, `coverage`, `missingTest`) but no resolved `disposition`; the **Triage** phase later assigns the `disposition`. The schema therefore validates BOTH the captured-but-untriaged shape (`disposition` absent, `null`, or a `pending`/`untriaged` sentinel — the rolling backlog `.agents/scripts/lib/qa/qa-session.js` reads back on resume) AND the fully-triaged shape (`disposition` resolved to `file`/`defer`/`dismiss`), while still rejecting genuinely malformed items. Evidence MUST already be scrubbed of secrets, session tokens, and PII per `.agents/rules/security-baseline.md` before it is rendered here.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "routedTo": {
66
66
  "type": "object",
67
- "description": "Optional finding-to-issue link recording where Triage routed this item. Populated only after the item is promoted to a follow-up ticket (`disposition: file`); omit while the item is still in Capture or was deferred/dismissed. The same link shape is mirrored on `qa-finding.schema.json`.",
67
+ "description": "Optional finding-to-issue link recording where Triage routed this item. Populated only after the item is promoted to a follow-up ticket (`disposition: file`); omit while the item is still in Capture or was deferred/dismissed.",
68
68
  "additionalProperties": false,
69
69
  "required": ["issue", "url", "kind"],
70
70
  "properties": {