mandrel 1.88.0 → 1.90.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 (145) hide show
  1. package/.agents/README.md +18 -13
  2. package/.agents/audit-checklists/architecture.md +24 -0
  3. package/.agents/audit-checklists/clean-code.md +24 -0
  4. package/.agents/audit-checklists/dependencies.md +14 -0
  5. package/.agents/audit-checklists/devops.md +17 -0
  6. package/.agents/audit-checklists/documentation.md +22 -0
  7. package/.agents/audit-checklists/lighthouse.md +15 -0
  8. package/.agents/audit-checklists/navigability.md +14 -0
  9. package/.agents/audit-checklists/performance.md +22 -0
  10. package/.agents/audit-checklists/privacy.md +21 -0
  11. package/.agents/audit-checklists/quality.md +18 -0
  12. package/.agents/audit-checklists/security.md +22 -0
  13. package/.agents/audit-checklists/seo.md +16 -0
  14. package/.agents/audit-checklists/sre.md +24 -0
  15. package/.agents/audit-checklists/ux-ui.md +21 -0
  16. package/.agents/docs/SDLC.md +62 -27
  17. package/.agents/docs/configuration.md +5 -4
  18. package/.agents/instructions.md +51 -21
  19. package/.agents/personas/architect.md +10 -7
  20. package/.agents/personas/engineer.md +4 -3
  21. package/.agents/personas/project-manager.md +5 -2
  22. package/.agents/personas/refactorer.md +5 -3
  23. package/.agents/rules/git-conventions.md +77 -0
  24. package/.agents/schemas/agentrc.schema.json +10 -6
  25. package/.agents/schemas/audit-rules.json +16 -2
  26. package/.agents/schemas/audit-rules.schema.json +7 -6
  27. package/.agents/schemas/lifecycle/epic.blocked.schema.json +1 -1
  28. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +39 -0
  29. package/.agents/schemas/signal-event.schema.json +28 -13
  30. package/.agents/scripts/acceptance-spec-reconciler.js +6 -4
  31. package/.agents/scripts/check-context-budget.js +320 -0
  32. package/.agents/scripts/coverage-capture.js +17 -0
  33. package/.agents/scripts/diagnose-friction.js +4 -4
  34. package/.agents/scripts/epic-audit-prepare.js +30 -2
  35. package/.agents/scripts/epic-audit-recheck.js +46 -13
  36. package/.agents/scripts/epic-deliver-prepare.js +80 -8
  37. package/.agents/scripts/epic-plan-spec.js +4 -8
  38. package/.agents/scripts/generate-lens-checklists.js +180 -0
  39. package/.agents/scripts/lib/audit-suite/checklist-threading.js +300 -0
  40. package/.agents/scripts/lib/audit-suite/findings.js +27 -0
  41. package/.agents/scripts/lib/audit-suite/index.js +9 -0
  42. package/.agents/scripts/lib/audit-suite/lens-checklist.js +212 -0
  43. package/.agents/scripts/lib/audit-suite/selector.js +136 -5
  44. package/.agents/scripts/lib/checks/loop-health.js +340 -0
  45. package/.agents/scripts/lib/cli-args.js +8 -0
  46. package/.agents/scripts/lib/close-validation/gates.js +64 -24
  47. package/.agents/scripts/lib/config/ci.js +12 -1
  48. package/.agents/scripts/lib/config/runners.js +13 -5
  49. package/.agents/scripts/lib/config/temp-paths.js +24 -0
  50. package/.agents/scripts/lib/config-settings-schema-delivery.js +28 -8
  51. package/.agents/scripts/lib/doc-tiers.js +291 -0
  52. package/.agents/scripts/lib/epic-body-sections.js +5 -2
  53. package/.agents/scripts/lib/epic-merge-lock.js +83 -0
  54. package/.agents/scripts/lib/epic-plan-clarity.js +3 -1
  55. package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +47 -15
  56. package/.agents/scripts/lib/feedback-loop/graduator-core.js +395 -86
  57. package/.agents/scripts/lib/feedback-loop/memory-freshness.js +299 -72
  58. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +438 -0
  59. package/.agents/scripts/lib/gates/friction.js +15 -5
  60. package/.agents/scripts/lib/npm-scripts.js +55 -0
  61. package/.agents/scripts/lib/observability/perf-aggregator.js +30 -104
  62. package/.agents/scripts/lib/observability/perf-report-readers.js +1 -1
  63. package/.agents/scripts/lib/observability/signal-validator.js +204 -0
  64. package/.agents/scripts/lib/observability/signals-writer.js +157 -54
  65. package/.agents/scripts/lib/observability/tool-trace-hook.js +42 -4
  66. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +1 -1
  67. package/.agents/scripts/lib/orchestration/code-review.js +74 -4
  68. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +213 -0
  69. package/.agents/scripts/lib/orchestration/doc-reader.js +4 -96
  70. package/.agents/scripts/lib/orchestration/docs-digest.js +34 -0
  71. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +56 -19
  72. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +22 -0
  73. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +193 -0
  74. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +6 -0
  75. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -13
  76. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +109 -12
  77. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +47 -61
  78. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +46 -4
  79. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +144 -0
  80. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +258 -14
  81. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +6 -0
  82. package/.agents/scripts/lib/orchestration/merge-block-class.js +246 -0
  83. package/.agents/scripts/lib/orchestration/plan-review-routing.js +1 -1
  84. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -3
  85. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +63 -34
  86. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +167 -52
  87. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +49 -2
  88. package/.agents/scripts/lib/orchestration/retro-proposals.js +12 -55
  89. package/.agents/scripts/lib/orchestration/retro-runner.js +9 -0
  90. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +5 -1
  91. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -0
  92. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +419 -0
  93. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +35 -2
  94. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +353 -69
  95. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +66 -4
  96. package/.agents/scripts/lib/orchestration/spec-section-validator.js +60 -9
  97. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +7 -5
  98. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +24 -2
  99. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +167 -8
  100. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +8 -1
  101. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +163 -0
  102. package/.agents/scripts/lib/orchestration/ticketing/reads.js +20 -9
  103. package/.agents/scripts/lib/planning-corpus.js +306 -0
  104. package/.agents/scripts/lib/signals/detectors/common.js +10 -10
  105. package/.agents/scripts/lib/signals/detectors/index.js +4 -4
  106. package/.agents/scripts/lib/signals/detectors/retry.js +19 -18
  107. package/.agents/scripts/lib/signals/detectors/rework.js +1 -1
  108. package/.agents/scripts/lib/signals/schema.js +56 -81
  109. package/.agents/scripts/lib/signals/span-tree.js +6 -5
  110. package/.agents/scripts/lib/story-plan.js +3 -0
  111. package/.agents/scripts/lib/wave-runner/tick.js +10 -2
  112. package/.agents/scripts/lifecycle-emit.js +39 -8
  113. package/.agents/scripts/providers/github/issues.js +12 -1
  114. package/.agents/scripts/resolve-doc-tiers.js +83 -0
  115. package/.agents/scripts/retro-run.js +51 -0
  116. package/.agents/scripts/signals-view.js +1 -1
  117. package/.agents/scripts/single-story-close.js +20 -1
  118. package/.agents/scripts/standalone-feedback-rollup.js +188 -0
  119. package/.agents/scripts/story-close.js +48 -0
  120. package/.agents/scripts/story-plan.js +51 -12
  121. package/.agents/scripts/validate-docs-freshness.js +69 -15
  122. package/.agents/skills/core/documentation-and-adrs/SKILL.md +58 -0
  123. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +5 -3
  124. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +20 -7
  125. package/.agents/skills/core/scope-triage/SKILL.md +61 -0
  126. package/.agents/skills/skills.index.json +3 -3
  127. package/.agents/workflows/audit-documentation.md +82 -2
  128. package/.agents/workflows/helpers/code-review.md +116 -43
  129. package/.agents/workflows/helpers/deliver-epic.md +123 -54
  130. package/.agents/workflows/helpers/deliver-stories.md +26 -0
  131. package/.agents/workflows/helpers/epic-audit.md +116 -366
  132. package/.agents/workflows/helpers/epic-deliver-story.md +14 -0
  133. package/.agents/workflows/helpers/epic-plan-decompose.md +18 -200
  134. package/.agents/workflows/helpers/epic-plan-spec.md +18 -180
  135. package/.agents/workflows/helpers/plan-epic.md +141 -105
  136. package/.agents/workflows/helpers/plan-story.md +32 -0
  137. package/.agents/workflows/helpers/single-story-deliver.md +43 -0
  138. package/.agents/workflows/loops/nightly-audit.md +9 -7
  139. package/docs/CHANGELOG.md +29 -0
  140. package/lib/cli/doctor.js +44 -0
  141. package/package.json +4 -3
  142. package/.agents/scripts/epic-plan-spec-validate.js +0 -111
  143. package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +0 -224
  144. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +0 -58
  145. package/.agents/scripts/lib/signals/detectors/hotspot.js +0 -292
