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.
- package/.agents/README.md +18 -13
- package/.agents/audit-checklists/architecture.md +24 -0
- package/.agents/audit-checklists/clean-code.md +24 -0
- package/.agents/audit-checklists/dependencies.md +14 -0
- package/.agents/audit-checklists/devops.md +17 -0
- package/.agents/audit-checklists/documentation.md +22 -0
- package/.agents/audit-checklists/lighthouse.md +15 -0
- package/.agents/audit-checklists/navigability.md +14 -0
- package/.agents/audit-checklists/performance.md +22 -0
- package/.agents/audit-checklists/privacy.md +21 -0
- package/.agents/audit-checklists/quality.md +18 -0
- package/.agents/audit-checklists/security.md +22 -0
- package/.agents/audit-checklists/seo.md +16 -0
- package/.agents/audit-checklists/sre.md +24 -0
- package/.agents/audit-checklists/ux-ui.md +21 -0
- package/.agents/docs/SDLC.md +62 -27
- package/.agents/docs/configuration.md +5 -4
- package/.agents/instructions.md +51 -21
- package/.agents/personas/architect.md +10 -7
- package/.agents/personas/engineer.md +4 -3
- package/.agents/personas/project-manager.md +5 -2
- package/.agents/personas/refactorer.md +5 -3
- package/.agents/rules/git-conventions.md +77 -0
- package/.agents/schemas/agentrc.schema.json +10 -6
- package/.agents/schemas/audit-rules.json +16 -2
- package/.agents/schemas/audit-rules.schema.json +7 -6
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +39 -0
- package/.agents/schemas/signal-event.schema.json +28 -13
- package/.agents/scripts/acceptance-spec-reconciler.js +6 -4
- package/.agents/scripts/check-context-budget.js +320 -0
- package/.agents/scripts/coverage-capture.js +17 -0
- package/.agents/scripts/diagnose-friction.js +4 -4
- package/.agents/scripts/epic-audit-prepare.js +30 -2
- package/.agents/scripts/epic-audit-recheck.js +46 -13
- package/.agents/scripts/epic-deliver-prepare.js +80 -8
- package/.agents/scripts/epic-plan-spec.js +4 -8
- package/.agents/scripts/generate-lens-checklists.js +180 -0
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +300 -0
- package/.agents/scripts/lib/audit-suite/findings.js +27 -0
- package/.agents/scripts/lib/audit-suite/index.js +9 -0
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +212 -0
- package/.agents/scripts/lib/audit-suite/selector.js +136 -5
- package/.agents/scripts/lib/checks/loop-health.js +340 -0
- package/.agents/scripts/lib/cli-args.js +8 -0
- package/.agents/scripts/lib/close-validation/gates.js +64 -24
- package/.agents/scripts/lib/config/ci.js +12 -1
- package/.agents/scripts/lib/config/runners.js +13 -5
- package/.agents/scripts/lib/config/temp-paths.js +24 -0
- package/.agents/scripts/lib/config-settings-schema-delivery.js +28 -8
- package/.agents/scripts/lib/doc-tiers.js +291 -0
- package/.agents/scripts/lib/epic-body-sections.js +5 -2
- package/.agents/scripts/lib/epic-merge-lock.js +83 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +3 -1
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +47 -15
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +395 -86
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +299 -72
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +438 -0
- package/.agents/scripts/lib/gates/friction.js +15 -5
- package/.agents/scripts/lib/npm-scripts.js +55 -0
- package/.agents/scripts/lib/observability/perf-aggregator.js +30 -104
- package/.agents/scripts/lib/observability/perf-report-readers.js +1 -1
- package/.agents/scripts/lib/observability/signal-validator.js +204 -0
- package/.agents/scripts/lib/observability/signals-writer.js +157 -54
- package/.agents/scripts/lib/observability/tool-trace-hook.js +42 -4
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +1 -1
- package/.agents/scripts/lib/orchestration/code-review.js +74 -4
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +213 -0
- package/.agents/scripts/lib/orchestration/doc-reader.js +4 -96
- package/.agents/scripts/lib/orchestration/docs-digest.js +34 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +56 -19
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +22 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +193 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +6 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -13
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +109 -12
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +47 -61
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +46 -4
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +144 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +258 -14
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +6 -0
- package/.agents/scripts/lib/orchestration/merge-block-class.js +246 -0
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +1 -1
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -3
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +63 -34
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +167 -52
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +49 -2
- package/.agents/scripts/lib/orchestration/retro-proposals.js +12 -55
- package/.agents/scripts/lib/orchestration/retro-runner.js +9 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +5 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +419 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +35 -2
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +353 -69
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +66 -4
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +60 -9
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +7 -5
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +24 -2
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +167 -8
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +8 -1
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +163 -0
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +20 -9
- package/.agents/scripts/lib/planning-corpus.js +306 -0
- package/.agents/scripts/lib/signals/detectors/common.js +10 -10
- package/.agents/scripts/lib/signals/detectors/index.js +4 -4
- package/.agents/scripts/lib/signals/detectors/retry.js +19 -18
- package/.agents/scripts/lib/signals/detectors/rework.js +1 -1
- package/.agents/scripts/lib/signals/schema.js +56 -81
- package/.agents/scripts/lib/signals/span-tree.js +6 -5
- package/.agents/scripts/lib/story-plan.js +3 -0
- package/.agents/scripts/lib/wave-runner/tick.js +10 -2
- package/.agents/scripts/lifecycle-emit.js +39 -8
- package/.agents/scripts/providers/github/issues.js +12 -1
- package/.agents/scripts/resolve-doc-tiers.js +83 -0
- package/.agents/scripts/retro-run.js +51 -0
- package/.agents/scripts/signals-view.js +1 -1
- package/.agents/scripts/single-story-close.js +20 -1
- package/.agents/scripts/standalone-feedback-rollup.js +188 -0
- package/.agents/scripts/story-close.js +48 -0
- package/.agents/scripts/story-plan.js +51 -12
- package/.agents/scripts/validate-docs-freshness.js +69 -15
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +58 -0
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +5 -3
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +20 -7
- package/.agents/skills/core/scope-triage/SKILL.md +61 -0
- package/.agents/skills/skills.index.json +3 -3
- package/.agents/workflows/audit-documentation.md +82 -2
- package/.agents/workflows/helpers/code-review.md +116 -43
- package/.agents/workflows/helpers/deliver-epic.md +123 -54
- package/.agents/workflows/helpers/deliver-stories.md +26 -0
- package/.agents/workflows/helpers/epic-audit.md +116 -366
- package/.agents/workflows/helpers/epic-deliver-story.md +14 -0
- package/.agents/workflows/helpers/epic-plan-decompose.md +18 -200
- package/.agents/workflows/helpers/epic-plan-spec.md +18 -180
- package/.agents/workflows/helpers/plan-epic.md +141 -105
- package/.agents/workflows/helpers/plan-story.md +32 -0
- package/.agents/workflows/helpers/single-story-deliver.md +43 -0
- package/.agents/workflows/loops/nightly-audit.md +9 -7
- package/docs/CHANGELOG.md +29 -0
- package/lib/cli/doctor.js +44 -0
- package/package.json +4 -3
- package/.agents/scripts/epic-plan-spec-validate.js +0 -111
- package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +0 -224
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +0 -58
- 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,
|
|
5
|
-
|
|
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-
|
|
40
|
-
→ Phase 5 — code-review (helpers/code-review.md
|
|
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
|
|
182
|
-
Story); the ready-set `tick` (Phase 2) decides
|
|
183
|
-
beat. `
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
lens
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
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
|
-
- **`
|
|
519
|
-
|
|
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> }
|
|
530
|
-
|
|
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
|
-
|
|
547
|
-
(Story #
|
|
548
|
-
**`medium`**
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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
|
|