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,510 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* node:coverage ignore file */
|
|
3
|
-
/**
|
|
4
|
-
* lifecycle-emit.js — generic argv-driven emit helper (Story #2425 /
|
|
5
|
-
* Task #2434, Epic #2307).
|
|
6
|
-
*
|
|
7
|
-
* Replaces the three single-purpose emit shims
|
|
8
|
-
* (`epic-deliver-finalize.js`, `epic-deliver-automerge.js`,
|
|
9
|
-
* `epic-deliver-cleanup.js`) that the `/deliver` workflow markdown
|
|
10
|
-
* invoked in Phase 6, 7.5, and 8. Those shims each did exactly one
|
|
11
|
-
* thing: construct a bus and emit one event. Collapsing them into a
|
|
12
|
-
* single argv-driven CLI lets the workflow stay declarative ("fire
|
|
13
|
-
* <event> with <payload>") while keeping the lifecycle-bus contract
|
|
14
|
-
* untouched.
|
|
15
|
-
*
|
|
16
|
-
* Usage:
|
|
17
|
-
* node .agents/scripts/lifecycle-emit.js --epic <id> --event <name> \
|
|
18
|
-
* [--<field> <value>]*
|
|
19
|
-
*
|
|
20
|
-
* Examples:
|
|
21
|
-
* # Phase 6 — close-tail entry event
|
|
22
|
-
* node .agents/scripts/lifecycle-emit.js --epic 2307 \
|
|
23
|
-
* --event epic.close.end
|
|
24
|
-
*
|
|
25
|
-
* # Phase 7.5 — automerge wrapper start
|
|
26
|
-
* node .agents/scripts/lifecycle-emit.js --epic 2307 \
|
|
27
|
-
* --event epic.automerge.start \
|
|
28
|
-
* --pr-url https://github.com/dsj1984/mandrel/pull/123
|
|
29
|
-
*
|
|
30
|
-
* # Phase 8 — cleanup (epic.merge.armed)
|
|
31
|
-
* node .agents/scripts/lifecycle-emit.js --epic 2307 \
|
|
32
|
-
* --event epic.merge.armed \
|
|
33
|
-
* --pr-url https://github.com/dsj1984/mandrel/pull/123
|
|
34
|
-
*
|
|
35
|
-
* Argv → payload mapping:
|
|
36
|
-
* - `--event <name>` selects the lifecycle event. The CLI validates
|
|
37
|
-
* that `.agents/schemas/lifecycle/<event>.schema.json` exists
|
|
38
|
-
* before invoking the bus; an unknown event exits non-zero with a
|
|
39
|
-
* message pointing at the missing schema file.
|
|
40
|
-
* - `--epic <id>` is mapped to `epicId` (integer) for events whose
|
|
41
|
-
* schema requires it.
|
|
42
|
-
* - Any other `--<kebab-case> <value>` flag is mapped to a
|
|
43
|
-
* camelCase payload key. Values that look like integers are
|
|
44
|
-
* parsed; everything else is forwarded as a string. Schema
|
|
45
|
-
* validation in the bus catches type mismatches.
|
|
46
|
-
*
|
|
47
|
-
* Missing required payload fields surface via the bus's schema
|
|
48
|
-
* validator with `code: 'BUS_SCHEMA_VALIDATION'` and a non-zero exit.
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
import { existsSync } from 'node:fs';
|
|
52
|
-
import path from 'node:path';
|
|
53
|
-
import { fileURLToPath } from 'node:url';
|
|
54
|
-
|
|
55
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
56
|
-
import { epicLedgerPath } from './lib/config/temp-paths.js';
|
|
57
|
-
import { resolveConfig } from './lib/config-resolver.js';
|
|
58
|
-
import { appendEpicSignal } from './lib/observability/signals-writer.js';
|
|
59
|
-
import * as epicRunStateStoreModule from './lib/orchestration/epic-run-state-store.js';
|
|
60
|
-
import { createBus } from './lib/orchestration/lifecycle/bus.js';
|
|
61
|
-
import { buildDefaultListenerChain } from './lib/orchestration/lifecycle/listeners/index.js';
|
|
62
|
-
import {
|
|
63
|
-
STATE_LABELS,
|
|
64
|
-
transitionTicketState,
|
|
65
|
-
} from './lib/orchestration/ticketing.js';
|
|
66
|
-
import { createProvider } from './lib/provider-factory.js';
|
|
67
|
-
|
|
68
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
69
|
-
const DEFAULT_SCHEMA_DIR = path.resolve(
|
|
70
|
-
__dirname,
|
|
71
|
-
'..',
|
|
72
|
-
'schemas',
|
|
73
|
-
'lifecycle',
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Convert a kebab-case argv key (`pr-url`) to its camelCase payload
|
|
78
|
-
* counterpart (`prUrl`). Leading dashes have already been stripped by
|
|
79
|
-
* the argv parser.
|
|
80
|
-
*/
|
|
81
|
-
function toCamelCase(kebab) {
|
|
82
|
-
return kebab.replace(/-([a-z0-9])/g, (_, ch) => ch.toUpperCase());
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Best-effort coercion: argv strings that look like positive integers
|
|
87
|
-
* are parsed; the literals `true` / `false` coerce to booleans (so
|
|
88
|
-
* boolean-typed payload fields like `epic.automerge.end`'s `merged` flag
|
|
89
|
-
* pass schema validation from the workflow's `--merged true` invocation,
|
|
90
|
-
* Story #3901); everything else is forwarded as-is. Schema validation in
|
|
91
|
-
* the bus catches genuine type mismatches.
|
|
92
|
-
*/
|
|
93
|
-
function coerceValue(raw) {
|
|
94
|
-
if (typeof raw !== 'string') return raw;
|
|
95
|
-
if (raw === 'true') return true;
|
|
96
|
-
if (raw === 'false') return false;
|
|
97
|
-
if (/^-?\d+$/.test(raw)) {
|
|
98
|
-
const n = Number.parseInt(raw, 10);
|
|
99
|
-
if (Number.isInteger(n)) return n;
|
|
100
|
-
}
|
|
101
|
-
return raw;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Parse a flat argv array (`['--event', 'foo', '--epic', '42']`) into
|
|
106
|
-
* an object map of flag → value. Boolean flags are not supported — the
|
|
107
|
-
* helper is intentionally minimal and every value lands in the payload.
|
|
108
|
-
*/
|
|
109
|
-
export function parseArgv(argv) {
|
|
110
|
-
const out = {};
|
|
111
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
112
|
-
const tok = argv[i];
|
|
113
|
-
if (typeof tok !== 'string' || !tok.startsWith('--')) {
|
|
114
|
-
throw new Error(
|
|
115
|
-
`lifecycle-emit: unexpected positional argument: ${String(tok)}`,
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
const key = tok.slice(2);
|
|
119
|
-
const value = argv[i + 1];
|
|
120
|
-
if (
|
|
121
|
-
value === undefined ||
|
|
122
|
-
(typeof value === 'string' && value.startsWith('--'))
|
|
123
|
-
) {
|
|
124
|
-
throw new Error(`lifecycle-emit: --${key} requires a value`);
|
|
125
|
-
}
|
|
126
|
-
out[key] = value;
|
|
127
|
-
i += 1;
|
|
128
|
-
}
|
|
129
|
-
return out;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Argv keys that are runtime OPTIONS consumed by `main()` /
|
|
134
|
-
* `runLifecycleEmit()` directly rather than forwarded into the emitted
|
|
135
|
-
* bus payload. `--headless` (Story #4427) is the first member: every
|
|
136
|
-
* lifecycle event schema declares `additionalProperties: false`, so a
|
|
137
|
-
* flag that selects delivery-run behavior (rather than describing the
|
|
138
|
-
* event itself) would fail schema validation if it leaked into the
|
|
139
|
-
* payload.
|
|
140
|
-
*/
|
|
141
|
-
const RUNTIME_OPTION_KEYS = Object.freeze(['event', 'headless']);
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Build the bus emit payload from parsed argv. `event` and `headless`
|
|
145
|
-
* (see `RUNTIME_OPTION_KEYS`) are consumed as runtime options, not
|
|
146
|
-
* payload fields. `--epic` is mapped to `epicId` (integer). All other
|
|
147
|
-
* flags are mapped from kebab-case to camelCase with light value
|
|
148
|
-
* coercion.
|
|
149
|
-
*/
|
|
150
|
-
export function buildPayload(parsed) {
|
|
151
|
-
const payload = {};
|
|
152
|
-
for (const [key, raw] of Object.entries(parsed)) {
|
|
153
|
-
if (RUNTIME_OPTION_KEYS.includes(key)) continue;
|
|
154
|
-
if (key === 'epic') {
|
|
155
|
-
const n = Number.parseInt(raw, 10);
|
|
156
|
-
if (!Number.isInteger(n) || n < 1) {
|
|
157
|
-
throw new Error(
|
|
158
|
-
`lifecycle-emit: --epic must be a positive integer (got ${raw})`,
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
payload.epicId = n;
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
payload[toCamelCase(key)] = coerceValue(raw);
|
|
165
|
-
}
|
|
166
|
-
return payload;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* The listener-chain keys (as returned by `buildDefaultListenerChain`)
|
|
171
|
-
* whose listener instances carry a `classifications` array. Each listener
|
|
172
|
-
* records one `{ event, seqId, outcome, reason? }` entry per invocation
|
|
173
|
-
* (the "no silent skip" contract). We flatten every listener's
|
|
174
|
-
* classifications into a single `outcomes[]` array so the CLI can surface
|
|
175
|
-
* them and decide its exit code.
|
|
176
|
-
*/
|
|
177
|
-
const CLASSIFYING_LISTENER_KEYS = Object.freeze([
|
|
178
|
-
'acceptanceReconciler',
|
|
179
|
-
'finalizer',
|
|
180
|
-
'automergeArmer',
|
|
181
|
-
'automergePredicate',
|
|
182
|
-
'branchCleaner',
|
|
183
|
-
'mergeWatcher',
|
|
184
|
-
'cleaner',
|
|
185
|
-
]);
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Flatten the listener-chain's per-listener `classifications` arrays into
|
|
189
|
-
* a single ordered `outcomes[]` list. Each entry is tagged with the
|
|
190
|
-
* `listener` key it came from so an operator (or the retro substrate) can
|
|
191
|
-
* see WHICH listener classified WHAT.
|
|
192
|
-
*
|
|
193
|
-
* A `null`/`undefined` chain (caller-supplied bus, or no chain wired)
|
|
194
|
-
* yields an empty array — the CLI then has nothing to fail on, preserving
|
|
195
|
-
* the injected-bus test contract.
|
|
196
|
-
*
|
|
197
|
-
* @param {object|null} chain result of `buildDefaultListenerChain`
|
|
198
|
-
* @returns {Array<{ listener: string, event?: string, seqId?: number,
|
|
199
|
-
* outcome: string, reason?: string }>}
|
|
200
|
-
*/
|
|
201
|
-
export function collectOutcomes(chain) {
|
|
202
|
-
if (!chain || typeof chain !== 'object') return [];
|
|
203
|
-
const outcomes = [];
|
|
204
|
-
for (const key of CLASSIFYING_LISTENER_KEYS) {
|
|
205
|
-
const listener = chain[key];
|
|
206
|
-
const classifications = listener?.classifications;
|
|
207
|
-
if (!Array.isArray(classifications)) continue;
|
|
208
|
-
for (const c of classifications) {
|
|
209
|
-
if (!c || typeof c !== 'object') continue;
|
|
210
|
-
outcomes.push({ listener: key, ...c });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return outcomes;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Default operator-visible blocker signal. Fired by `runLifecycleEmit`
|
|
218
|
-
* when one or more listener classifications came back `failed` and an
|
|
219
|
-
* `epicId` is resolvable. It does two things, each best-effort:
|
|
220
|
-
*
|
|
221
|
-
* 1. Flips the Epic ticket to `agent::blocked` (the authoritative HITL
|
|
222
|
-
* runtime pause point per `instructions.md` § 1.J) via the canonical
|
|
223
|
-
* `transitionTicketState` API — but only when a `provider` is wired
|
|
224
|
-
* in. The standalone CLI is usable in repos with no `github` block,
|
|
225
|
-
* so a missing provider degrades to "signal-only".
|
|
226
|
-
* 2. Appends a `friction` signal to the per-Epic `signals.ndjson` stream
|
|
227
|
-
* so the failure is recorded out-of-band even when no provider is
|
|
228
|
-
* configured (the no-ticket fallback from § 1.H).
|
|
229
|
-
*
|
|
230
|
-
* Neither step throws: the CLI must still print its `outcomes[]` envelope
|
|
231
|
-
* and exit non-zero on the underlying failure regardless of whether the
|
|
232
|
-
* side-effect plumbing succeeded.
|
|
233
|
-
*
|
|
234
|
-
* @param {object} args
|
|
235
|
-
* @param {number} args.epicId resolved Epic id
|
|
236
|
-
* @param {string} args.event the lifecycle event that produced the failure
|
|
237
|
-
* @param {Array<object>} args.failedOutcomes the `outcome: 'failed'` entries
|
|
238
|
-
* @param {object|null} [args.provider] ticketing provider (label flip)
|
|
239
|
-
* @param {object} [args.config] resolved agent config (signal path)
|
|
240
|
-
* @param {object} [args.logger] logger surface
|
|
241
|
-
* @returns {Promise<{ labelFlipped: boolean, signalAppended: boolean }>}
|
|
242
|
-
*/
|
|
243
|
-
export async function emitBlockedSignal({
|
|
244
|
-
epicId,
|
|
245
|
-
event,
|
|
246
|
-
failedOutcomes,
|
|
247
|
-
provider,
|
|
248
|
-
config,
|
|
249
|
-
logger,
|
|
250
|
-
} = {}) {
|
|
251
|
-
const log = logger ?? console;
|
|
252
|
-
const reasons = (failedOutcomes ?? [])
|
|
253
|
-
.map((o) => `${o.listener}:${o.reason ?? o.outcome}`)
|
|
254
|
-
.join('; ');
|
|
255
|
-
let labelFlipped = false;
|
|
256
|
-
if (provider) {
|
|
257
|
-
try {
|
|
258
|
-
await transitionTicketState(provider, epicId, STATE_LABELS.BLOCKED);
|
|
259
|
-
labelFlipped = true;
|
|
260
|
-
} catch (err) {
|
|
261
|
-
log?.warn?.(
|
|
262
|
-
`[lifecycle-emit] failed to flip Epic #${epicId} to agent::blocked: ${err?.message ?? err}`,
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
} else {
|
|
266
|
-
log?.debug?.(
|
|
267
|
-
`[lifecycle-emit] no provider wired — skipping agent::blocked flip for Epic #${epicId} (signal-only)`,
|
|
268
|
-
);
|
|
269
|
-
}
|
|
270
|
-
let signalAppended = false;
|
|
271
|
-
try {
|
|
272
|
-
signalAppended = await appendEpicSignal({
|
|
273
|
-
epicId,
|
|
274
|
-
config,
|
|
275
|
-
signal: {
|
|
276
|
-
kind: 'friction',
|
|
277
|
-
ts: new Date().toISOString(),
|
|
278
|
-
epicId,
|
|
279
|
-
category: 'lifecycle-listener-failure',
|
|
280
|
-
emitter: { tool: 'lifecycle-emit.js' },
|
|
281
|
-
severity: 'high',
|
|
282
|
-
event,
|
|
283
|
-
details: {
|
|
284
|
-
message: `lifecycle-emit: ${event} produced failed listener classification(s): ${reasons}`,
|
|
285
|
-
outcomes: failedOutcomes,
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
});
|
|
289
|
-
} catch (err) {
|
|
290
|
-
log?.warn?.(
|
|
291
|
-
`[lifecycle-emit] failed to append friction signal for Epic #${epicId}: ${err?.message ?? err}`,
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
return { labelFlipped, signalAppended };
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Programmatic entry point. Tests inject `bus` to assert payload
|
|
299
|
-
* shape without triggering real schema validation.
|
|
300
|
-
*
|
|
301
|
-
* When the caller does NOT supply a `bus`, the helper constructs a
|
|
302
|
-
* default bus AND subscribes the canonical listener chain via
|
|
303
|
-
* `buildDefaultListenerChain` so the standalone CLI surface fires every
|
|
304
|
-
* documented downstream side effect (acceptance reconcile, finalize,
|
|
305
|
-
* automerge, cleanup). Callers that inject a bus retain full control —
|
|
306
|
-
* they are responsible for wiring whatever listeners they want.
|
|
307
|
-
*
|
|
308
|
-
* The listener chain requires `epicId` (decoded from the payload) and a
|
|
309
|
-
* `repoRoot` (defaulted from `process.cwd()`). Story #2531 (Epic #2527)
|
|
310
|
-
* additionally resolves the canonical provider, the
|
|
311
|
-
* full agent `config`, and a per-Epic `checkpointer` bound to the
|
|
312
|
-
* `epic-run-state` structured comment so the FULL listener roster
|
|
313
|
-
* (including AutomergePredicate and BranchCleaner) subscribes — the
|
|
314
|
-
* skip path that previously dropped those two listeners is reserved
|
|
315
|
-
* for callers that inject overrides via `opts`.
|
|
316
|
-
*
|
|
317
|
-
* @param {object} opts
|
|
318
|
-
* @param {string} opts.event lifecycle event name (matches schema file)
|
|
319
|
-
* @param {object} opts.payload assembled emit payload
|
|
320
|
-
* @param {object} [opts.bus] override bus (defaults to `createBus()`)
|
|
321
|
-
* @param {string} [opts.schemaDir] override schema dir for existence check
|
|
322
|
-
* @param {string} [opts.repoRoot] override repo root for shell-out
|
|
323
|
-
* listeners (defaults to `process.cwd()`)
|
|
324
|
-
* @param {object} [opts.logger] optional logger forwarded to the chain
|
|
325
|
-
* @param {object} [opts.provider] override provider (defaults to
|
|
326
|
-
* `createProvider(config)` from the resolved config).
|
|
327
|
-
* Pass `null` to explicitly skip provider-dependent listeners.
|
|
328
|
-
* @param {object} [opts.checkpointer] override checkpointer (defaults
|
|
329
|
-
* to a provider/epicId-bound `epic-run-state-store` facade). Pass
|
|
330
|
-
* `null` to explicitly skip BranchCleaner.
|
|
331
|
-
* @param {object} [opts.config] override resolved config (defaults to
|
|
332
|
-
* `resolveConfig()`).
|
|
333
|
-
* @param {(args: object) => Promise<unknown>} [opts.emitBlockedSignalFn]
|
|
334
|
-
* override the operator-visible blocker signal (defaults to
|
|
335
|
-
* `emitBlockedSignal`). Tests inject a spy to assert it fires on a
|
|
336
|
-
* `failed` classification without touching GitHub or the filesystem.
|
|
337
|
-
* @param {object} [opts.chain] override the listener chain whose
|
|
338
|
-
* `classifications` arrays are collected into `outcomes[]`. Only honoured
|
|
339
|
-
* alongside an injected `bus` (when the caller owns listener wiring) —
|
|
340
|
-
* lets a test inject a bus + a chain carrying a `failed`-classifying
|
|
341
|
-
* listener to exercise the non-zero-exit path without the real roster.
|
|
342
|
-
* @param {boolean} [opts.headless] Explicit must-land signal (Story
|
|
343
|
-
* #4427), forwarded to `buildDefaultListenerChain({ headless })` (and
|
|
344
|
-
* from there to `MergeWatcher`) when this call constructs the default
|
|
345
|
-
* chain. Defaults to `false` — attended-mode behavior is unchanged.
|
|
346
|
-
* Ignored when the caller injects its own `bus`/`chain`.
|
|
347
|
-
*
|
|
348
|
-
* @returns {Promise<{ event: string, payload: object, seqId: number,
|
|
349
|
-
* outcomes: Array<object>, failed: boolean }>} The `outcomes[]` array
|
|
350
|
-
* carries every listener classification (tagged with its listener key);
|
|
351
|
-
* `failed` is `true` when any classification's `outcome` is `'failed'`.
|
|
352
|
-
* The CLI maps `failed` to a non-zero exit code.
|
|
353
|
-
*/
|
|
354
|
-
export async function runLifecycleEmit({
|
|
355
|
-
event,
|
|
356
|
-
payload,
|
|
357
|
-
bus,
|
|
358
|
-
schemaDir = DEFAULT_SCHEMA_DIR,
|
|
359
|
-
repoRoot,
|
|
360
|
-
logger,
|
|
361
|
-
provider,
|
|
362
|
-
checkpointer,
|
|
363
|
-
config,
|
|
364
|
-
emitBlockedSignalFn = emitBlockedSignal,
|
|
365
|
-
chain: injectedChain,
|
|
366
|
-
headless = false,
|
|
367
|
-
} = {}) {
|
|
368
|
-
if (typeof event !== 'string' || event.length === 0) {
|
|
369
|
-
throw new Error('lifecycle-emit: --event is required');
|
|
370
|
-
}
|
|
371
|
-
const schemaPath = path.join(schemaDir, `${event}.schema.json`);
|
|
372
|
-
if (!existsSync(schemaPath)) {
|
|
373
|
-
throw new Error(
|
|
374
|
-
`lifecycle-emit: unknown event "${event}" — no schema at ${schemaPath}`,
|
|
375
|
-
);
|
|
376
|
-
}
|
|
377
|
-
const callerSuppliedBus = Boolean(bus);
|
|
378
|
-
const targetBus = bus ?? createBus({ schemaDir });
|
|
379
|
-
const epicId = Number(payload?.epicId);
|
|
380
|
-
const hasEpicId = Number.isInteger(epicId) && epicId > 0;
|
|
381
|
-
// An injected chain is only meaningful when the caller also injected the
|
|
382
|
-
// bus (otherwise we build the chain ourselves below).
|
|
383
|
-
let chain = callerSuppliedBus ? (injectedChain ?? null) : null;
|
|
384
|
-
let resolvedConfig = config;
|
|
385
|
-
let resolvedProvider = provider;
|
|
386
|
-
// Wire the default listener chain only when we constructed the bus
|
|
387
|
-
// ourselves. Callers that inject a bus own its listener wiring.
|
|
388
|
-
if (!callerSuppliedBus && hasEpicId) {
|
|
389
|
-
const ledgerPath = epicLedgerPath(epicId);
|
|
390
|
-
// Resolve config + provider + checkpointer so the full canonical
|
|
391
|
-
// listener roster subscribes (Story #2531). The CLI swallows
|
|
392
|
-
// resolution errors (missing/invalid .agentrc.json or
|
|
393
|
-
// unconfigured provider) and falls back to the skip-cleanly
|
|
394
|
-
// behaviour — the standalone CLI MUST remain usable in repos
|
|
395
|
-
// that have not configured the github block yet, just
|
|
396
|
-
// with a reduced listener roster.
|
|
397
|
-
let resolvedCheckpointer = checkpointer;
|
|
398
|
-
if (resolvedConfig === undefined) {
|
|
399
|
-
try {
|
|
400
|
-
resolvedConfig = resolveConfig();
|
|
401
|
-
} catch (err) {
|
|
402
|
-
(logger ?? console)?.debug?.(
|
|
403
|
-
`[lifecycle-emit] resolveConfig failed (continuing with skipped collaborators): ${err?.message ?? err}`,
|
|
404
|
-
);
|
|
405
|
-
resolvedConfig = null;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
if (resolvedProvider === undefined) {
|
|
409
|
-
try {
|
|
410
|
-
resolvedProvider = createProvider(resolvedConfig);
|
|
411
|
-
} catch (err) {
|
|
412
|
-
(logger ?? console)?.debug?.(
|
|
413
|
-
`[lifecycle-emit] createProvider skipped (no provider configured): ${err?.message ?? err}`,
|
|
414
|
-
);
|
|
415
|
-
resolvedProvider = null;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
if (resolvedCheckpointer === undefined) {
|
|
419
|
-
resolvedCheckpointer = resolvedProvider
|
|
420
|
-
? buildEpicCheckpointer({ provider: resolvedProvider, epicId })
|
|
421
|
-
: null;
|
|
422
|
-
}
|
|
423
|
-
chain = await buildDefaultListenerChain({
|
|
424
|
-
bus: targetBus,
|
|
425
|
-
ledgerPath,
|
|
426
|
-
repoRoot: repoRoot ?? process.cwd(),
|
|
427
|
-
provider: resolvedProvider,
|
|
428
|
-
checkpointer: resolvedCheckpointer,
|
|
429
|
-
config: resolvedConfig,
|
|
430
|
-
logger,
|
|
431
|
-
headless,
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
const { seqId } = await targetBus.emit(event, payload ?? {});
|
|
435
|
-
|
|
436
|
-
// Collect every listener classification the chain recorded. Listeners
|
|
437
|
-
// record `failed` classifications instead of throwing (the bus's
|
|
438
|
-
// `onFailed` boundary already persists the originating event), so the
|
|
439
|
-
// bus emit resolves cleanly even when a downstream side effect — e.g.
|
|
440
|
-
// an acceptance-reconcile gap or an `openOrLocatePr` throw inside
|
|
441
|
-
// the Finalizer — failed. Without surfacing these, the CLI would exit 0
|
|
442
|
-
// with success-shaped JSON despite a partial finalize (Story #3904).
|
|
443
|
-
const outcomes = collectOutcomes(chain);
|
|
444
|
-
const failedOutcomes = outcomes.filter((o) => o.outcome === 'failed');
|
|
445
|
-
const failed = failedOutcomes.length > 0;
|
|
446
|
-
|
|
447
|
-
// Operator-visible signal: a failed classification surfaces an
|
|
448
|
-
// `agent::blocked` flip + friction signal rather than a silent exit 0.
|
|
449
|
-
// Fired only when we own the chain AND have a target Epic to flag.
|
|
450
|
-
if (failed && hasEpicId) {
|
|
451
|
-
await emitBlockedSignalFn({
|
|
452
|
-
epicId,
|
|
453
|
-
event,
|
|
454
|
-
failedOutcomes,
|
|
455
|
-
provider: resolvedProvider ?? null,
|
|
456
|
-
config: resolvedConfig ?? undefined,
|
|
457
|
-
logger,
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
return { event, payload: payload ?? {}, seqId, outcomes, failed };
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Build a thin per-Epic checkpointer facade over `epic-run-state-store`.
|
|
466
|
-
* Exposes the `read()`/`write()`/`setPhase()`/`appendIntervention()`
|
|
467
|
-
* surface BranchCleaner expects. (This was previously also constructed by
|
|
468
|
-
* the in-process `epic-runner/factory.js`, deleted with the dead runner
|
|
469
|
-
* stratum in Story #3908; this CLI is now the only builder of the facade.)
|
|
470
|
-
*/
|
|
471
|
-
function buildEpicCheckpointer({ provider, epicId }) {
|
|
472
|
-
return {
|
|
473
|
-
read: () => epicRunStateStoreModule.read({ provider, epicId }),
|
|
474
|
-
write: (state) =>
|
|
475
|
-
epicRunStateStoreModule.write({ provider, epicId, state }),
|
|
476
|
-
setPhase: (nextPhase) =>
|
|
477
|
-
epicRunStateStoreModule.setPhase({ provider, epicId, nextPhase }),
|
|
478
|
-
appendIntervention: (entry) =>
|
|
479
|
-
epicRunStateStoreModule.appendIntervention({ provider, epicId, entry }),
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
async function main() {
|
|
484
|
-
const parsed = parseArgv(process.argv.slice(2));
|
|
485
|
-
if (!parsed.event) {
|
|
486
|
-
throw new Error(
|
|
487
|
-
'lifecycle-emit: --event <name> is required. Example: --event epic.close.end',
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
const event = parsed.event;
|
|
491
|
-
const payload = buildPayload(parsed);
|
|
492
|
-
// `--headless true` is a runtime option (Story #4427), not a payload
|
|
493
|
-
// field — see RUNTIME_OPTION_KEYS. Threaded explicitly through
|
|
494
|
-
// runLifecycleEmit → buildDefaultListenerChain → MergeWatcher so the
|
|
495
|
-
// epic-path must-land terminal step reads a caller-supplied input
|
|
496
|
-
// rather than an ambient global.
|
|
497
|
-
const headless = parsed.headless === 'true';
|
|
498
|
-
const out = await runLifecycleEmit({ event, payload, headless });
|
|
499
|
-
process.stdout.write(`${JSON.stringify(out)}\n`);
|
|
500
|
-
// Exit non-zero when any listener classification came back `failed` so
|
|
501
|
-
// the workflow's "re-run on non-zero" loop closes the partial-finalize
|
|
502
|
-
// gap (Story #3904). `runAsCli`'s `propagateExitCode` maps this return
|
|
503
|
-
// value to `process.exit`.
|
|
504
|
-
return out.failed ? 1 : 0;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
runAsCli(import.meta.url, main, {
|
|
508
|
-
source: 'lifecycle-emit',
|
|
509
|
-
propagateExitCode: true,
|
|
510
|
-
});
|