@@ -1,8 +1,10 @@
1
1
  ---
2
2
  description: >-
3
3
  Drive an Epic from `agent::ready` to a merged pull request against `main`.
4
- The ten-phase flow runs the wave loop, close-validation, epic-audit,
5
- code-review, retro, finalize, watch-and-iterate, conditional auto-merge,
4
+ The ten-phase flow runs the wave loop, close-validation, the Epic-close
5
+ lens-roster resolve, the code-review pass (which walks the cumulative diff
6
+ once with the lens roster folded in), retro, finalize, watch-and-iterate,
7
+ conditional auto-merge,
6
8
  and local branch cleanup. When the run is end-to-end clean (zero manual
7
9
  interventions, zero 🔴/🟠 review findings, compact retro) the PR
8
10
  auto-merges via `gh pr merge --squash --delete-branch`; otherwise the
@@ -36,8 +38,8 @@ back to the operator-merges-button path.
36
38
  → Phase 1 — prepare (epic-deliver-prepare.js)
37
39
  → Phase 2 — ready-set loop (wave-tick.js → dispatch ready set → observe → re-tick)
38
40
  → Phase 3 — close-validation (lint + test + ratchets on epic/<id>)
39
- → Phase 4 — epic-audit (helpers/epic-audit.md — change-set audits via selectAudits)
40
- → Phase 5 — code-review (helpers/code-review.md with scope: epic)
41
+ → Phase 4 — epic-close lens roster (helpers/epic-audit.md — resolve the slim cumulative+global+risk-routed roster)
42
+ → Phase 5 — code-review (helpers/code-review.md scope: epic — walks the cumulative diff once, lens roster folded in)
41
43
  → Phase 6 — retro (.agents/scripts/lib/orchestration/retro-runner.js)
