mandrel 1.93.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/acceptance-critic.md +129 -0
- package/.agents/agents/story-worker.md +161 -0
- package/.agents/docs/SDLC.md +489 -1285
- package/.agents/docs/agentrc-reference.json +177 -67
- package/.agents/docs/configuration.md +108 -136
- package/.agents/docs/execution-reference.md +44 -22
- package/.agents/docs/quality-gates.md +13 -19
- package/.agents/docs/workflows.md +3 -3
- package/.agents/instructions.md +107 -108
- package/.agents/rules/ci-remediation.md +8 -12
- package/.agents/rules/git-conventions-reference.md +224 -0
- package/.agents/rules/git-conventions.md +42 -223
- package/.agents/rules/security-baseline.md +5 -0
- package/.agents/rules/testing-standards.md +106 -13
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +71 -201
- 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/acceptance-eval.js +62 -18
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- 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-context-budget.js +62 -5
- 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/diagnose-friction.js +0 -6
- 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/bootstrap/project-bootstrap.js +56 -18
- 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 +160 -22
- package/.agents/scripts/lib/config/acceptance-eval.js +52 -5
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +103 -0
- package/.agents/scripts/lib/config/explain.js +57 -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 +3 -8
- package/.agents/scripts/lib/config-settings-schema-delivery.js +46 -136
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -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 +39 -4
- 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 +112 -3
- package/.agents/scripts/lib/observability/hook-heartbeat.js +187 -0
- package/.agents/scripts/lib/observability/source-classifier.js +3 -3
- package/.agents/scripts/lib/observability/tool-trace-hook.js +15 -4
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +111 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +32 -4
- package/.agents/scripts/lib/orchestration/audit-lens-routing.js +128 -0
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +273 -0
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +204 -0
- 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-critic-conditions.js +3 -2
- 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 +14 -14
- 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/close-validation.js +1 -0
- 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 +3 -8
- 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/provider-factory.js +1 -1
- 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/post-structured-comment.js +38 -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/sync-claude-agents.js +165 -0
- package/.agents/scripts/update-ticket-state.js +37 -15
- package/.agents/skills/core/analyze-execution/SKILL.md +21 -18
- package/.agents/skills/core/api-and-interface-design/SKILL.md +5 -3
- package/.agents/skills/core/code-review-and-quality/SKILL.md +63 -7
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +1 -1
- package/.agents/skills/core/gates-and-baselines/SKILL.md +149 -0
- package/.agents/skills/core/idea-refinement/SKILL.md +8 -14
- package/.agents/skills/core/qa-coverage-mapping/SKILL.md +7 -7
- package/.agents/skills/core/scope-triage/SKILL.md +28 -172
- package/.agents/skills/skills.index.json +8 -418
- 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 -131
- 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 +52 -40
- 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/mandrel-sync-config.md +1 -1
- 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 +3 -2
- 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 +46 -0
- package/lib/cli/registry.js +95 -0
- package/lib/migrations/index.js +6 -5
- package/package.json +5 -3
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer-mobile.md +0 -120
- package/.agents/personas/engineer-web.md +0 -111
- package/.agents/personas/engineer.md +0 -119
- package/.agents/personas/product.md +0 -94
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/refactorer.md +0 -113
- package/.agents/personas/security-engineer.md +0 -112
- package/.agents/personas/sre.md +0 -86
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/personas/ux-designer.md +0 -95
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- 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 -590
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-decompose.js +0 -54
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-plan-spec.js +0 -64
- 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 -660
- 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 -388
- 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-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -384
- 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 -278
- 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/skill-capsule-loader.js +0 -109
- 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 -301
- 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/plan-critics.js +0 -199
- package/.agents/scripts/retro-run.js +0 -218
- 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 -335
- package/.agents/skills/core/baseline-refresh/SKILL.md +0 -181
- package/.agents/skills/core/ci-cd-and-automation/SKILL.md +0 -274
- package/.agents/skills/core/ci-cd-and-automation/examples.md +0 -211
- package/.agents/skills/core/code-simplification/SKILL.md +0 -389
- package/.agents/skills/core/context-engineering/SKILL.md +0 -309
- package/.agents/skills/core/context-engineering/examples.md +0 -58
- package/.agents/skills/core/deprecation-and-migration/SKILL.md +0 -250
- 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 -413
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/skills/core/frontend-ui-engineering/SKILL.md +0 -357
- package/.agents/skills/core/hydrate-context/SKILL.md +0 -123
- package/.agents/skills/core/idea-refinement/examples.md +0 -437
- package/.agents/skills/core/idea-refinement/frameworks.md +0 -135
- package/.agents/skills/core/incremental-implementation/SKILL.md +0 -271
- package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +0 -213
- package/.agents/skills/core/knowledge-transfer/SKILL.md +0 -180
- package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +0 -117
- package/.agents/skills/core/performance-optimization/SKILL.md +0 -314
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +0 -277
- package/.agents/skills/core/property-based-testing/SKILL.md +0 -148
- package/.agents/skills/core/refactoring-discipline/SKILL.md +0 -111
- package/.agents/skills/core/shipping-and-launch/SKILL.md +0 -328
- package/.agents/skills/core/spec-driven-development/SKILL.md +0 -252
- package/.agents/skills/core/test-driven-development/SKILL.md +0 -475
- package/.agents/skills/core/using-agent-skills/SKILL.md +0 -232
- package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +0 -31
- package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +0 -51
- package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +0 -76
- package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +0 -33
- package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +0 -31
- package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +0 -51
- package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +0 -54
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +0 -29
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +0 -30
- package/.agents/skills/stack/backend/stripe-integration/SKILL.md +0 -57
- package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +0 -9
- package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +0 -48
- package/.agents/skills/stack/frontend/astro/SKILL.md +0 -62
- package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +0 -30
- package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +0 -29
- package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +0 -50
- package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +0 -58
- package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +0 -34
- package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +0 -51
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +0 -199
- package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +0 -68
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -534
- package/.agents/workflows/helpers/deliver-epic.md +0 -955
- package/.agents/workflows/helpers/deliver-stories.md +0 -440
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -427
- 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 -351
- 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,68 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: backend-security-patterns
|
|
3
|
-
description:
|
|
4
|
-
Combined backend protocols for authentication (Clerk JWT verification) and
|
|
5
|
-
PII-safe observability. Use when handling auth on the server, verifying
|
|
6
|
-
Clerk webhooks via `svix`, scoping metadata via `publicMetadata`/
|
|
7
|
-
`privateMetadata`, or sanitizing logs to keep emails, tokens, and request
|
|
8
|
-
bodies out of telemetry.
|
|
9
|
-
vendor: clerk
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Skill: Backend Security Patterns
|
|
13
|
-
|
|
14
|
-
## Policy Capsule
|
|
15
|
-
|
|
16
|
-
- Verify Clerk JWTs on the server or in middleware on every protected route; never trust client-asserted auth state.
|
|
17
|
-
- Protect sensitive routes with Clerk's middleware helper so unauthenticated requests are redirected before hitting application logic.
|
|
18
|
-
- Verify Clerk webhook signatures with the `svix` library before parsing payloads.
|
|
19
|
-
- Store user state in `publicMetadata` (client-readable) or `privateMetadata` (server-only); never invent a parallel user store.
|
|
20
|
-
- Never log raw request bodies, headers, or user objects that may contain PII (emails, DOB, IPs, Stripe tokens, passwords, JWTs).
|
|
21
|
-
- Log entities by opaque ID only — e.g. `{ event: 'user_created', userId: user.id }`.
|
|
22
|
-
- For Clerk-flow telemetry, log the Clerk user ID or session ID — never the email, name, or metadata payload.
|
|
23
|
-
- Sanitize user input before including it in error logs so payloads cannot smuggle PII through the error path.
|
|
24
|
-
|
|
25
|
-
Combined protocols for authentication (Clerk) and PII-safe observability in
|
|
26
|
-
backend services.
|
|
27
|
-
|
|
28
|
-
## 1. Authentication (Clerk)
|
|
29
|
-
|
|
30
|
-
### Core Principles
|
|
31
|
-
|
|
32
|
-
- **Security First:** Never trust the client. Always verify JWTs on the server
|
|
33
|
-
or in middleware.
|
|
34
|
-
- **Zero-Boilerplate Auth:** Use Clerk's built-in components (`<SignIn>`,
|
|
35
|
-
`<SignUp>`, `<UserButton>`) to maintain UI consistency and security standards.
|
|
36
|
-
- **Metadata Management:** Store application-specific user state in
|
|
37
|
-
`publicMetadata` (read-only by client) or `privateMetadata` (server-only).
|
|
38
|
-
|
|
39
|
-
### Technical Standards
|
|
40
|
-
|
|
41
|
-
- **Middleware:** Protect sensitive routes using Clerk's middleware helper so
|
|
42
|
-
non-authenticated users are redirected before hitting application logic.
|
|
43
|
-
- **Webhooks:** Verify Clerk webhooks using the `svix` library to ensure
|
|
44
|
-
requests originate from Clerk.
|
|
45
|
-
- **Session Tokens:** Use short-lived sessions and handle expired tokens
|
|
46
|
-
gracefully.
|
|
47
|
-
|
|
48
|
-
### Best Practices
|
|
49
|
-
|
|
50
|
-
- **OAuth Providers:** Prefer standard social logins (Google, GitHub) to reduce
|
|
51
|
-
user friction.
|
|
52
|
-
- **Customization:** Use Clerk's theme API to align auth components with the
|
|
53
|
-
project's styling system.
|
|
54
|
-
- **Multi-tenant:** Use Clerk Organizations for applications requiring teams or
|
|
55
|
-
workspaces.
|
|
56
|
-
|
|
57
|
-
## 2. Telemetry & PII Logging
|
|
58
|
-
|
|
59
|
-
### Rules
|
|
60
|
-
|
|
61
|
-
- NEVER log raw request bodies, headers, or user objects that might contain PII
|
|
62
|
-
(Emails, DOB, IP Addresses, Stripe Tokens, Passwords, JWTs).
|
|
63
|
-
- Log entities by opaque ID only (e.g.,
|
|
64
|
-
`logger.info({ event: 'user_created', userId: user.id })`).
|
|
65
|
-
- For errors, log `error.message` and a safe contextual stack trace, but
|
|
66
|
-
sanitize any user input that caused the error before logging.
|
|
67
|
-
- When instrumenting Clerk flows specifically, log the Clerk user ID or session
|
|
68
|
-
ID — never the email, name, or metadata payload.
|
|
@@ -1,534 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: >-
|
|
3
|
-
Reference companion to `helpers/deliver-epic.md` — the recovery
|
|
4
|
-
procedures, historical rationale, and troubleshooting detail lifted out
|
|
5
|
-
of the runtime core so the always-ingested Epic-delivery prose stays lean.
|
|
6
|
-
Not a slash command; consulted on demand when the core file points here.
|
|
7
|
-
caller: helpers/deliver-epic.md
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# helpers/deliver-epic — reference (recovery, rationale, troubleshooting)
|
|
11
|
-
|
|
12
|
-
> **Not a slash command, not the runtime path.** This file is the
|
|
13
|
-
> reference companion to [`deliver-epic.md`](deliver-epic.md). The core
|
|
14
|
-
> file carries the phase flow, commands, gate contracts, and return shapes
|
|
15
|
-
> a `/deliver` run needs on every beat; this file holds the recovery
|
|
16
|
-
> procedures, the "why it works this way" rationale, and the
|
|
17
|
-
> troubleshooting detail the core points at with one-line pointers. Read a
|
|
18
|
-
> section here only when the matching pointer in the core sends you.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Phase 1 — Preflight guards (Story #3482 / F-workflow-guards)
|
|
23
|
-
|
|
24
|
-
Before the snapshot phase runs — and before any worktree is created —
|
|
25
|
-
`epic-deliver-prepare.js` runs two **fail-closed** guards
|
|
26
|
-
([`lib/orchestration/epic-deliver-lease-guard.js`](../../scripts/lib/orchestration/epic-deliver-lease-guard.js)):
|
|
27
|
-
|
|
28
|
-
1. **Checkout safety.** Prepare refuses to start when the working tree is
|
|
29
|
-
dirty or HEAD is on a branch other than the expected one (`epic/<id>`
|
|
30
|
-
on a resume, or the project base branch on a fresh run). It will
|
|
31
|
-
**not** check `epic/<id>` out over your work — the historic
|
|
32
|
-
HEAD-yank footgun. Remediation: commit/stash/clean the tree, or
|
|
33
|
-
switch to the expected branch, then re-run.
|
|
34
|
-
2. **Epic lease.** Prepare acquires the assignee-as-lease on the Epic
|
|
35
|
-
ticket (`ticket-lease.acquireLease`). On a **live foreign claim**
|
|
36
|
-
(a teammate's run with a fresh `story.heartbeat` within
|
|
37
|
-
`delivery.lease.ttlMs`) it exits non-zero and names the current owner;
|
|
38
|
-
a **stale** claim is silently reclaimed. The operator identity is
|
|
39
|
-
resolved from `--as <handle>` → `github.operatorHandle` →
|
|
40
|
-
`git config user.email`. Pass `--steal` to forcibly transfer a live
|
|
41
|
-
foreign claim (the takeover is logged for auditability). The committed
|
|
42
|
-
`github.operatorHandle` is the non-personal `@[USERNAME]` placeholder,
|
|
43
|
-
which resolves to null — so when none of the three sources yields a real
|
|
44
|
-
identity the guard **fails closed** (throws after the checkout guard
|
|
45
|
-
runs) rather than driving an ownerless, unguarded delivery. Set your own
|
|
46
|
-
handle in `.agentrc.local.json`, pass `--as <handle>`, or configure
|
|
47
|
-
`git user.email`. The lease is the cross-clone coordination layer, while
|
|
48
|
-
`epic-merge-lock.js` continues to serialize same-machine sessions.
|
|
49
|
-
|
|
50
|
-
Both guards throw on failure, which `runAsCli` maps to `process.exit(1)`
|
|
51
|
-
per [`orchestration-error-handling.md`](../../rules/orchestration-error-handling.md).
|
|
52
|
-
|
|
53
|
-
### Acceptance-table start gate
|
|
54
|
-
|
|
55
|
-
Once the preflight guards pass, the snapshot phase applies one more gate.
|
|
56
|
-
Before the wave loop fans out, the snapshot phase
|
|
57
|
-
([`lib/orchestration/epic-runner/phases/snapshot.js`](../../scripts/lib/orchestration/epic-runner/phases/snapshot.js))
|
|
58
|
-
asserts that the Epic either carries the `acceptance::n-a` waiver label
|
|
59
|
-
**or** has a `## Acceptance Table` managed section in its body — section
|
|
60
|
-
presence is sufficient. The reviewer's OK during `/plan` Phase 7 is the
|
|
61
|
-
approval signal. Neither condition met → the snapshot throws a clear error
|
|
62
|
-
(`[epic-deliver] Epic #<id> cannot launch: …` — naming the missing
|
|
63
|
-
`## Acceptance Table` section and the absent waiver) and `runAsCli` maps it
|
|
64
|
-
to `process.exit(1)`. Operator remediation: either run `/plan` Phase 7 to
|
|
65
|
-
author the acceptance table, or apply the `acceptance::n-a` label to opt
|
|
66
|
-
out.
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Phase 2 — Dispatch rationale and recovery
|
|
71
|
-
|
|
72
|
-
### Throughput tradeoff
|
|
73
|
-
|
|
74
|
-
The default `concurrencyCap` of 3 is the GLOBAL in-flight cap,
|
|
75
|
-
intentionally conservative — it keeps host-quota consumption low and avoids
|
|
76
|
-
flooding the GitHub API. For Epics with wide dependency-free fronts where
|
|
77
|
-
the host has adequate parallel-agent quota, raising
|
|
78
|
-
`delivery.deliverRunner.concurrencyCap` in `.agentrc.json` reduces
|
|
79
|
-
wall-clock time proportionally to the extra concurrency. The safe default
|
|
80
|
-
is left in place; this is a deliberate operator-tuning knob, not a hidden
|
|
81
|
-
performance ceiling. See `agentrc-reference.json`
|
|
82
|
-
`delivery.deliverRunner.concurrencyCap` for the configuration surface.
|
|
83
|
-
|
|
84
|
-
### Sub-agent dispatch capability
|
|
85
|
-
|
|
86
|
-
`Agent` calls emit no `model:` argument by default — children inherit from
|
|
87
|
-
the `general-purpose` sub-agent definition and the parent's worktree
|
|
88
|
-
context. No `--dangerously-skip-permissions` (no subprocess is spawned).
|
|
89
|
-
Per [`.agents/instructions.md` § 4](../../instructions.md)'s cost-aware
|
|
90
|
-
spawning heuristic, this optional per-call `model:` is the escape hatch: if
|
|
91
|
-
a specific call would run better on a cheaper or faster capability the host
|
|
92
|
-
exposes (a mechanical or read-only Story), pass `model:` as a per-call
|
|
93
|
-
literal at the `Agent(...)` site. This is **guidance only** — it adds no
|
|
94
|
-
config key, requires no model argument, and names no specific model; the
|
|
95
|
-
host and operator own the concrete choice.
|
|
96
|
-
|
|
97
|
-
### Fail-closed on an old-shape checkpoint
|
|
98
|
-
|
|
99
|
-
If the Epic still carries a pre-ready-set (`plan` / `currentWave` /
|
|
100
|
-
`totalWaves`) `epic-run-state` checkpoint, the tick **refuses to run** and
|
|
101
|
-
throws an explicit operator message — re-run
|
|
102
|
-
`epic-deliver-prepare.js --epic <id>` to re-seed the checkpoint in the
|
|
103
|
-
per-Story-status shape, then re-run `/deliver`.
|
|
104
|
-
|
|
105
|
-
### Crash recovery (record step)
|
|
106
|
-
|
|
107
|
-
If the host crashed *after* a child finished but *before* its return was
|
|
108
|
-
recorded, the next `tick` re-derives that Story's state directly from its
|
|
109
|
-
live label (the tick reads labels every beat), so a done-but-unrecorded
|
|
110
|
-
Story is recognised as done and never re-dispatched — there is no
|
|
111
|
-
falsely-`complete` empty wave to recover from. If you want to reconcile a
|
|
112
|
-
known-completed Story whose return text was lost, re-record it from its
|
|
113
|
-
live state by passing `--results '[{"storyId":<n>,"status":"done"}]'`
|
|
114
|
-
(verification re-checks the live label before recording `done`).
|
|
115
|
-
|
|
116
|
-
### 2e. Idle Watchdog
|
|
117
|
-
|
|
118
|
-
A Story's implementation loop can run for many minutes between
|
|
119
|
-
`story.dispatch.start` and the post-merge `story.merged` record. While
|
|
120
|
-
`observe` keeps the host LLM polling the Epic, it does **not** flag a
|
|
121
|
-
sub-agent that has gone silent (host crash, mid-Story stall, lost
|
|
122
|
-
return). The Idle Watchdog closes that gap.
|
|
123
|
-
|
|
124
|
-
**Cadence.** While any Story is in flight (i.e. `nextAction.kind` is
|
|
125
|
-
`observe` or the most recent dispatch's `in-flight` list is non-empty),
|
|
126
|
-
re-tick every **30 minutes** with the watchdog flag:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
node .agents/scripts/wave-tick.js --epic <epicId> --check-idle 30
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
> **Why 30, not 10 (Story #3900).** Heartbeats fire only at Story-level
|
|
133
|
-
> phase transitions, and `implementing → closing` routinely exceeds 10
|
|
134
|
-
> minutes for a healthy Story. A 10-minute threshold therefore tripped the
|
|
135
|
-
> watchdog on every long-running Story, whose prescribed remediation —
|
|
136
|
-
> re-dispatch — put two agents on one `story-<id>` branch (the worst
|
|
137
|
-
> failure mode in the system). The threshold is widened to 30 minutes and
|
|
138
|
-
> the staleness test now also consults a deterministic branch-commit
|
|
139
|
-
> signal (below), so a Story still gaining commits is never flagged.
|
|
140
|
-
|
|
141
|
-
The `--check-idle <minutes>` mode scans the per-Epic lifecycle ledger
|
|
142
|
-
(`temp/epic-<epicId>/lifecycle.ndjson`) for Stories that carry a
|
|
143
|
-
`story.dispatch.start` without a matching `story.dispatch.end` (the
|
|
144
|
-
canonical in-flight list — see § 2a's `nextAction['in-flight']`), and
|
|
145
|
-
compares each in-flight Story's most recent ledger event (any
|
|
146
|
-
`story.*` event, notably the `story.heartbeat` records emitted by
|
|
147
|
-
`story-phase.js` at each Story-level phase transition) against the
|
|
148
|
-
threshold. **Before flagging a stall, it also checks the last commit on
|
|
149
|
-
`story-<id>` via `git log` (Story #3900): a Story whose branch carries a
|
|
150
|
-
commit newer than the threshold is making forward progress and is left
|
|
151
|
-
in-flight, never stalled — deterministic protection against the
|
|
152
|
-
false-positive re-dispatch hazard even when no heartbeat has landed.**
|
|
153
|
-
The CLI emits one envelope on stdout and exits non-zero when at least
|
|
154
|
-
one in-flight Story has been silent for ≥ the threshold:
|
|
155
|
-
|
|
156
|
-
```json
|
|
157
|
-
{
|
|
158
|
-
"kind": "wave-stall",
|
|
159
|
-
"epicId": <n>,
|
|
160
|
-
"thresholdMinutes": <n>,
|
|
161
|
-
"checkedAt": "<ISO-8601>",
|
|
162
|
-
"stalled": [{ "storyId": <n>, "lastEventAt": "<ISO-8601>", "idleMinutes": <n> }],
|
|
163
|
-
"inFlight": [<storyId>, ...]
|
|
164
|
-
}
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**On a stall.** When the watchdog exits non-zero, post the envelope
|
|
168
|
-
verbatim as a `wave-stall` structured comment on the Epic (use
|
|
169
|
-
[`post-structured-comment.js`](../../scripts/post-structured-comment.js)
|
|
170
|
-
with `--kind wave-stall`), then re-evaluate the affected Stories: if a
|
|
171
|
-
child sub-agent has crashed (no `story.dispatch.end`, no recent
|
|
172
|
-
heartbeat, no commit on `story-<id>`), re-dispatch the Story per § 2b of
|
|
173
|
-
the core incrementing the `--attempt` counter; if the child is alive but
|
|
174
|
-
genuinely blocked, flip the Story to `agent::blocked` and proceed per
|
|
175
|
-
§ 2d's `observe` branch.
|
|
176
|
-
|
|
177
|
-
Stop the watchdog cadence once `wave-tick.js` returns `epic-complete` —
|
|
178
|
-
there are no in-flight Stories left to monitor.
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
|
|
182
|
-
## Phase 6.5 — Post-wave integration gate (Epic #4131, F1/F4)
|
|
183
|
-
|
|
184
|
-
This phase runs **after** the Phase 2 wave loop reports `epic-complete` and
|
|
185
|
-
**before** the Phase 7 finalize emit opens the PR to `main`. Where every gate
|
|
186
|
-
before it (`selectAudits`, the cross-epic-leak guard `#3362`, diff-against-base,
|
|
187
|
-
the file-assumption gate) is **change-set-scoped** — it narrows its evidence to
|
|
188
|
-
the Epic's `changedFiles` — this is the one **deliberately-global** gate: its
|
|
189
|
-
evidence spans the **whole product**, not just the change set. The disease it
|
|
190
|
-
catches is the surface that each Story shipped correctly in isolation yet that
|
|
191
|
-
the assembled product cannot reach: a route nobody can navigate to, or a
|
|
192
|
-
persona journey that the integrated waves silently broke. A change-set lens
|
|
193
|
-
never sees that, because no single Story's diff contains the orphan.
|
|
194
|
-
|
|
195
|
-
Skip when `--skip-integration-gate` (log the override; record a manual
|
|
196
|
-
intervention per [§ Recording manual interventions](#recording-manual-interventions)).
|
|
197
|
-
The gate is otherwise **always evaluated**, but it is a **silent no-op when
|
|
198
|
-
unconfigured** (see *No-op when unconfigured* below) so consumers who ship no
|
|
199
|
-
nav config and no journey suite are unaffected.
|
|
200
|
-
|
|
201
|
-
### 6.5a — Whole-product navigability (reuses the Phase 4 lens)
|
|
202
|
-
|
|
203
|
-
Run the `navigability` lens
|
|
204
|
-
([`audit-navigability.md`](../audit-navigability.md), the deliberately-global
|
|
205
|
-
lens delivered in this Epic's wave 0) in **whole-route mode** against the
|
|
206
|
-
integrated `epic/<epicId>` tip. Unlike its Phase 4 change-set-routed invocation,
|
|
207
|
-
here it is driven explicitly over the consumer's **entire** route tree + nav
|
|
208
|
-
registry — it is on the global-lens allowlist (`GLOBAL_LENS_ALLOWLIST` in
|
|
209
|
-
[`lib/audit-suite/selector.js`](../../scripts/lib/audit-suite/selector.js)) and
|
|
210
|
-
exempt from the cross-epic-leak guard `#3362`, so a route orphaned anywhere in
|
|
211
|
-
the product is in scope even when no Story in this Epic touched it.
|
|
212
|
-
|
|
213
|
-
The lens reads the consumer's navigability config (resolved from `.agentrc.json`):
|
|
214
|
-
|
|
215
|
-
- `delivery.quality.navigability.routeGlobs` — the route-tree SSOT the lens
|
|
216
|
-
enumerates.
|
|
217
|
-
- `delivery.quality.navigability.navRegistry` — the nav-registry SSOT the lens
|
|
218
|
-
cross-checks every route against.
|
|
219
|
-
|
|
220
|
-
A whole-product finding is a **hard failure**: an **orphaned route** (a route
|
|
221
|
-
with no nav door for any entitled persona) or a **dead nav href** (a nav door
|
|
222
|
-
pointing at a route that no longer exists). On a hard failure the gate **blocks
|
|
223
|
-
finalize** and names the orphaned surface (route identifier / nav-door
|
|
224
|
-
identifier only — never the route body or persona PII, per
|
|
225
|
-
`security-baseline.md`). Do **not** proceed to Phase 7.
|
|
226
|
-
|
|
227
|
-
### 6.5b — Consumer journey suite
|
|
228
|
-
|
|
229
|
-
Run the consumer's per-persona journey suite — the integrated, cross-Epic
|
|
230
|
-
persona-journey verification — over the `epic/<epicId>` tip:
|
|
231
|
-
|
|
232
|
-
- `delivery.quality.navigability.journeySuite` — path/command for the journey
|
|
233
|
-
suite. Absent ⇒ this sub-step is skipped (no-op).
|
|
234
|
-
|
|
235
|
-
A failing journey (a persona cannot complete an end-to-end journey through the
|
|
236
|
-
assembled product) is a **hard failure**: block finalize and name the broken
|
|
237
|
-
journey. This is the runtime complement to 6.5a's static reachability check —
|
|
238
|
-
6.5a proves a door exists; the journey suite proves the door, and everything
|
|
239
|
-
behind it, actually works when the waves are integrated.
|
|
240
|
-
|
|
241
|
-
### 6.5c — `@pending` ≠ green for surface-adding Epics (F4)
|
|
242
|
-
|
|
243
|
-
The Phase 7 finalize chain runs the acceptance-spec reconciler
|
|
244
|
-
([`acceptance-spec-reconciler.js`](../../scripts/acceptance-spec-reconciler.js)),
|
|
245
|
-
which classifies every AC ID into `satisfied` (covered by a non-pending
|
|
246
|
-
scenario), `pending` (covered **only** by scenarios tagged `@pending`), or
|
|
247
|
-
`missing`. For a **surface-adding Epic** — one whose risk verdict carries a
|
|
248
|
-
surface-adding signal (a route-adding change set, the `navigability` lens routed
|
|
249
|
-
in Phase 4, or a configured `routeGlobs` match) — this phase tightens that
|
|
250
|
-
contract: an AC whose coverage is **only `@pending`** is treated as
|
|
251
|
-
**unsatisfied**, not green. A surface-adding Epic whose acceptance coverage is
|
|
252
|
-
**only `@pending`** therefore **fails the close gate** instead of passing —
|
|
253
|
-
shipping a new surface behind a deferred-forever `@pending` scenario is exactly
|
|
254
|
-
the late-gate gap this Epic exists to close.
|
|
255
|
-
|
|
256
|
-
This is **purely additive** and **scoped to surface-adding Epics**:
|
|
257
|
-
refactor-only and docs-only Epics (no surface-adding signal) are **unaffected** —
|
|
258
|
-
their `@pending` handling is exactly as before, and the existing
|
|
259
|
-
`satisfied` / `missing` reconciliation is **not** de-scoped for any Epic.
|
|
260
|
-
|
|
261
|
-
### No-op when unconfigured
|
|
262
|
-
|
|
263
|
-
With **no** navigability config (`routeGlobs` / `navRegistry`) and **no**
|
|
264
|
-
`journeySuite` present in `.agentrc.json`, this entire phase degrades to a
|
|
265
|
-
**silent no-op**: 6.5a and 6.5b skip (nothing to enumerate or run) and 6.5c's
|
|
266
|
-
surface-adding signal cannot fire without route globs, so the `@pending`
|
|
267
|
-
tightening never engages. The gate adds **zero** behaviour to an unconfigured
|
|
268
|
-
consumer — it neither blocks finalize nor changes the existing change-set-scoped
|
|
269
|
-
gates. The override flag `--skip-integration-gate` is the explicit operator
|
|
270
|
-
escape hatch (consistent with `--skip-epic-audit`) for a configured consumer who
|
|
271
|
-
wants to bypass the gate for a specific run.
|
|
272
|
-
|
|
273
|
-
### Fail safe and loud
|
|
274
|
-
|
|
275
|
-
Per the Tech Spec's security note, this gate sits on the **critical path** to
|
|
276
|
-
finalize. It MUST fail **safe and loud**: a hard failure **blocks** finalize and
|
|
277
|
-
**names the cause** (the orphaned route, dead href, broken journey, or
|
|
278
|
-
`@pending`-only AC), never silently passes. A genuinely unconfigured consumer is
|
|
279
|
-
the **only** silent path, and that path **passes** (it is a no-op, not a block).
|
|
280
|
-
On a hard failure, post a friction structured comment naming the surface, flip
|
|
281
|
-
the Epic to `agent::blocked`, and park for the operator — do **not** open the PR.
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
## Phase 7 — Finalize (close-tail listener chain)
|
|
286
|
-
|
|
287
|
-
### 7.0 — Sync Epic branch from `main` (Story #2580)
|
|
288
|
-
|
|
289
|
-
Before firing the close-tail emit, sync the Epic branch with
|
|
290
|
-
`origin/main` so the PR opens with the latest base commits already
|
|
291
|
-
integrated. The Epic branch may be behind `main` if other PRs merged
|
|
292
|
-
during the wave loop; without this step, the Epic→`main` PR opens
|
|
293
|
-
"behind base" and (with branch-protection's `up-to-date branch` rule)
|
|
294
|
-
stalls at the merge gate.
|
|
295
|
-
|
|
296
|
-
```bash
|
|
297
|
-
git checkout epic/<epicId>
|
|
298
|
-
node .agents/scripts/sync-branch-from-base.js \
|
|
299
|
-
--branch epic/<epicId> --base main
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
Outcomes:
|
|
303
|
-
|
|
304
|
-
- **`fast-forward` / `merge-commit` / `noop-already-current`** → push
|
|
305
|
-
the resulting tip and continue to Phase 7.1: `git push origin epic/<epicId>`.
|
|
306
|
-
- **`conflict`** → resolve in the Epic checkout (`git merge --no-edit
|
|
307
|
-
origin/main`, fix conflicts, `git commit --no-edit`), then re-run the
|
|
308
|
-
sync command. Once it exits 0, continue. Operator-recoverable; not an
|
|
309
|
-
agent loop.
|
|
310
|
-
- **`fetch-failed`** → re-check network / `origin` access and re-run.
|
|
311
|
-
|
|
312
|
-
This is a workflow-level step (operator-driven), not part of the
|
|
313
|
-
close-tail listener chain. The sync runs from the main checkout so
|
|
314
|
-
the resulting tip lands on `epic/<epicId>` before Phase 7.1 fires
|
|
315
|
-
the bus-driven close-tail.
|
|
316
|
-
|
|
317
|
-
### 7.1 — Close-tail listener chain
|
|
318
|
-
|
|
319
|
-
`node .agents/scripts/lifecycle-emit.js --epic <epicId> --event epic.close.end`
|
|
320
|
-
emits `epic.close.end` onto the lifecycle bus. **Every close-time
|
|
321
|
-
responsibility below runs inside the listener chain — the operator
|
|
322
|
-
shells nothing manually. The `Finalizer` listener (Story #2894 —
|
|
323
|
-
bus-owned finalize) composes three helpers under
|
|
324
|
-
`.agents/scripts/lib/orchestration/finalize/` and emits the canonical
|
|
325
|
-
chain.** Treat this section as a runtime contract — `/deliver`
|
|
326
|
-
just fires the emit and reads the resulting ledger.
|
|
327
|
-
|
|
328
|
-
1. **Acceptance-table reconciliation — bus-driven.** The
|
|
329
|
-
`AcceptanceReconciler` listener invokes
|
|
330
|
-
[`acceptance-spec-reconciler.js`](../../scripts/acceptance-spec-reconciler.js)
|
|
331
|
-
to diff the AC IDs declared in the Epic body's `## Acceptance Table`
|
|
332
|
-
section against `@ac-*` / `@pending` tags in `tests/features/**`,
|
|
333
|
-
recording each row's verification outcome
|
|
334
|
-
(`satisfied` / `pending` / `missing`) into the table's Disposition
|
|
335
|
-
column via a section-scoped upsert of the Epic body. A
|
|
336
|
-
non-OK reconciliation throws (per
|
|
337
|
-
[`rules/orchestration-error-handling.md`](../../rules/orchestration-error-handling.md)),
|
|
338
|
-
aborting finalize **before** any PR is opened — so the Epic stays
|
|
339
|
-
unfinalized until the AC coverage gap is fixed. The reconciler returns
|
|
340
|
-
`status: 'waived'` without scanning features when the Epic carries
|
|
341
|
-
`acceptance::n-a`, and defends against direct CLI invocation by
|
|
342
|
-
refusing to run when the body has no `## Acceptance Table` section
|
|
343
|
-
and no waiver is set (the
|
|
344
|
-
start gate in Phase 1 would normally catch that first).
|
|
345
|
-
2. **PR open / ready — bus-driven (Story #2894; earlyPr split Story
|
|
346
|
-
#4359).** On `acceptance.reconcile.ok` the `Finalizer` listener
|
|
347
|
-
resolves `delivery.ci.earlyPr` via
|
|
348
|
-
[`getCiDelivery`](../../scripts/lib/config/ci.js) (default `true`) and
|
|
349
|
-
branches:
|
|
350
|
-
- **`earlyPr` on (default)** — the Epic PR already exists as a draft
|
|
351
|
-
(Phase 2 opened it at wave 1 with
|
|
352
|
-
[`openOrLocatePr`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
|
|
353
|
-
`{ draft: true }`). Finalize locates it and flips it ready-for-review
|
|
354
|
-
via
|
|
355
|
-
[`markPrReady`](../../scripts/lib/orchestration/finalize/open-or-locate-pr.js)
|
|
356
|
-
rather than creating a PR. `gh pr ready` on an already-ready PR is a
|
|
357
|
-
no-op, so replay is idempotent.
|
|
358
|
-
- **`earlyPr` off** — finalize invokes `openOrLocatePr` with
|
|
359
|
-
`{ epicId, headBranch: 'epic/<id>', baseBranch: 'main' }` (no
|
|
360
|
-
`draft`). The helper probes for an existing open PR on the head branch
|
|
361
|
-
first (idempotent locate path — a re-run of `/deliver` on the same
|
|
362
|
-
branch short-circuits without opening a duplicate) and only opens a
|
|
363
|
-
new PR when none exists.
|
|
364
|
-
|
|
365
|
-
In both modes the PR title/body contract (`feat: Epic #<id>` /
|
|
366
|
-
`Closes #<id>`) is identical. The listener then
|
|
367
|
-
emits `pr.created` → `epic.finalize.end` and **stops** (Story
|
|
368
|
-
#3367). It does **not** emit `epic.merge.ready`: that event is
|
|
369
|
-
the sole `AutomergeArmer` trigger, and emitting it from finalize
|
|
370
|
-
would cascade `epic.close.end` synchronously through the arm →
|
|
371
|
-
`MergeWatcher` → `Cleaner` → `BranchCleaner` reap, deleting the
|
|
372
|
-
`epic/<id>` branch before the PR merged and bypassing the
|
|
373
|
-
`AutomergePredicate` disqualification gate. The auto-merge arm is
|
|
374
|
-
driven later from the gated watch path (`pr.created` → `Watcher`
|
|
375
|
-
→ `epic.watch.end` → `AutomergePredicate` → `epic.merge.ready` →
|
|
376
|
-
`AutomergeArmer`) re-entered in Phase 8.5. The merge-lockout rule
|
|
377
|
-
in [`check-lifecycle-lint.js`](../../scripts/check-lifecycle-lint.js)
|
|
378
|
-
keeps `gh pr merge --auto --squash --delete-branch` confined to
|
|
379
|
-
`AutomergeArmer` — Phase 7 never shells the merge command.
|
|
380
|
-
3. **Hand-off — bus-driven (Story #2894).** After `openOrLocatePr`
|
|
381
|
-
returns, the `Finalizer` chains
|
|
382
|
-
[`postHandoffComment`](../../scripts/lib/orchestration/finalize/post-handoff-comment.js)
|
|
383
|
-
to upsert the canonical `epic-handoff` structured comment naming
|
|
384
|
-
the PR URL. The helper is idempotent — the handoff comment is
|
|
385
|
-
edited in place via `upsertStructuredComment` rather than
|
|
386
|
-
appending a duplicate. There is **no planning-ticket close sweep**
|
|
387
|
-
(Story #4324): the planning artifacts live as sections of the Epic
|
|
388
|
-
body itself, so there are no context tickets to close and nothing
|
|
389
|
-
blocks the Epic's `Closes #<id>` auto-close path.
|
|
390
|
-
|
|
391
|
-
Branch cleanup is out-of-band (Phase 9 reaps local refs after merge; the
|
|
392
|
-
rare "scrap and reset" case for an unmerged Epic is handled manually).
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
## Phase 8 — Watch-and-iterate remediation
|
|
397
|
-
|
|
398
|
-
### 8.1 Remediation
|
|
399
|
-
|
|
400
|
-
For each failed required check: fetch the log
|
|
401
|
-
(`gh run view <runId> --log-failed`), classify and fix:
|
|
402
|
-
|
|
403
|
-
- **lint / format** → `npm run lint` + `npx biome check --apply` (or
|
|
404
|
-
`format --write`); commit, push.
|
|
405
|
-
- **maintainability / crap baseline drift** → re-run the ratcheted
|
|
406
|
-
script. Refresh the baseline only when drift is justified by the
|
|
407
|
-
diff; otherwise fix at source.
|
|
408
|
-
- **test failure** → reproduce with `npm test`, fix source or test.
|
|
409
|
-
- **coverage threshold** → add tests (preferred); refresh baseline only
|
|
410
|
-
when the diff demonstrably can't be covered.
|
|
411
|
-
- **anything else** → read the log, fix at source.
|
|
412
|
-
|
|
413
|
-
Push to `epic/<epicId>` and re-run
|
|
414
|
-
`node <agentRoot>/scripts/pr-watch-with-update.js --pr <prNumber>`.
|
|
415
|
-
|
|
416
|
-
### 8.2 When to halt
|
|
417
|
-
|
|
418
|
-
Three consecutive iterations on the same failure class without
|
|
419
|
-
convergence → friction comment, flip to `agent::blocked`, park. Unknown
|
|
420
|
-
failure class on first encounter → attempt source-level fix; log
|
|
421
|
-
friction if diagnosis takes more than one round.
|
|
422
|
-
|
|
423
|
-
### 8.3 Hard prohibitions
|
|
424
|
-
|
|
425
|
-
**Never** `gh pr merge` from Phase 8 (Phase 8.5 is the only merge
|
|
426
|
-
site). **Never** force-push to `main`. **Never** push empty commits or
|
|
427
|
-
refresh baselines to dodge a red check.
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
## Phase 8.5 — Auto-merge predicate detail
|
|
432
|
-
|
|
433
|
-
`AutomergePredicate` subscribes to `epic.automerge.start` (Story #3901 —
|
|
434
|
-
before that this event had **zero** subscribers and the entire Phase 8.5
|
|
435
|
-
gate was a dead wire). It evaluates the structured-signal verdict and
|
|
436
|
-
emits `epic.merge.ready` on a clean verdict or `epic.merge.blocked`
|
|
437
|
-
otherwise. The CI-freshness gate is skipped on this event because Phase 8
|
|
438
|
-
already polled every required check to green — `epic.automerge.start`
|
|
439
|
-
carries `prUrl` but no `checkOutcomes`.
|
|
440
|
-
|
|
441
|
-
The `AutomergeArmer` listener subscribes to the downstream
|
|
442
|
-
`epic.merge.ready` outcome and fires `gh pr merge --auto --squash
|
|
443
|
-
--delete-branch` only when `clean: true`. `clean: true` requires
|
|
444
|
-
**all** of:
|
|
445
|
-
|
|
446
|
-
- `state.manualInterventions[]` is empty;
|
|
447
|
-
- every wave's `status === "complete"`;
|
|
448
|
-
- no story envelope carries a `blockerCommentId` or non-`done` status;
|
|
449
|
-
- code-review reports `0` 🔴 + `0` 🟠 findings;
|
|
450
|
-
- the retro's machine-readable `automerge-verdict` trailer reports
|
|
451
|
-
`cleanSprint: true` (Story #3901 — the predicate reads the parsed JSON
|
|
452
|
-
trailer `retro-run.js` writes into the retro body, **not** an emoji
|
|
453
|
-
string-match on the human-facing "🟢 Clean sprint" prose).
|
|
454
|
-
|
|
455
|
-
When clean, the listener fires `gh pr merge --squash --delete-branch`.
|
|
456
|
-
Otherwise the listener records disqualifying reasons via
|
|
457
|
-
`epic.merge.blocked` and exits without merging — operator merges
|
|
458
|
-
manually.
|
|
459
|
-
|
|
460
|
-
### Recording manual interventions
|
|
461
|
-
|
|
462
|
-
Whenever you step outside the happy path during a delivery, record it
|
|
463
|
-
(each entry disqualifies auto-merge):
|
|
464
|
-
|
|
465
|
-
```bash
|
|
466
|
-
node .agents/scripts/epic-deliver-note-intervention.js \
|
|
467
|
-
--epic <epicId> --reason "<one-line description>"
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
Triggers: `AskUserQuestion` mid-run; `git restore`/`reset` against the
|
|
471
|
-
tree; child-reported `--no-ff` recovery, stash dance, or out-of-band
|
|
472
|
-
merge surgery; child closes via `--skipValidation`; force-pushing or
|
|
473
|
-
empty-committing to dodge CI diagnosis.
|
|
474
|
-
|
|
475
|
-
---
|
|
476
|
-
|
|
477
|
-
## Phase 9 — Local branch cleanup detail
|
|
478
|
-
|
|
479
|
-
Phase 9 runs **automatically** inside the lifecycle bus once auto-merge
|
|
480
|
-
arms: the `BranchCleaner` listener subscribes to `epic.cleanup.start`
|
|
481
|
-
and reaps local refs before `Cleaner` archives the `temp/epic-<id>/`
|
|
482
|
-
tree. No operator step is required on the auto-merge path.
|
|
483
|
-
|
|
484
|
-
What gets reaped (in order, all in-process):
|
|
485
|
-
|
|
486
|
-
1. The main checkout is switched off `epic/<id>` to `baseBranch` when
|
|
487
|
-
needed (otherwise `git branch -D epic/<id>` is refused).
|
|
488
|
-
2. Every `story-<id>` listed in the `epic-run-state` checkpoint, plus
|
|
489
|
-
`epic/<id>`. Attached worktrees are removed with the standard
|
|
490
|
-
`git worktree remove` → `--force` → filesystem-rm fallback (the
|
|
491
|
-
last step covers Windows file-locks).
|
|
492
|
-
3. `git remote prune <remote>` drops stale `<remote>/...` tracking
|
|
493
|
-
refs left behind by `gh pr merge --delete-branch`.
|
|
494
|
-
4. The `wt-branch` scratch ref left by `story-close.js`'s internal
|
|
495
|
-
merge worktree is deleted when no worktree still points at it.
|
|
496
|
-
|
|
497
|
-
Per-branch failures aggregate into the listener's classification log
|
|
498
|
-
(`reaped` / `failed` / `no-state` / `skipped-duplicate`) and are
|
|
499
|
-
visible in `temp/epic-<id>/lifecycle.ndjson`. They do not block the
|
|
500
|
-
rest of cleanup.
|
|
501
|
-
|
|
502
|
-
For out-of-band cleanup re-entry (resume after a crash, or operator
|
|
503
|
-
override), fire `epic.merge.armed` via the lifecycle-emit helper:
|
|
504
|
-
|
|
505
|
-
```bash
|
|
506
|
-
node .agents/scripts/lifecycle-emit.js --epic <epicId> \
|
|
507
|
-
--event epic.merge.armed --pr-url <prUrl>
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
If Phase 8.5 fell back to the operator-merges-button path (`gh pr
|
|
511
|
-
merge --auto` was declined), the `epic.merge.armed` event never fires
|
|
512
|
-
inside this run and Phase 9 will not run automatically. **Do not** hand-reap
|
|
513
|
-
the refs with a raw `git branch -D` sequence — drive the same
|
|
514
|
-
`BranchCleaner`-backed reap the auto-merge path uses by firing
|
|
515
|
-
`epic.merge.armed` after the operator merges the PR:
|
|
516
|
-
|
|
517
|
-
```bash
|
|
518
|
-
node .agents/scripts/lifecycle-emit.js --epic <epicId> \
|
|
519
|
-
--event epic.merge.armed --pr-url <prUrl>
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
That single emit reaps `epic/<epicId>` and every `story-<id>` ref from the
|
|
523
|
-
checkpoint, prunes stale tracking refs, and fast-forwards local `main` to
|
|
524
|
-
`origin/main` — the whole Phase 9 reap, not a partial hand-roll. A plain
|
|
525
|
-
`git-cleanup.js` sweep alone will **not** catch the `story-<id>` refs here,
|
|
526
|
-
because the epic PR squash-merge breaks the `git branch --merged main` signal
|
|
527
|
-
and the stories never had their own PRs; the lifecycle-emit surface above is
|
|
528
|
-
the correct driver.
|
|
529
|
-
|
|
530
|
-
Re-running `/deliver <epicId>` reaches the same outcome without the manual
|
|
531
|
-
emit: the idempotent-resume auto-arm
|
|
532
|
-
(`detectMergedUncleanedEpic` → `armCleanupIfMerged` in
|
|
533
|
-
[`epic-cleanup.js`](../../scripts/lib/orchestration/epic-cleanup.js)) detects
|
|
534
|
-
the merged-but-uncleaned Epic and fires `epic.merge.armed` for you.
|