mandrel 1.94.0 → 2.0.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 +59 -73
- package/.agents/agents/story-worker.md +12 -13
- package/.agents/docs/SDLC.md +489 -1285
- package/.agents/docs/agentrc-reference.json +177 -67
- package/.agents/docs/configuration.md +104 -138
- package/.agents/docs/execution-reference.md +17 -20
- package/.agents/docs/quality-gates.md +13 -19
- package/.agents/docs/workflows.md +3 -3
- package/.agents/instructions.md +70 -81
- package/.agents/rules/ci-remediation.md +8 -12
- package/.agents/rules/git-conventions-reference.md +6 -7
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +54 -214
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/risk-verdict.schema.json +0 -13
- package/.agents/scripts/analyze-execution.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/check-lifecycle-lint.js +6 -9
- package/.agents/scripts/check-prepush-recovery.js +1 -1
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/lib/Logger.js +6 -10
- package/.agents/scripts/lib/audit-suite/runner.js +2 -2
- package/.agents/scripts/lib/audit-suite/selector.js +5 -5
- package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
- package/.agents/scripts/lib/baselines/kernel.js +206 -18
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -4
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/checks/core-bare-clean.js +2 -2
- package/.agents/scripts/lib/checks/index.js +2 -1
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +23 -21
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +16 -7
- package/.agents/scripts/lib/close-validation/gates.js +2 -2
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +45 -29
- package/.agents/scripts/lib/config/explain.js +55 -36
- package/.agents/scripts/lib/config/limits.js +17 -58
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +1 -1
- package/.agents/scripts/lib/config/runners.js +17 -50
- package/.agents/scripts/lib/config/temp-paths.js +19 -14
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +2 -7
- package/.agents/scripts/lib/config-settings-schema-delivery.js +24 -148
- package/.agents/scripts/lib/config-settings-schema-quality.js +8 -14
- package/.agents/scripts/lib/config-settings-schema.js +52 -38
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +2 -2
- package/.agents/scripts/lib/duplicate-search.js +211 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +5 -5
- package/.agents/scripts/lib/framework-version.js +2 -3
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -22
- package/.agents/scripts/lib/git-utils.js +32 -6
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/label-constants.js +10 -23
- package/.agents/scripts/lib/label-taxonomy.js +9 -43
- package/.agents/scripts/lib/observability/active-story-env.js +1 -1
- package/.agents/scripts/lib/observability/hook-heartbeat.js +20 -52
- package/.agents/scripts/lib/observability/source-classifier.js +3 -3
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +8 -5
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +83 -20
- package/.agents/scripts/lib/orchestration/code-review.js +20 -268
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +1 -1
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
- package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +8 -8
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +2 -2
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +17 -43
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +1 -1
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +248 -266
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +1 -1
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +61 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +97 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +223 -854
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +361 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +35 -108
- package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +13 -13
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/risk-verdict.js +3 -4
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +2 -2
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +8 -20
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +3 -2
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/preflight-cache.js +5 -5
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +155 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +8 -8
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +26 -12
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/run-epilogue.js +426 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +95 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +16 -13
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +40 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +11 -3
- package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
- package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
- package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +15 -12
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +237 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +47 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +48 -0
- package/.agents/scripts/lib/orchestration/{epic-runner → story-progress}/story-run-progress-writer.js +3 -3
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +8 -18
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +11 -61
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +189 -373
- package/.agents/scripts/lib/orchestration/ticket-validator.js +2 -7
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +0 -25
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +29 -26
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +5 -5
- package/.agents/scripts/lib/planning-corpus.js +16 -11
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +36 -0
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/story-adjacency.js +11 -14
- package/.agents/scripts/lib/story-body/story-body.js +124 -70
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +46 -45
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +26 -26
- package/.agents/scripts/lib/validation-evidence.js +1 -1
- package/.agents/scripts/lib/wave-runner/ready-set.js +6 -6
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +5 -7
- package/.agents/scripts/lint-issue-body.js +71 -40
- package/.agents/scripts/mandrel-update-preflight.js +1 -1
- package/.agents/scripts/notify.js +4 -3
- package/.agents/scripts/plan-context.js +64 -74
- package/.agents/scripts/plan-persist.js +121 -280
- package/.agents/scripts/plan-run-epilogue.js +97 -0
- package/.agents/scripts/providers/github/issues.js +17 -33
- package/.agents/scripts/providers/github/mappers.js +0 -12
- package/.agents/scripts/providers/github/tickets.js +2 -5
- package/.agents/scripts/resolve-plan-run.js +117 -0
- package/.agents/scripts/signals-view.js +24 -19
- package/.agents/scripts/single-story-close.js +11 -14
- package/.agents/scripts/single-story-confirm-merge.js +39 -23
- package/.agents/scripts/single-story-init.js +29 -20
- package/.agents/scripts/stories-wave-tick.js +6 -6
- package/.agents/scripts/story-plan.js +26 -47
- package/.agents/scripts/update-ticket-state.js +6 -15
- package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
- package/.agents/skills/core/idea-refinement/SKILL.md +6 -6
- package/.agents/skills/core/scope-triage/SKILL.md +28 -172
- package/.agents/skills/skills.index.json +3 -43
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +3 -3
- package/.agents/workflows/audit-clean-code.md +3 -3
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +5 -5
- package/.agents/workflows/audit-lighthouse.md +3 -3
- package/.agents/workflows/audit-navigability.md +3 -2
- package/.agents/workflows/audit-performance.md +3 -3
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +3 -3
- package/.agents/workflows/audit-security.md +3 -3
- package/.agents/workflows/audit-seo.md +3 -3
- package/.agents/workflows/audit-sre.md +3 -3
- package/.agents/workflows/audit-to-stories.md +20 -20
- package/.agents/workflows/audit-ux-ui.md +3 -3
- package/.agents/workflows/deliver.md +122 -174
- package/.agents/workflows/git-cleanup.md +3 -4
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +16 -29
- package/.agents/workflows/helpers/code-review.md +70 -193
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +12 -14
- package/.agents/workflows/helpers/{single-story-deliver.md → deliver-story.md} +113 -139
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +1 -1
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +48 -64
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +112 -145
- package/.agents/workflows/qa-assist.md +24 -30
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -2
- package/README.md +9 -8
- package/docs/CHANGELOG.md +30 -0
- package/lib/migrations/index.js +6 -5
- package/package.json +2 -2
- package/.agents/agents/retro.md +0 -42
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer.md +0 -33
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/security-engineer.md +0 -111
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
- package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- package/.agents/scripts/dispatcher.js +0 -295
- package/.agents/scripts/epic-audit-prepare.js +0 -497
- package/.agents/scripts/epic-audit-recheck.js +0 -274
- package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
- package/.agents/scripts/epic-deliver-preflight.js +0 -462
- package/.agents/scripts/epic-deliver-prepare.js +0 -852
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-reconcile.js +0 -625
- package/.agents/scripts/lib/baseline-snapshot.js +0 -979
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
- package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
- package/.agents/scripts/lib/config/lifecycle.js +0 -40
- package/.agents/scripts/lib/config/preflight.js +0 -58
- package/.agents/scripts/lib/config/retro.js +0 -77
- package/.agents/scripts/lib/epic-merge-lock.js +0 -322
- package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
- package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
- package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
- package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
- package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
- package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
- package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
- package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
- package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
- package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
- package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
- package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
- package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
- package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
- package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
- package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
- package/.agents/scripts/lib/push-epic-retry.js +0 -209
- package/.agents/scripts/lib/spec/index.js +0 -36
- package/.agents/scripts/lib/spec/loader.js +0 -425
- package/.agents/scripts/lib/spec/state.js +0 -208
- package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
- package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
- package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
- package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
- package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
- package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
- package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
- package/.agents/scripts/lib/wave-runner/tick.js +0 -754
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
- package/.agents/scripts/lifecycle-emit.js +0 -510
- package/.agents/scripts/retro-run.js +0 -218
- package/.agents/scripts/slice-phase.js +0 -361
- package/.agents/scripts/standalone-feedback-rollup.js +0 -188
- package/.agents/scripts/story-close.js +0 -294
- package/.agents/scripts/story-init.js +0 -599
- package/.agents/scripts/story-phase.js +0 -369
- package/.agents/scripts/wave-tick.js +0 -464
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
- package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
- package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
- package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
- package/.agents/workflows/helpers/deliver-epic.md +0 -998
- package/.agents/workflows/helpers/deliver-stories.md +0 -450
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
- package/.agents/workflows/helpers/epic-testing.md +0 -125
- package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
- package/.agents/workflows/helpers/plan-epic.md +0 -353
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- /package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +0 -0
|
@@ -1,450 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: >-
|
|
3
|
-
Deliver one or more standalone Stories end-to-end. Accepts 1+ Story IDs,
|
|
4
|
-
builds a dependency DAG, asks the operator to confirm it, then drives a
|
|
5
|
-
continuous ready-set loop via `stories-wave-tick.js` (the shared
|
|
6
|
-
`selectReadySet` core) — dispatching each Story the instant its own deps
|
|
7
|
-
are done, under one global concurrency cap and one file-overlap guard,
|
|
8
|
-
each dispatch delegating to `helpers/single-story-deliver`. Stories
|
|
9
|
-
without an `Epic: #N` reference only; Epic-attached Stories use `/deliver`.
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# helpers/deliver-stories — multi-Story delivery path (invoked by /deliver)
|
|
13
|
-
|
|
14
|
-
## Overview
|
|
15
|
-
|
|
16
|
-
This helper is the **standalone multi-Story delivery path** behind
|
|
17
|
-
`/deliver`. The router delegates to it whenever the supplied IDs include
|
|
18
|
-
standalone Stories — either as the sole route (Story-only input) or as the
|
|
19
|
-
**standalone segment** of a mixed segment plan (run first, before any Epic
|
|
20
|
-
segments; see [`deliver.md`](../deliver.md)). It takes one or more Story
|
|
21
|
-
IDs, builds a dependency DAG, optionally confirms it with the operator, and
|
|
22
|
-
then drives a **continuous ready-set loop**: it dispatches each Story the
|
|
23
|
-
instant its **own** dependencies are done — there is no wave barrier where a
|
|
24
|
-
whole group must drain before the next opens — capped by one global
|
|
25
|
-
concurrency limit and guarded by one file-overlap rule, the same scheduling
|
|
26
|
-
core (`lib/wave-runner/ready-set.js#selectReadySet`) the Epic path uses.
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
/deliver 101 102 103
|
|
30
|
-
→ Phase 0 — Validate input & build DAG
|
|
31
|
-
→ Phase 1 — stories-wave-tick.js → DAG sanity + operator confirmation
|
|
32
|
-
→ Phase 2 — continuous ready-set loop:
|
|
33
|
-
repeat until every Story is done:
|
|
34
|
-
stories-wave-tick.js --dag … --done <doneIds> --in-flight <n>
|
|
35
|
-
→ ready[] = Stories dispatchable on this beat
|
|
36
|
-
Agent tool × ready.length parallel calls (≤ concurrencyCap − inFlight)
|
|
37
|
-
helpers/single-story-deliver <storyId>
|
|
38
|
-
as each child returns done, add its id to <doneIds> and re-tick
|
|
39
|
-
→ Phase 3 — Summary
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
**When to use `/deliver` vs. other commands:**
|
|
43
|
-
|
|
44
|
-
| Scenario | Command |
|
|
45
|
-
| --- | --- |
|
|
46
|
-
| 1+ standalone Stories (no `Epic: #N` in body) | `/deliver <id> [<id>...]` |
|
|
47
|
-
| Exactly one standalone Story (lighter path) | `/single-story-deliver <id>` |
|
|
48
|
-
| Epic-attached Stories (have `Epic: #N`) | `/deliver <epicId>` |
|
|
49
|
-
| Mixed Epics + standalone Stories | `/deliver <ids...>` — the router composes a sequential segment plan; this helper delivers the standalone segment first |
|
|
50
|
-
|
|
51
|
-
This helper **refuses** Stories that carry an `Epic: #N` reference in
|
|
52
|
-
their body. Those Stories belong to an Epic's dispatch manifest and must flow
|
|
53
|
-
through `/deliver <epicId>`. Use `/single-story-deliver` for a single
|
|
54
|
-
Epic-free Story when you want the leaner one-story path without the
|
|
55
|
-
ready-set scheduling loop.
|
|
56
|
-
|
|
57
|
-
> **Concurrency cap.** The cap is resolved **deterministically in code** by
|
|
58
|
-
> `stories-wave-tick.js` — the same `resolveConfig` + `getRunners` seam
|
|
59
|
-
> `/deliver` uses — and emitted as the `concurrencyCap` field on the
|
|
60
|
-
> `stories-ready-set` envelope on **every** beat. The default is 3; override
|
|
61
|
-
> persistently via `delivery.deliverRunner.concurrencyCap` in `.agentrc.json`
|
|
62
|
-
> (a `.agentrc.local.json` override is honored) or per-run via the
|
|
63
|
-
> `--concurrency` flag below. The cap is global, not per-wave: the core caps
|
|
64
|
-
> each beat's `ready[]` at `concurrencyCap − inFlight`, so the workflow simply
|
|
65
|
-
> dispatches every id in `ready[]` — do **not** re-read or merge config
|
|
66
|
-
> yourself, and do **not** re-throttle the returned set.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Arguments
|
|
71
|
-
|
|
72
|
-
```text
|
|
73
|
-
/deliver <storyId> [<storyId> ...] [--dep <fromId>:<toId> ...] [--yes] [--concurrency <n>]
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
- `storyId` — One or more GitHub issue numbers carrying `type::story` and
|
|
77
|
-
**no** `Epic: #N` reference. At least one is required.
|
|
78
|
-
- `--dep <fromId>:<toId>` — Declare an explicit dependency edge: `<fromId>`
|
|
79
|
-
must complete before `<toId>` runs. Repeat for each edge. When omitted,
|
|
80
|
-
all Stories are treated as independent (every Story is dispatchable on the
|
|
81
|
-
first beat) unless `blocked by #N` references between the supplied IDs are
|
|
82
|
-
detected automatically.
|
|
83
|
-
- `--yes` — Skip the operator confirmation in Phase 1 and proceed
|
|
84
|
-
immediately. Safe for scripted / sub-agent invocations.
|
|
85
|
-
- `--concurrency <n>` — Override the global concurrency cap for this run
|
|
86
|
-
only. Passed through to `stories-wave-tick.js` on every beat, which validates
|
|
87
|
-
it (must be a positive integer) and reflects it in the emitted
|
|
88
|
-
`concurrencyCap` field. When omitted, the cap is resolved from
|
|
89
|
-
`delivery.deliverRunner.concurrencyCap` (default 3).
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Phase 0 — Validate input and build DAG
|
|
94
|
-
|
|
95
|
-
For each supplied Story ID:
|
|
96
|
-
|
|
97
|
-
1. Confirm the issue exists and carries the `type::story` label.
|
|
98
|
-
2. Confirm the issue body does **not** contain an `Epic: #N` reference. If
|
|
99
|
-
it does, STOP and tell the operator to use `/deliver <epicId>`
|
|
100
|
-
instead.
|
|
101
|
-
3. Collect `blocked by #N` references between the supplied Story IDs.
|
|
102
|
-
References to Story IDs outside the supplied set are advisory warnings
|
|
103
|
-
only — they do not block delivery.
|
|
104
|
-
|
|
105
|
-
Construct the DAG input array:
|
|
106
|
-
|
|
107
|
-
```json
|
|
108
|
-
[
|
|
109
|
-
{ "id": 101, "dependsOn": [] },
|
|
110
|
-
{ "id": 102, "dependsOn": [101] },
|
|
111
|
-
{ "id": 103, "dependsOn": [] }
|
|
112
|
-
]
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
`dependsOn` is the union of:
|
|
116
|
-
|
|
117
|
-
- `blocked by #N` edges where `N` is in the supplied set.
|
|
118
|
-
- Explicit `--dep` edges.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Phase 1 — DAG sanity check and operator confirmation
|
|
123
|
-
|
|
124
|
-
### 1a. Sanity-check the DAG (first beat, nothing done yet)
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
node .agents/scripts/stories-wave-tick.js --dag '<dag-json>'
|
|
128
|
-
# with a per-run cap override:
|
|
129
|
-
node .agents/scripts/stories-wave-tick.js --dag '<dag-json>' --concurrency <n>
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
When the operator passed `--concurrency <n>` to `/deliver`, forward it
|
|
133
|
-
verbatim to `stories-wave-tick.js`. The script resolves the cap from config
|
|
134
|
-
(`delivery.deliverRunner.concurrencyCap`, default 3) and the override wins for
|
|
135
|
-
that run.
|
|
136
|
-
|
|
137
|
-
With no `--done` / `--in-flight` (the first beat), stdout is one JSON
|
|
138
|
-
envelope describing the Stories dispatchable **right now** — the roots:
|
|
139
|
-
|
|
140
|
-
```json
|
|
141
|
-
{
|
|
142
|
-
"kind": "stories-ready-set",
|
|
143
|
-
"ready": [101, 103],
|
|
144
|
-
"totalStories": 3,
|
|
145
|
-
"concurrencyCap": 3,
|
|
146
|
-
"inFlight": 0,
|
|
147
|
-
"cycleError": null
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
- **`cycleError` non-null** → STOP. Report the cycle to the operator and
|
|
152
|
-
exit. The Story set cannot be delivered until the circular dependency is
|
|
153
|
-
resolved.
|
|
154
|
-
- **`totalStories === 0`** → STOP. Zero Stories resolved — report and exit.
|
|
155
|
-
- **`ready` empty with `totalStories > 0` on the first beat** → STOP. Every
|
|
156
|
-
Story is gated behind a dependency outside the supplied set; report and
|
|
157
|
-
exit (the operator must include the missing prerequisites).
|
|
158
|
-
- **`concurrencyCap`** is the resolved global cap. Phase 2 re-reads it from
|
|
159
|
-
each beat's envelope and never re-derives it from config.
|
|
160
|
-
- An invalid `--concurrency` / `--in-flight` / `--done` value makes the
|
|
161
|
-
script exit non-zero with an `inputError` → STOP and surface the message.
|
|
162
|
-
|
|
163
|
-
This first call is a **sanity gate**, not the schedule: Phase 2 re-ticks
|
|
164
|
-
continuously as Stories complete. The envelope no longer enumerates future
|
|
165
|
-
waves — ordering emerges beat by beat from the live `--done` set.
|
|
166
|
-
|
|
167
|
-
### 1b. Operator confirmation (skipped with `--yes` or for single-story runs)
|
|
168
|
-
|
|
169
|
-
**Auto-skip rule (Story #3302):** When `totalStories === 1`, skip the
|
|
170
|
-
confirmation prompt automatically and proceed. A single-Story run has no
|
|
171
|
-
ordering ambiguity and no meaningful operator decision to make — the run
|
|
172
|
-
*is* "deliver this one Story". Prompting for confirmation would just be
|
|
173
|
-
friction.
|
|
174
|
-
|
|
175
|
-
Otherwise, present the dependency DAG to the operator in a readable table —
|
|
176
|
-
the roots dispatch immediately, dependents unlock as their prerequisites
|
|
177
|
-
complete:
|
|
178
|
-
|
|
179
|
-
```text
|
|
180
|
-
Delivery plan — 3 Stories (continuous, dependency-driven)
|
|
181
|
-
Ready now: #101 "<title>", #103 "<title>"
|
|
182
|
-
Unlocks after its deps complete: #102 "<title>" (needs #101)
|
|
183
|
-
|
|
184
|
-
Proceed? [Y/n]
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Wait for the operator to confirm before dispatching. When the operator
|
|
188
|
-
types `n` or `N`, abort cleanly with a summary of the plan that was
|
|
189
|
-
declined. When `--yes` was passed, skip this step and proceed regardless
|
|
190
|
-
of Story count.
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## Phase 2 — Continuous ready-set loop
|
|
195
|
-
|
|
196
|
-
Drive a single loop, re-ticking after every child returns. Maintain two
|
|
197
|
-
pieces of state across the loop:
|
|
198
|
-
|
|
199
|
-
- **`doneIds`** — the set of Story IDs that have returned `status: 'done'`
|
|
200
|
-
(start empty).
|
|
201
|
-
- **`inFlight`** — the count of Stories dispatched but not yet returned
|
|
202
|
-
(start at 0).
|
|
203
|
-
|
|
204
|
-
Each iteration (one **beat**):
|
|
205
|
-
|
|
206
|
-
### 2a. Tick the ready set
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
node .agents/scripts/stories-wave-tick.js --dag '<dag-json>' \
|
|
210
|
-
--done '<comma-separated doneIds>' --in-flight <inFlight> [--concurrency <n>]
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
The envelope's `ready[]` is the set of Stories whose **own** dependencies
|
|
214
|
-
are all in `doneIds` and that fit the remaining capacity
|
|
215
|
-
(`concurrencyCap − inFlight`) without a file-overlap collision — the core
|
|
216
|
-
has already applied the global cap and the overlap guard, so the list is
|
|
217
|
-
safe to dispatch verbatim. **Termination:** when `ready` is empty **and**
|
|
218
|
-
`inFlight === 0` **and** `doneIds` covers every Story, the run is complete →
|
|
219
|
-
go to Phase 3. When `ready` is empty but `inFlight > 0`, dispatch nothing
|
|
220
|
-
and wait for an in-flight child to return (a dependent is waiting on it).
|
|
221
|
-
|
|
222
|
-
### 2b. Fan out per-Story Agent calls
|
|
223
|
-
|
|
224
|
-
Emit **one `Agent` tool call per Story ID in `ready[]`**, all with
|
|
225
|
-
`run_in_background: true`. The list is already capped, so dispatch the whole
|
|
226
|
-
of `ready[]` and increment `inFlight` by `ready.length`. Do **not** re-derive
|
|
227
|
-
or re-throttle the cap here; the core sized `ready[]` for you.
|
|
228
|
-
|
|
229
|
-
Each Agent call:
|
|
230
|
-
|
|
231
|
-
1. Names the Story ID and instructs the child to invoke
|
|
232
|
-
[`helpers/single-story-deliver`](single-story-deliver.md)
|
|
233
|
-
for that Story.
|
|
234
|
-
2. States the **return contract** (see § 2c) and the **no-park rule**: the
|
|
235
|
-
child MUST drive the close → CI-watch → merge-confirm → `agent::done`
|
|
236
|
-
sequence to a terminal state *within its own turn* and end **only** by
|
|
237
|
-
returning the § 2c JSON object. The auto-merge wait is an
|
|
238
|
-
internally-blocking step (`pr-watch-with-update.js` blocks the turn), **not**
|
|
239
|
-
a reason to suspend and hand back. A child that ends its turn with
|
|
240
|
-
free-form prose and an unconfirmed merge (e.g. "I'll wait for the
|
|
241
|
-
background watch task…") has violated the contract — the loop cannot
|
|
242
|
-
advance, and the Story strands at `agent::closing` (the Story #1553 /
|
|
243
|
-
PR #1554 failure mode). There is no "pending" return status: the child
|
|
244
|
-
returns `done` (merge confirmed), `blocked` (transitioned + friction
|
|
245
|
-
posted), or `failed`.
|
|
246
|
-
3. Reminds the child of the **non-interactive contract**: no clarifying
|
|
247
|
-
questions — if stuck, transition to `agent::blocked`, post a
|
|
248
|
-
`friction` comment, and exit non-zero.
|
|
249
|
-
4. Requests the child suppress per-phase chat relay and include its
|
|
250
|
-
**terminal** `renderedBody` in the JSON return.
|
|
251
|
-
|
|
252
|
-
**Sub-agent type (Epic #4478, M7-B).** When `delivery.routing.roleScopedAgents`
|
|
253
|
-
is enabled (the **default**), dispatch each Story child with
|
|
254
|
-
`subagent_type: story-worker` — it boots on the role-scoped
|
|
255
|
-
[`story-worker`](../../agents/story-worker.md) context (its own system prompt,
|
|
256
|
-
no `CLAUDE.md` @-closure) which carries every load-bearing delivery MUST
|
|
257
|
-
standalone, so the spawn stops re-paying the always-loaded context. When the
|
|
258
|
-
kill-switch is **off** (`delivery.routing.roleScopedAgents: false`), fall back
|
|
259
|
-
to `subagent_type: general-purpose` — the instant, code-rollback-free revert and
|
|
260
|
-
the universal escape for hosts that ignore `.claude/agents/`. The child still
|
|
261
|
-
runs [`helpers/epic-deliver-story`](epic-deliver-story.md) either way; only the
|
|
262
|
-
boot context differs.
|
|
263
|
-
|
|
264
|
-
### 2b′. Collect each return and re-tick
|
|
265
|
-
|
|
266
|
-
As each child returns, decrement `inFlight` by 1 and apply its outcome
|
|
267
|
-
(§ 2d). When a child returns `done`, add its id to `doneIds`. Then **re-tick
|
|
268
|
-
immediately** (§ 2a) so a newly-unblocked Story dispatches the instant its
|
|
269
|
-
last dependency clears — do not wait for the whole batch to drain. This is
|
|
270
|
-
the no-false-barrier behavior: an unrelated still-running Story never holds
|
|
271
|
-
back a Story whose own deps are already done.
|
|
272
|
-
|
|
273
|
-
### 2c. Per-Story return contract
|
|
274
|
-
|
|
275
|
-
Each child ends its turn by returning **exactly one** JSON object — never
|
|
276
|
-
free-form prose:
|
|
277
|
-
|
|
278
|
-
```json
|
|
279
|
-
{
|
|
280
|
-
"storyId": <number>,
|
|
281
|
-
"status": "done" | "blocked" | "failed",
|
|
282
|
-
"phase": "init|implementing|closing|blocked|done",
|
|
283
|
-
"branchDeleted": <boolean>,
|
|
284
|
-
"blockerCommentId": <string|null>,
|
|
285
|
-
"detail": "<one-liner>",
|
|
286
|
-
"renderedBody": "<terminal story body>"
|
|
287
|
-
}
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
The status enum is **closed** — `done`, `blocked`, or `failed`. There is no
|
|
291
|
-
"pending" / "waiting" status, because the close-phase auto-merge wait is
|
|
292
|
-
**not** a returnable suspension: the child blocks on `pr-watch-with-update.js`
|
|
293
|
-
*inside its own turn*, confirms the merge, flips `agent::done`, and only then
|
|
294
|
-
returns `status: "done"`. A child that returns prose instead — parking on the
|
|
295
|
-
CI wait with an unconfirmed merge — breaks the loop's ability to advance
|
|
296
|
-
and leaves the Story at `agent::closing` (Story #1553 / PR #1554). The
|
|
297
|
-
single-homed restatement of this no-park rule for the child's own perspective
|
|
298
|
-
is [`single-story-deliver.md` § Step 7](single-story-deliver.md#return-contract).
|
|
299
|
-
|
|
300
|
-
### 2d. Per-return outcome handling
|
|
301
|
-
|
|
302
|
-
As each child returns (before the next re-tick):
|
|
303
|
-
|
|
304
|
-
- **`status === 'done'`** → Add its id to `doneIds` and re-tick. Print a
|
|
305
|
-
one-line per-Story complete summary.
|
|
306
|
-
- **`status === 'blocked'`** → STOP dispatching new Stories. Drain the
|
|
307
|
-
Stories still in flight (let them return), then post a summary of blocked
|
|
308
|
-
Stories and their `blockerCommentId` references. Do not dispatch any
|
|
309
|
-
further beat. Wait for the operator to resolve each blocker and re-run
|
|
310
|
-
`/deliver` with the same set (already-done Stories will short-circuit
|
|
311
|
-
because `single-story-close.js` is idempotent).
|
|
312
|
-
- **`status === 'failed'`** → STOP dispatching new Stories, drain the
|
|
313
|
-
in-flight set, and report the failures. The operator must fix the failing
|
|
314
|
-
Stories before re-running.
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Phase 3 — Summary
|
|
319
|
-
|
|
320
|
-
Print a final run summary listing every delivered Story in completion order:
|
|
321
|
-
|
|
322
|
-
```text
|
|
323
|
-
/deliver — 3 Stories delivered (continuous, dependency-driven)
|
|
324
|
-
|
|
325
|
-
#101 ✅ done, #103 ✅ done (dispatched first — roots)
|
|
326
|
-
#102 ✅ done (after #101 cleared)
|
|
327
|
-
|
|
328
|
-
All Stories delivered. PRs opened, auto-merge armed. CI will merge each
|
|
329
|
-
PR when checks pass; each child then confirms the merge and flips its
|
|
330
|
-
Story to `agent::done` (Story #3385 — until the merge confirms, a Story
|
|
331
|
-
rests at `agent::closing` with its issue OPEN).
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
Then **fast-forward `main` yourself** — do not instruct the operator to run it
|
|
335
|
-
after the last merge. The delivering flow owns bringing the local base branch
|
|
336
|
-
up to whatever has merged so far:
|
|
337
|
-
|
|
338
|
-
```bash
|
|
339
|
-
node .agents/scripts/git-cleanup.js --fast-forward-main --execute --yes
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
This runs only the fast-forward-main phase (`git fetch origin main` →
|
|
343
|
-
`git merge --ff-only`); it is idempotent and a no-op when `main` is already
|
|
344
|
-
current, so it is safe to run even while some PRs are still queued in
|
|
345
|
-
auto-merge. Report its one-line result in the summary. Merged Story branches
|
|
346
|
-
themselves are reaped by the boot sweep at the next `/plan` / `/deliver` boot —
|
|
347
|
-
see [`.agents/rules/git-conventions.md` § Local checkout hygiene](../../rules/git-conventions.md).
|
|
348
|
-
|
|
349
|
-
### Feedback rollup
|
|
350
|
-
|
|
351
|
-
Then run the **end-of-run feedback rollup** over the delivered Story set so
|
|
352
|
-
the write-only standalone signals tree finally has a consumer. Each per-Story
|
|
353
|
-
sub-agent appends `friction` records to its standalone stream
|
|
354
|
-
(`temp/standalone/stories/story-<sid>/signals.ndjson`); the rollup scans those
|
|
355
|
-
streams and aggregates friction by category:
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
node .agents/scripts/standalone-feedback-rollup.js --stories <all delivered story ids, comma-separated>
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
The CLI prints one JSON object
|
|
362
|
-
(`{ kind, stories, totalFriction, byCategory, perStory }`) and **always exits
|
|
363
|
-
0** — missing or empty streams degrade to an empty summary, so this beat never
|
|
364
|
-
fails the run. Surface `totalFriction` and the `byCategory` totals in the run
|
|
365
|
-
summary so the operator sees where friction clustered across the delivery:
|
|
366
|
-
|
|
367
|
-
```text
|
|
368
|
-
Feedback rollup — 4 friction signals across 3 Stories
|
|
369
|
-
Execution Error: 2, Tool Limitation: 1, Missing Skill: 1
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
When `totalFriction` is 0 (or every stream was missing), report a single
|
|
373
|
-
"no friction signals recorded" line and move on — it is not an error.
|
|
374
|
-
|
|
375
|
-
When some Stories are blocked or failed, list them explicitly with the
|
|
376
|
-
`blockerCommentId` or failure detail so the operator knows where to look.
|
|
377
|
-
|
|
378
|
-
---
|
|
379
|
-
|
|
380
|
-
## Opt-in post-green refactor stage (`delivery.refactorStage`)
|
|
381
|
-
|
|
382
|
-
When `delivery.refactorStage.enabled` is `true` in `.agentrc.json`, each
|
|
383
|
-
per-Story worker runs an **advisory** post-green refactor pass after the
|
|
384
|
-
Story's suite is green and the close-validation gates already pass — and
|
|
385
|
-
**before** close. The stage is **strictly opt-in and default-OFF**: when the
|
|
386
|
-
key is unset or `false`, story-deliver behaves exactly as documented above
|
|
387
|
-
and this stage is skipped entirely.
|
|
388
|
-
|
|
389
|
-
The stage applies the post-green refactor discipline in
|
|
390
|
-
[`core/code-review-and-quality`](../../skills/core/code-review-and-quality/SKILL.md)
|
|
391
|
-
(§ Post-Green Refactor Pass) to drive a behaviour-preserving pass that lowers
|
|
392
|
-
CRAP and removes duplication on the files the Story already touched:
|
|
393
|
-
|
|
394
|
-
- **Post-green only.** It runs after the suite is green and the gates pass —
|
|
395
|
-
never from red, and never to make a failing test pass.
|
|
396
|
-
- **Behaviour-preserving.** Existing tests MUST keep passing without
|
|
397
|
-
modification; if a test had to change, the change was a behaviour change and
|
|
398
|
-
must be reverted.
|
|
399
|
-
- **Advisory, not a gate.** This stage does **not** introduce a new
|
|
400
|
-
close-validation gate and does **not** change the semantics of the existing
|
|
401
|
-
[close-validation](../../scripts/lib/close-validation/runner.js) chain (typecheck,
|
|
402
|
-
lint, test, format, maintainability, coverage, crap). The canonical gates
|
|
403
|
-
remain the single source of pass/fail at close; the refactor stage only adds
|
|
404
|
-
an extra behaviour-preserving cleanup commit when enabled.
|
|
405
|
-
|
|
406
|
-
> **Default-OFF guarantee.** Consumers who do not set
|
|
407
|
-
> `delivery.refactorStage.enabled` (or set it to `false`) see no change in
|
|
408
|
-
> delivery behaviour — no extra stage, no new gate, identical close semantics.
|
|
409
|
-
|
|
410
|
-
---
|
|
411
|
-
|
|
412
|
-
## Idempotence
|
|
413
|
-
|
|
414
|
-
`/single-story-deliver` is idempotent at every phase:
|
|
415
|
-
`single-story-init.js` reuses an existing worktree and
|
|
416
|
-
`single-story-close.js` short-circuits when the Story is already closed.
|
|
417
|
-
Re-running `/deliver` with the same Story set after a partial
|
|
418
|
-
failure is safe — already-done Stories produce no-op outcomes; only the
|
|
419
|
-
blocked or unstarted Stories execute.
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## Constraints
|
|
424
|
-
|
|
425
|
-
- **Never** pass Epic-attached Stories to this command. Detect `Epic: #N`
|
|
426
|
-
in Phase 0 and STOP.
|
|
427
|
-
- **Never** dispatch a new beat once any Story has returned `blocked` or
|
|
428
|
-
`failed` — drain the in-flight set and stop.
|
|
429
|
-
- **Never** exceed the resolved `concurrencyCap` (emitted by
|
|
430
|
-
`stories-wave-tick.js` on every beat) parallel Agent calls at any moment.
|
|
431
|
-
The core caps each beat's `ready[]` at `concurrencyCap − inFlight`;
|
|
432
|
-
dispatch the whole list and never add to it.
|
|
433
|
-
- **Always** confirm the dependency DAG with the operator before dispatching,
|
|
434
|
-
unless `--yes` was passed.
|
|
435
|
-
- **Label transitions**: drive every `agent::*` state change through
|
|
436
|
-
`node .agents/scripts/update-ticket-state.js --ticket <id> --state <state>`.
|
|
437
|
-
This CLI is the authoritative mechanism — there is no separate
|
|
438
|
-
state-mutation MCP server to degrade from (see
|
|
439
|
-
[`.agents/instructions.md` § 1.D](../../instructions.md)).
|
|
440
|
-
|
|
441
|
-
---
|
|
442
|
-
|
|
443
|
-
## See also
|
|
444
|
-
|
|
445
|
-
- [`helpers/single-story-deliver`](single-story-deliver.md) — the
|
|
446
|
-
per-Story worker this command delegates to.
|
|
447
|
-
- [`/deliver`](deliver-epic.md) — full Epic wave loop for
|
|
448
|
-
Epic-attached Stories.
|
|
449
|
-
- [`helpers/epic-deliver-story`](epic-deliver-story.md) — the
|
|
450
|
-
per-Story worker `/deliver` uses internally.
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: >-
|
|
3
|
-
Resolve the slim Epic-close (gate3) lens roster for /deliver. Consumes the
|
|
4
|
-
epic-audit-prepare envelope, restricts it to the cumulative + global +
|
|
5
|
-
risk-routed lenses the Epic-close tier owns, and hands that roster to the
|
|
6
|
-
Phase 5 code-review pass — which walks the cumulative Epic diff once and folds
|
|
7
|
-
the lens findings into its single verification-results comment.
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Epic-close lens roster (helper)
|
|
11
|
-
|
|
12
|
-
> **Helper module.** Not a slash command. Invoked automatically from
|
|
13
|
-
> `/deliver` Phase 4 once the wave loop completes (all Stories at
|
|
14
|
-
> `agent::done`) to resolve the Epic-close lens roster that the Phase 5
|
|
15
|
-
> code-review pass walks. To run delivery, use `/deliver [Epic_ID]` (or pass
|
|
16
|
-
> `--skip-epic-audit` to bypass the Epic-close lens tier).
|
|
17
|
-
|
|
18
|
-
This helper resolves the **change-set-aware Epic-close lens roster** for an
|
|
19
|
-
Epic branch. Under the three-tier verification model (Epic #4405) it does
|
|
20
|
-
**not** run a standalone lens walk of its own and does **not** post its own
|
|
21
|
-
structured comment. It selects the slim roster and hands it to the Phase 5
|
|
22
|
-
[`code-review.md`](code-review.md) pass, which walks the cumulative Epic diff
|
|
23
|
-
**once** — executing these lenses as review dimensions — and folds their
|
|
24
|
-
findings into the single `verification-results` comment it posts on the Epic.
|
|
25
|
-
|
|
26
|
-
> **Three-tier model — where each lens concern is verified.** A lens's `scope`
|
|
27
|
-
> field in [`audit-rules.json`](../../schemas/audit-rules.json) (resolved by
|
|
28
|
-
> [`resolveLensTier`](../../scripts/lib/audit-suite/selector.js)) decides the
|
|
29
|
-
> **one** tier that owns its concern:
|
|
30
|
-
>
|
|
31
|
-
> - **`local`** — decidable from a single Story's diff. Verified **write-time**
|
|
32
|
-
> (the distilled checklist threaded into the Story implementation prompt,
|
|
33
|
-
> Story #4410) and at **Story-scope** (the maker-blind local-lens pass in
|
|
34
|
-
> `story-close`, Story #4409). **Not** re-run at Epic close.
|
|
35
|
-
> - **`cumulative`** — only decidable across the Epic's combined diff. Verified
|
|
36
|
-
> at **Epic close** only.
|
|
37
|
-
> - **`global`** — evaluates a whole-product property regardless of the diff
|
|
38
|
-
> (exempt from the cross-epic-leak change-set narrowing). Verified at **Epic
|
|
39
|
-
> close** only.
|
|
40
|
-
>
|
|
41
|
-
> No lens concern is verified at more than one tier: the Epic-close roster
|
|
42
|
-
> below deliberately **excludes every local-tier change-set lens** and keeps
|
|
43
|
-
> only cumulative + global + risk-routed lenses.
|
|
44
|
-
|
|
45
|
-
**When to run**: After Phase 3 close-validation passes, to resolve the roster
|
|
46
|
-
the Phase 5 code-review pass consumes. `/deliver` invokes this automatically
|
|
47
|
-
once the wave loop completes and all Stories reach `agent::done`.
|
|
48
|
-
|
|
49
|
-
**Persona**: `architect` · **Skills**: `core/code-review-and-quality`,
|
|
50
|
-
`core/security-and-hardening`
|
|
51
|
-
|
|
52
|
-
## Step 0 — Resolve Context
|
|
53
|
-
|
|
54
|
-
1. Resolve `[EPIC_ID]` — the GitHub Issue number of the Epic under audit.
|
|
55
|
-
2. Resolve `[EPIC_BRANCH]` — `epic/<epicId>`.
|
|
56
|
-
3. Resolve `[BASE_BRANCH]` from `baseBranch` in `.agentrc.json` (default:
|
|
57
|
-
`main`).
|
|
58
|
-
4. Fetch the Epic ticket — the Epic body is the single planning
|
|
59
|
-
document:
|
|
60
|
-
- **Narrative sections** — Context / Goal / Scope / User Stories /
|
|
61
|
-
Acceptance Criteria.
|
|
62
|
-
- **Tech Spec** — the folded Tech Spec sections (opening with
|
|
63
|
-
`## Delivery Slicing`) inside the body's managed region.
|
|
64
|
-
5. Read the Epic body fully (including its Tech Spec sections) to
|
|
65
|
-
understand the intended scope, selected lenses, and acceptance criteria.
|
|
66
|
-
|
|
67
|
-
## Step 1 — Prepare (`epic-audit-prepare.js`)
|
|
68
|
-
|
|
69
|
-
Run the prepare CLI to compute the change-set, ask `selectAudits` which
|
|
70
|
-
lenses fire at `gate3` (the Epic close gate), union in the model-judged
|
|
71
|
-
risk-routed lenses, and emit the helper-consumable JSON envelope on stdout:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
node .agents/scripts/epic-audit-prepare.js \
|
|
75
|
-
--epic [EPIC_ID] --base-branch [BASE_BRANCH] --gate gate3
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
The CLI is thin glue around the audit-suite SDK and is fully described in
|
|
79
|
-
[`epic-audit-prepare.js`](../../scripts/epic-audit-prepare.js). Capture the
|
|
80
|
-
envelope:
|
|
81
|
-
|
|
82
|
-
```json
|
|
83
|
-
{
|
|
84
|
-
"epicId": 2586,
|
|
85
|
-
"epicBranch": "epic/2586",
|
|
86
|
-
"depth": "deep",
|
|
87
|
-
"selectedAudits": ["audit-security", "audit-architecture", "audit-privacy"],
|
|
88
|
-
"epicCloseLenses": ["audit-architecture", "audit-security"],
|
|
89
|
-
"changeSetAudits": ["audit-architecture", "audit-privacy"],
|
|
90
|
-
"riskRoutedAudits": ["audit-security"],
|
|
91
|
-
"globalLenses": [],
|
|
92
|
-
"changedFiles": ["src/api/admin/users.ts", "..."],
|
|
93
|
-
"changedFilesCount": 47,
|
|
94
|
-
"substitutionsPayload": "src/api/admin/users.ts\n..."
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
- **`epicCloseLenses` is the roster you hand to Phase 5.** It is the slim
|
|
99
|
-
Epic-close roster — `selectedAudits` restricted to the tiers the Epic-close
|
|
100
|
-
tier owns via
|
|
101
|
-
[`selectEpicCloseLenses`](../../scripts/lib/orchestration/code-review.js):
|
|
102
|
-
every **cumulative** and **global** change-set lens, plus every **risk-routed**
|
|
103
|
-
lens, with every **local-tier** change-set lens dropped (its concern is
|
|
104
|
-
already verified shift-left). In the example above `audit-privacy` (local) is
|
|
105
|
-
excluded from `epicCloseLenses` while `audit-architecture` (cumulative) is
|
|
106
|
-
kept and `audit-security` (risk-routed) is kept.
|
|
107
|
-
- **`selectedAudits` / `changeSetAudits` / `riskRoutedAudits`** are surfaced for
|
|
108
|
-
observability so the operator can see the pre-slim union and why each lens
|
|
109
|
-
fired. Do **not** walk `selectedAudits` — walk `epicCloseLenses`.
|
|
110
|
-
- **`globalLenses`** is the subset of the roster on the global-lens allowlist
|
|
111
|
-
(e.g. `audit-navigability`) that the Phase 5 walk runs against the WHOLE
|
|
112
|
-
route tree, exempt from the cross-epic-leak guard's change-set narrowing
|
|
113
|
-
(Epic #4131, F2).
|
|
114
|
-
|
|
115
|
-
### The `depth` field (Story #3939)
|
|
116
|
-
|
|
117
|
-
`depth` is `light`, `standard`, or `deep` — an **orthogonal** signal that
|
|
118
|
-
tells the Phase 5 pass how thorough each **rostered** lens should be on this
|
|
119
|
-
Epic. It is resolved by the shared `resolveDepth` resolver from the Epic's
|
|
120
|
-
model-judged risk envelope (`overallLevel` off the `epic-plan-state`
|
|
121
|
-
checkpoint) folded with `changedFilesCount`: a high-risk **or** wide-footprint
|
|
122
|
-
Epic resolves to `deep`, a low-risk small one to `light`, and everything else
|
|
123
|
-
— including an Epic that skipped `/plan` and has no checkpoint — to `standard`.
|
|
124
|
-
Depth changes **how deeply** each lens runs, never **which** lenses fire.
|
|
125
|
-
|
|
126
|
-
### Outcomes
|
|
127
|
-
|
|
128
|
-
- **`epicCloseLenses` is non-empty** — pass the roster (and `depth`,
|
|
129
|
-
`globalLenses`, `substitutionsPayload`) to the Phase 5 code-review pass.
|
|
130
|
-
- **`epicCloseLenses` is empty** (docs-only change set, or every selected lens
|
|
131
|
-
was a local-tier change-set lens already covered shift-left, and no high-risk
|
|
132
|
-
axis routed a lens) — there is no Epic-close lens dimension to walk; the
|
|
133
|
-
Phase 5 pass still runs its review pillars and posts the
|
|
134
|
-
`verification-results` comment.
|
|
135
|
-
- **`degraded: true`** — the selector aborted. Possible `reason` codes:
|
|
136
|
-
`GIT_DIFF_TIMEOUT` (git-diff timed out), `HEAD_REF_UNRESOLVED` (the
|
|
137
|
-
Epic's branch `refs/heads/epic/<id>` is not present in this checkout),
|
|
138
|
-
or `EPIC_REF_MISMATCH` (the selector diffed a ref other than the
|
|
139
|
-
requested Epic's branch — the cross-epic-leak guard from Story #3362).
|
|
140
|
-
Surface the `reason`/`detail` fields to the operator, post a friction
|
|
141
|
-
comment on the Epic, and STOP. Do not fall back to running the full lens
|
|
142
|
-
roster — that defeats the change-set scoping, and an unresolved/mismatched
|
|
143
|
-
ref means the change set would belong to the wrong Epic.
|
|
144
|
-
|
|
145
|
-
## Step 2 — Hand the roster to the Phase 5 code-review pass
|
|
146
|
-
|
|
147
|
-
The cumulative Epic diff is walked **once** at Epic close. The
|
|
148
|
-
`epicCloseLenses` roster is executed as **dimensions of the Phase 5
|
|
149
|
-
code-review pass** ([`code-review.md`](code-review.md) with `scope: epic`),
|
|
150
|
-
not as a standalone walk here. The Phase 5 pass:
|
|
151
|
-
|
|
152
|
-
1. Loads each rostered lens's `.agents/workflows/audit-<lens>.md` via
|
|
153
|
-
[`runAuditSuite`](../../scripts/lib/audit-suite/index.js) (the
|
|
154
|
-
prompt-assembly runner), applying the `{{changedFiles}}` / `{{ticketId}}` /
|
|
155
|
-
`{{baseBranch}}` substitutions from this envelope.
|
|
156
|
-
2. Executes each lens inline at the run's `depth` over the cumulative diff,
|
|
157
|
-
folding its findings into the pass's severity aggregate alongside the review
|
|
158
|
-
pillars — one walk of `main..epic/<id>`, one aggregate.
|
|
159
|
-
3. Posts the single `verification-results` structured comment (there is **no**
|
|
160
|
-
separate `audit-results` comment; that producer was retired in Story #4412).
|
|
161
|
-
|
|
162
|
-
Remediation of the aggregate is **tier-aware** (Story #4412): the Epic-close
|
|
163
|
-
tier reads `delivery.epicAudit.autoFixSeverity` (default **`high`** — see
|
|
164
|
-
[`config/runners.js`](../../scripts/lib/config/runners.js)) and routes only
|
|
165
|
-
🔴 Critical + 🟠 High findings into on-branch remediation; 🟡 Medium and
|
|
166
|
-
🟢 Suggestion findings graduate to follow-up issues, because 🟡 Medium concerns
|
|
167
|
-
are already remediated shift-left at the write-time and Story-scope tiers.
|
|
168
|
-
Setting `medium` opts back into routing 🔴/🟠/🟡 on-branch. The severity gate
|
|
169
|
-
is **unchanged** — a surviving 🔴 Critical Blocker halts the run.
|
|
170
|
-
|
|
171
|
-
## Constraints
|
|
172
|
-
|
|
173
|
-
- **Always** diff against `[BASE_BRANCH]`, not against individual Story
|
|
174
|
-
branches. The Epic-close pass examines the cumulative effect of the entire
|
|
175
|
-
Epic.
|
|
176
|
-
- **Always** read the Epic body and Tech Spec before the Phase 5 walk. Findings
|
|
177
|
-
without spec context are noise.
|
|
178
|
-
- **Never** walk `selectedAudits`. The roster the Phase 5 pass executes is
|
|
179
|
-
`epicCloseLenses` — the slim cumulative + global + risk-routed set. Walking
|
|
180
|
-
the pre-slim union re-verifies local-tier concerns already covered
|
|
181
|
-
shift-left, defeating the three-tier model.
|
|
182
|
-
- **Never** widen the roster past `epicCloseLenses`. The whole point of the
|
|
183
|
-
change-set selector plus the tier filter is to avoid re-running irrelevant or
|
|
184
|
-
already-verified lenses on a scoped Epic.
|
|
185
|
-
- **Never** post an `audit-results` structured comment. The Epic-close lens
|
|
186
|
-
findings are folded into the Phase 5 `verification-results` comment — the
|
|
187
|
-
single findings surface on the Epic.
|
|
188
|
-
- **Always** propagate `degraded` envelopes verbatim. Do not paper over a
|
|
189
|
-
selector failure with a full-roster fallback.
|