42
44
  → Phase 6.5 — integration gate (whole-product navigability + journey suite; @pending ≠ green for surface-adding Epics — blocks finalize)
43
45
  → Phase 7 — finalize (lifecycle-emit → epic.close.end → open PR to main)
@@ -81,6 +83,19 @@ spawned.
81
83
  Every other runtime modifier is sourced from the Epic's labels or from
82
84
  `delivery.deliverRunner` in `.agentrc.json`.
83
85
 
86
+ - `--yes` — the top-level `/deliver` unattended flag (suppresses the
87
+ operator confirmation gate; see [`deliver.md`](../deliver.md)). This
88
+ helper reads it as the **headless signal** for Phase 8.5's must-land
89
+ terminal step (Story #4427): when `/deliver` was invoked with `--yes`,
90
+ thread `--headless true` into the Phase 8.5
91
+ `epic.automerge.start` `lifecycle-emit.js` call (omit the flag, or
92
+ pass `--headless false`, for an attended run). The runtime reads this
93
+ as an explicit `headless` input threaded through
94
+ `runLifecycleEmit` → `buildDefaultListenerChain` →
95
+ `MergeWatcher({ headless })` — never an ambient/undefined global.
96
+ Attended-mode behavior (no `--headless` flag) is byte-for-byte
97
+ unchanged: `MergeWatcher` defaults `headless` to `false`.
98
+
84
99
  ---
85
100
 
86
101
  ## Contract
@@ -178,9 +193,14 @@ Validates `type::epic`, enumerates `type::story` descendants, parses
178
193
  checkpoint in the per-Story-status shape (a flat `stories` map seeded at
179
194
  `pending`, plus the global `concurrencyCap`). Treat the printed JSON as
180
195
  `state`: `{ epicId, storyCount, concurrencyCap, stories, checkpointInitializedAt, docsDigestPath }`.
181
- `stories` is the flat dispatch hint (`{ storyId, worktree, title }` per open
182
- Story); the ready-set `tick` (Phase 2) decides which to dispatch on each
183
- beat. `docsDigestPath` is the repo-relative path to the per-Epic docs digest
196
+ `stories` is the flat dispatch hint (`{ storyId, worktree, title,
197
+ checklistPath }` per open Story); the ready-set `tick` (Phase 2) decides
198
+ which to dispatch on each beat. `checklistPath` is the repo-relative path to
199
+ that Story's footprint-matched local-lens authoring checklist
200
+ (`temp/epic-<epicId>/checklists/story-<storyId>.md`, Story #4410) — thread it
201
+ into that child's prompt (§ 2b, item 7); it is `null` when the Story's
202
+ predicted footprint matched no local lens. `docsDigestPath` is the
203
+ repo-relative path to the per-Epic docs digest
184
204
  (`temp/epic-<epicId>/docs-digest.md`) that prepare writes from
185
205
  `project.docsContextFiles` — thread it into every child prompt (§ 2b, item 6).
186
206
  It is `null` when the project configured no `docsContextFiles` (no digest is
@@ -369,7 +389,14 @@ digest instead of re-reading the full `project.docsContextFiles` set,
369
389
  and to pull individual docs files on demand (per
370
390
  [`.agents/instructions.md` § 3](../../instructions.md)). When
371
391
  `docsDigestPath` is null (the project configured no `docsContextFiles`),
372
- say so — the child then has no per-Story docs mandate. The pairing of
392
+ say so — the child then has no per-Story docs mandate. (7) pass the
393
+ **checklist path** — the `checklistPath` field from that Story's entry in
394
+ the `stories` dispatch hint (Story #4410), which points at
395
+ `temp/epic-<epicId>/checklists/story-<storyId>.md`. Instruct the child to
396
+ read that file (footprint-matched local-lens authoring checklists) and
397
+ self-check its change against those concerns while writing. When
398
+ `checklistPath` is null (the Story's predicted footprint matched no local
399
+ lens), there is nothing to read. The pairing of
373
400
  `story.heartbeat` and `agent::blocked` is what lets the § 2d Idle
374
401
  Watchdog distinguish a working child from a dead one; a silent child
375
402
  with no recent heartbeat and no blocker label is the failure mode the
@@ -473,61 +500,61 @@ the Epic branch; if any drifts, refresh and commit
473
500
 
474
501
  ---
475
502
 
476
- ## Phase 4 — Epic audit (change-set lenses)
503
+ ## Phase 4 — Epic-close lens roster
477
504
 
478
505
  Skip when `--skip-epic-audit`. Otherwise auto-invoke
479
- [`helpers/epic-audit.md`](epic-audit.md) inline. The helper runs
506
+ [`helpers/epic-audit.md`](epic-audit.md) inline to **resolve** (not walk) the
507
+ slim Epic-close lens roster. The helper runs
480
508
  [`epic-audit-prepare.js`](../../scripts/epic-audit-prepare.js) to ask the
481
509
  [`selectAudits`](../../scripts/lib/audit-suite/index.js) SDK which lenses fire
482
510
  at the `gate3` close gate, **unions in the model-judged risk-routed lenses**
483
511
  (Story #3889 — `epic-audit-prepare.js` reads the Epic's `planningRisk`
484
512
  envelope off the `epic-plan-state` checkpoint and maps each high-risk axis to
485
- its lens via `resolveAuditLenses`), then dispatches each selected lens through
486
- [`runAuditSuite`](../../scripts/lib/audit-suite/index.js). A high-risk Epic
487
- therefore auto-runs its mapped lenses (e.g. a `security`-axis Epic runs
488
- `audit-security`) even when the change set alone did not select them; a
489
- low-risk Epic adds nothing. Findings are persisted as an `audit-results`
490
- structured comment on the Epic.
491
-
492
- The helper's Step 3 remediation is **threshold-aware** (Story #4399): it
493
- reads `delivery.epicAudit.autoFixSeverity` (default **`medium`**) and, at
494
- `medium`, routes 🔴/🟠/**🟡** findings into on-branch remediation (Mediums
495
- batched per lens — one commit per lens, a single validation + overlapping-
496
- lens rescan at the end) while 🟢 Suggestions still graduate; `high`
497
- reproduces the pre-4399 Critical/High-only routing. Remediated findings are
498
- rendered under the comment's `## Fixed on-branch` section so they never
499
- graduate to follow-up issues. The severity gate below is **unchanged** —
500
- it keys off the surviving (unfixed) findings.
501
-
502
- The helper walks the selected roster **serially in-context by default**; when
503
- the roster carries more than one lens it **may delegate the walk to a single
504
- audit-orchestrator sub-agent** that fans the already-selected lenses out as
505
- parallel level-2 agents and returns only the aggregated `audit-results` (see
506
- [`epic-audit.md` § "Optional: delegate the roster walk to an audit-orchestrator
507
- sub-agent"](epic-audit.md), within the sub-agent depth budget noted under
508
- "Flat Story dispatch by design" above). The roster stays fixed upstream, every
509
- per-lens cost gate is preserved, and the seven sequential-only lenses are **not**
510
- batch-converted — the fan-out parallelizes across lenses only and never changes
511
- how any single lens runs internally.
513
+ its lens via `resolveAuditLenses`), then restricts that union to the tiers the
514
+ Epic-close tier owns via
515
+ [`selectEpicCloseLenses`](../../scripts/lib/orchestration/code-review.js): the
516
+ envelope's **`epicCloseLenses`** field is the slim roster of **cumulative +
517
+ global + risk-routed** lenses, with every **local-tier** change-set lens
518
+ excluded (its concern is already verified shift-left at the write-time and
519
+ Story-scope tiers). A high-risk Epic still auto-runs its risk-routed lenses
520
+ even when the change set alone did not select them; a docs-only or
521
+ already-shift-left-covered change set yields an empty roster.
522
+
523
+ **The lens roster is not walked here.** Story #4412 folded the standalone
524
+ Phase 4 lens walk into the Phase 5 code-review pass so the cumulative Epic diff
525
+ is walked **once**. Phase 4 resolves `epicCloseLenses` (plus `depth`,
526
+ `globalLenses`, `substitutionsPayload`) and hands it to Phase 5; there is no
527
+ separate `audit-results` comment. Remediation of the lens findings happens in
528
+ Phase 5 and is **tier-aware** (Story #4412): the Epic-close tier reads
529
+ `delivery.epicAudit.autoFixSeverity` (default **`high`**) and routes only
530
+ 🔴 Critical + 🟠 High lens findings into on-branch remediation while 🟡 Medium
531
+ and 🟢 Suggestion findings graduate (🟡 Medium concerns are already remediated
532
+ shift-left); setting `medium` opts back into routing 🔴/🟠/🟡.
512
533
 
513
- - **Any surviving 🔴 Critical Blocker** — STOP. Relay to the operator.
514
- - **Only 🟠/🟡/🟢 surviving** — log as non-blocking and continue.
515
534
  - **Selector reports `degraded: true`** — STOP. Propagate the
516
535
  `reason`/`detail`, post a friction comment, do not fall back to a
517
536
  full-roster audit.
518
- - **`selectedAudits` is empty** (docs-only change set) — log the
519
- short-circuit and continue to Phase 5.
537
+ - **`epicCloseLenses` is empty** (docs-only change set, or every selected lens
538
+ already covered shift-left, and no risk-routed lens) — there is no lens
539
+ dimension for Phase 5 to walk; continue to Phase 5, which still runs its
540
+ review pillars.
520
541
 
521
542
  ---
522
543
 
523
- ## Phase 5 — Code review
544
+ ## Phase 5 — Code review (cumulative diff walked once)
524
545
 
525
546
  Skip when `--skip-code-review`. Otherwise resolve the **risk-derived review
526
547
  depth** for this Epic, then auto-invoke
527
548
  [`helpers/code-review.md`](code-review.md) inline (read-only audit)
528
549
  with the argument envelope `{ scope: 'epic', ticketId: <epicId>, baseRef:
529
- 'main', headRef: 'epic/<epicId>', depth: <reviewDepth> }`. The helper
530
- persists findings as a `code-review` structured comment on the Epic.
550
+ 'main', headRef: 'epic/<epicId>', depth: <reviewDepth> }`, threading the
551
+ Phase 4 `epicCloseLenses` roster through. The pass walks the cumulative
552
+ `main..epic/<epicId>` diff **once**: it executes the Epic-close lens roster as
553
+ review dimensions (helper Step 1b) **and** the review pillars, folding both
554
+ into a single aggregate. Findings persist as the unified `verification-results`
555
+ structured comment on the Epic (the single findings surface — Story #4411
556
+ unified the former `code-review` and `audit-results` contracts, and Story #4412
557
+ folded the lens walk into this pass).
531
558
 
532
559
  The `depth` is the live epic-scope producer for Story #3876's review-depth
533
560
  lever (Story #3937). Resolve it from the Epic's judged risk envelope the same
@@ -543,14 +570,16 @@ emit so a high-risk Epic gets a deeper adversarial pass and a low-risk one a
543
570
  lighter one. Depth is **input-only** — it never changes the findings envelope
544
571
  or the posted comment shape.
545
572
 
546
- The helper's Step 4.5 focused-fix routing is **threshold-aware**
547
- (Story #4399): it reads `delivery.codeReview.autoFixSeverity` (default
548
- **`medium`**) and, at `medium`, routes 🔴/🟠/**🟡** findings into on-branch
549
- remediation (Mediums batched per lens — one commit per lens, a single
550
- validation + rescan at the end) while 🟢 Suggestions stay on the comment;
551
- `high` reproduces the pre-4399 Critical/High-only routing. Remediated
552
- findings are rendered under the comment's `## Fixed on-branch` section so
553
- they never graduate to follow-up issues. The severity gate below is
573
+ Remediation in this pass is **tier-aware and split by finding class**
574
+ (Story #4412). The **review-pillar** findings (Pillars 1–4) route off
575
+ `delivery.codeReview.autoFixSeverity` (default **`medium`** — 🔴/🟠/🟡
576
+ on-branch, Mediums batched per lens, 🟢 stays on the comment). The **Epic-close
577
+ lens** findings (Step 1b) route off `delivery.epicAudit.autoFixSeverity`
578
+ (default **`high`** — only 🔴/🟠 on-branch; 🟡 Medium + 🟢 graduate, because
579
+ 🟡 Medium concerns were already remediated shift-left). Setting either key to
580
+ its other value re-widens or narrows that class. Remediated findings are
581
+ rendered under the single `verification-results` comment's `## Fixed on-branch`
582
+ section so they never graduate to follow-up issues. The severity gate below is
554
583
  **unchanged** — it keys off the surviving (unfixed) findings.
555
584
 
556
585
  - **Any surviving 🔴 Critical Blocker** — STOP. Relay to the operator.
@@ -585,6 +614,23 @@ the GitHub upsert succeeds, the retro body is also **mirrored locally** to
585
614
  `epicRetroMirrorPath`). GitHub remains the source of truth — a
586
615
  mirror-write failure only logs a warn and never fails the phase.
587
616
 
617
+ **Auto-file routed proposals (Story #4418).** Between gathering the retro
618
+ signals and composing the body, the runner files the retro's **actionable
619
+ routed proposals** (the `framework` / `consumer` friction categories that
620
+ recurred ≥ 2× or were force-flagged by an unresolved `agent::blocked`) as
621
+ GitHub follow-up issues via the graduator pre-parsed-findings seam
622
+ ([`retro-proposals-graduator.js`](../../scripts/lib/feedback-loop/retro-proposals-graduator.js)).
623
+ Each filed issue carries `meta::<framework-gap|consumer-improvement>` +
624
+ `friction::<category>` labels — the join key `/plan` Phase 0's
625
+ prior-feedback fetcher reads back — and the rendered retro sections then
626
+ list the **real filed issue numbers** instead of paste-ready `gh issue
627
+ create` command stanzas. Filing is idempotent (a content-hash marker probe
628
+ skips already-filed categories) and respects the graduator per-run filing
629
+ cap. The beat runs behind `delivery.feedbackLoop.retroProposals` (default
630
+ **ON**); set it to `false` to suppress auto-filing and fall back to the
631
+ command stanzas. Filing never fails the phase — a filing error degrades to
632
+ the command stanzas.
633
+
588
634
  ---
589
635
 
590
636
  ## Phase 6.5 — Post-wave integration gate (Epic #4131, F1/F4)
@@ -740,13 +786,36 @@ run. Passing `--epic <epicId>` scopes the red-path failure digest to
740
786
  ## Phase 8.5 — Auto-merge gate
741
787
 
742
788
  After Phase 8 exits 0, evaluate the auto-merge predicate by emitting
743
- `epic.automerge.start`:
789
+ `epic.automerge.start`. When this `/deliver` run was invoked with `--yes`,
790
+ add `--headless true` so the downstream `MergeWatcher` engages the
791
+ must-land terminal step (Story #4427, § Arguments above); omit the flag
792
+ (or pass `--headless false`) for an attended run:
744
793
 
745
794
  ```bash
746
795
  node .agents/scripts/lifecycle-emit.js --epic <epicId> \
747
- --event epic.automerge.start --pr-url <prUrl>
796
+ --event epic.automerge.start --pr-url <prUrl> [--headless true]
748
797
  ```
749
798
 
799
+ **Must-land terminal step (headless only).** `MergeWatcher` polls
800
+ `epic.merge.armed` to confirmation as usual. If its poll budget is
801
+ exhausted, a headless (`--headless true`) run does not exit silently —
802
+ it classifies the block (`classifyMergeBlock`, the shared classifier
803
+ from Story #4426) and applies one bounded retry before giving up:
804
+
805
+ - `checks-pending-timeout` (required checks still progressing) — extend
806
+ the watch budget once and keep polling.
807
+ - `api-race-other` (no definitive block signal) — re-arm once by
808
+ re-emitting `epic.merge.ready` on the bus (never a direct `gh pr merge`
809
+ call — `AutomergeArmer` remains the sole authorized call site).
810
+ - `branch-protection-human-required`, or both bounded retries already
811
+ spent — terminal: emit `merge.unlanded` (`scope: "epic"`, carrying the
812
+ block class) and fall through to the existing single `epic.blocked`
813
+ emit — one blocked path, never a duplicate `agent::blocked` transition.
814
+
815
+ Attended runs (no `--headless` flag) keep today's exact behavior: budget
816
+ exhaustion emits `epic.blocked` immediately, with no classification, no
817
+ retry, and no `merge.unlanded`.
818
+
750
819
  `AutomergePredicate` first runs a **live `gh pr checks --required` probe**
751
820
  (Story #4361): green required CI is the arming signal, so if any required
752
821
  check is red, pending, or the probe is unreadable it emits
@@ -336,6 +336,32 @@ auto-merge. Report its one-line result in the summary. Merged Story branches
336
336
  themselves are reaped by the boot sweep at the next `/plan` / `/deliver` boot —
337
337
  see [`.agents/rules/git-conventions.md` § Local checkout hygiene](../../rules/git-conventions.md).
338
338
 
339
+ ### Feedback rollup
340
+
341
+ Then run the **end-of-run feedback rollup** over the delivered Story set so
342
+ the write-only standalone signals tree finally has a consumer. Each per-Story
343
+ sub-agent appends `friction` records to its standalone stream
344
+ (`temp/standalone/stories/story-<sid>/signals.ndjson`); the rollup scans those
345
+ streams and aggregates friction by category:
346
+
347
+ ```bash
348
+ node .agents/scripts/standalone-feedback-rollup.js --stories <all delivered story ids, comma-separated>
349
+ ```
350
+
351
+ The CLI prints one JSON object
352
+ (`{ kind, stories, totalFriction, byCategory, perStory }`) and **always exits
353
+ 0** — missing or empty streams degrade to an empty summary, so this beat never
354
+ fails the run. Surface `totalFriction` and the `byCategory` totals in the run
355
+ summary so the operator sees where friction clustered across the delivery:
356
+
357
+ ```text
358
+ Feedback rollup — 4 friction signals across 3 Stories
359
+ Execution Error: 2, Tool Limitation: 1, Missing Skill: 1
360
+ ```
361
+
362
+ When `totalFriction` is 0 (or every stream was missing), report a single
363
+ "no friction signals recorded" line and move on — it is not an error.
364
+
339
365
  When some Stories are blocked or failed, list them explicitly with the
340
366
  `blockerCommentId` or failure detail so the operator knows where to look.
341
367