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,449 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* node:coverage ignore file */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* epic-execute-record-wave.js — record one recorder beat's per-Story
|
|
6
|
-
* returns, splice each Story's terminal status into the `epic-run-state`
|
|
7
|
-
* checkpoint's flat per-Story `stories` map, and re-render the unified
|
|
8
|
-
* `epic-run-progress` rollup on the Epic.
|
|
9
|
-
*
|
|
10
|
-
* Story #4155 (Epic #4151) — the Epic `/deliver` runtime cut over from the
|
|
11
|
-
* wave-batch scheduler to the continuous ready-set core. This recorder lost
|
|
12
|
-
* its wave semantics with it: there is no `--wave` flag, no wave-level
|
|
13
|
-
* status aggregation, no `currentWave` advance, and no `waves[]` history. The
|
|
14
|
-
* tick (`lib/wave-runner/tick.js`) re-derives readiness from live labels on
|
|
15
|
-
* every beat, so the checkpoint only records terminal Story outcomes (for the
|
|
16
|
-
* auto-merge predicate, branch cleanup, and the operator rollup). The
|
|
17
|
-
* recorder also emits one `story.dispatch.end` per recorded Story so the
|
|
18
|
-
* tick's ledger-derived in-flight set and the `--check-idle` watchdog can
|
|
19
|
-
* clear the dispatch start/end pairing.
|
|
20
|
-
*
|
|
21
|
-
* 1. Parse / reconcile / verify the per-Story returns.
|
|
22
|
-
* 2. Record each Story's terminal status onto the checkpoint `stories` map.
|
|
23
|
-
* 3. Emit `story.dispatch.end` per recorded Story.
|
|
24
|
-
* 4. Re-render `epic-run-progress` from the checkpoint `stories` map.
|
|
25
|
-
* 5. Print the next action for the slash-command (`dispatch-next` |
|
|
26
|
-
* `halt-blocked` | `halt-failed`).
|
|
27
|
-
*
|
|
28
|
-
* The implementation is split across three modules so the parent stays a
|
|
29
|
-
* thin runner shell:
|
|
30
|
-
*
|
|
31
|
-
* - `lib/orchestration/wave-record-projection.js` — pure helpers
|
|
32
|
-
* (per-Story validation / normalization, rollup-row shaping). Re-exported
|
|
33
|
-
* from this file so existing callers see an unchanged public surface.
|
|
34
|
-
* - `lib/orchestration/wave-record-io.js` — impure helpers (ticket
|
|
35
|
-
* verification, manifest title lookup, returns reconciliation).
|
|
36
|
-
* - `lib/orchestration/wave-record-notifications.js` — curated webhook
|
|
37
|
-
* emit chain for the recorder beat.
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
import { readFileSync } from 'node:fs';
|
|
41
|
-
|
|
42
|
-
import { defineFlags } from './lib/cli-args.js';
|
|
43
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
44
|
-
import { getRunners } from './lib/config/runners.js';
|
|
45
|
-
import { resolveConfig } from './lib/config-resolver.js';
|
|
46
|
-
import { Logger } from './lib/Logger.js';
|
|
47
|
-
import * as epicRunStateStore from './lib/orchestration/epic-run-state-store.js';
|
|
48
|
-
import { upsertEpicRunProgress } from './lib/orchestration/epic-runner/progress-reporter/composition.js';
|
|
49
|
-
import {
|
|
50
|
-
emitStoryDispatchEnd,
|
|
51
|
-
storyStatusToDispatchOutcome,
|
|
52
|
-
} from './lib/orchestration/lifecycle/emit-story-dispatch-end.js';
|
|
53
|
-
import {
|
|
54
|
-
loadManifestTitleMap,
|
|
55
|
-
resolveResolvedResults,
|
|
56
|
-
verifyWaveResults,
|
|
57
|
-
} from './lib/orchestration/wave-record-io.js';
|
|
58
|
-
import { emitRecordNotifications } from './lib/orchestration/wave-record-notifications.js';
|
|
59
|
-
import {
|
|
60
|
-
selectInputFlag,
|
|
61
|
-
validateEpic,
|
|
62
|
-
validateResults,
|
|
63
|
-
} from './lib/orchestration/wave-record-projection.js';
|
|
64
|
-
import { createProvider } from './lib/provider-factory.js';
|
|
65
|
-
import { notify } from './notify.js';
|
|
66
|
-
|
|
67
|
-
export {
|
|
68
|
-
loadManifestTitleMap,
|
|
69
|
-
normalizeReturns,
|
|
70
|
-
resolveResolvedResults,
|
|
71
|
-
verifyWaveResults,
|
|
72
|
-
} from './lib/orchestration/wave-record-io.js';
|
|
73
|
-
// Re-export the pure projection surface so tests and downstream consumers
|
|
74
|
-
// can keep importing from `epic-execute-record-wave.js` after the extract.
|
|
75
|
-
export {
|
|
76
|
-
classifyParsedReturn,
|
|
77
|
-
normalizeReturnsPure,
|
|
78
|
-
STORY_STATUS_TO_ROW_STATE,
|
|
79
|
-
selectInputFlag,
|
|
80
|
-
toRollupRow,
|
|
81
|
-
VALID_STORY_STATUSES,
|
|
82
|
-
validateEpic,
|
|
83
|
-
validateResults,
|
|
84
|
-
validateReturnsEntry,
|
|
85
|
-
} from './lib/orchestration/wave-record-projection.js';
|
|
86
|
-
|
|
87
|
-
const HELP = `Usage: node .agents/scripts/epic-execute-record-wave.js \\
|
|
88
|
-
--epic <epicId> \\
|
|
89
|
-
(--returns @<file>|<inline-json> | --results @<file>|<inline-json>)
|
|
90
|
-
|
|
91
|
-
Records this recorder beat's per-Story outcomes onto the epic-run-state
|
|
92
|
-
checkpoint's flat per-Story status map and upserts the unified
|
|
93
|
-
epic-run-progress rollup on the Epic. Prints the next action for the
|
|
94
|
-
/deliver slash command.
|
|
95
|
-
`;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Parse a `--results` / `--returns` argv value, supporting both `@<file>`
|
|
99
|
-
* and inline JSON. `flag` controls which CLI name appears in error messages.
|
|
100
|
-
*
|
|
101
|
-
* @param {string} value
|
|
102
|
-
* @param {{ readFile?: (path: string) => string, flag?: string }} [deps]
|
|
103
|
-
*/
|
|
104
|
-
export function parseInputArg(value, deps = {}) {
|
|
105
|
-
const flag = deps.flag ?? '--results';
|
|
106
|
-
if (typeof value !== 'string' || value.length === 0) {
|
|
107
|
-
throw new TypeError(
|
|
108
|
-
`epic-execute-record-wave: ${flag} is required (use \`@<file>\` or an inline JSON array).`,
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
const reader = deps.readFile ?? ((p) => readFileSync(p, 'utf8'));
|
|
112
|
-
let raw;
|
|
113
|
-
if (value.startsWith('@')) {
|
|
114
|
-
const filePath = value.slice(1);
|
|
115
|
-
if (!filePath) {
|
|
116
|
-
throw new TypeError(
|
|
117
|
-
`epic-execute-record-wave: ${flag} @<file> requires a path after \`@\`.`,
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
raw = reader(filePath);
|
|
121
|
-
} else {
|
|
122
|
-
raw = value;
|
|
123
|
-
}
|
|
124
|
-
try {
|
|
125
|
-
return JSON.parse(raw);
|
|
126
|
-
} catch (err) {
|
|
127
|
-
throw new SyntaxError(
|
|
128
|
-
`epic-execute-record-wave: ${flag} value is not valid JSON: ${err.message}`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Classify the recorder beat's next action from the verified rows. Pure.
|
|
135
|
-
* Any failed Story → `halt-failed`; else any blocked Story → `halt-blocked`;
|
|
136
|
-
* else → `dispatch-next` (the host re-ticks to pick up the next ready set).
|
|
137
|
-
*
|
|
138
|
-
* @param {Array<{ status: string }>} verified
|
|
139
|
-
* @returns {{ status: 'complete'|'blocked'|'failed', nextAction: string, blockedStoryIds: number[] }}
|
|
140
|
-
*/
|
|
141
|
-
export function classifyRecordOutcome(verified) {
|
|
142
|
-
const rows = Array.isArray(verified) ? verified : [];
|
|
143
|
-
const failed = rows.some((r) => r.status === 'failed');
|
|
144
|
-
const blockedStoryIds = rows
|
|
145
|
-
.filter((r) => r.status === 'blocked')
|
|
146
|
-
.map((r) => r.storyId);
|
|
147
|
-
if (failed) {
|
|
148
|
-
return { status: 'failed', nextAction: 'halt-failed', blockedStoryIds };
|
|
149
|
-
}
|
|
150
|
-
if (blockedStoryIds.length > 0) {
|
|
151
|
-
return { status: 'blocked', nextAction: 'halt-blocked', blockedStoryIds };
|
|
152
|
-
}
|
|
153
|
-
return { status: 'complete', nextAction: 'dispatch-next', blockedStoryIds };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* End-to-end record beat. DI-friendly: tests pass `injectedProvider` and a
|
|
158
|
-
* fully-formed `results` (or `returns`) array to skip real network reads.
|
|
159
|
-
*
|
|
160
|
-
* @param {{
|
|
161
|
-
* epicId: number,
|
|
162
|
-
* results?: unknown,
|
|
163
|
-
* returns?: unknown,
|
|
164
|
-
* cwd?: string,
|
|
165
|
-
* injectedProvider?: object,
|
|
166
|
-
* injectedConfig?: object,
|
|
167
|
-
* injectedNotify?: (ticketId: number, payload: object) => Promise<void>,
|
|
168
|
-
* now?: () => Date,
|
|
169
|
-
* }} args
|
|
170
|
-
*/
|
|
171
|
-
export async function runEpicExecuteRecordWave({
|
|
172
|
-
epicId,
|
|
173
|
-
results,
|
|
174
|
-
returns,
|
|
175
|
-
cwd,
|
|
176
|
-
injectedProvider,
|
|
177
|
-
injectedConfig,
|
|
178
|
-
injectedNotify,
|
|
179
|
-
now = () => new Date(),
|
|
180
|
-
} = {}) {
|
|
181
|
-
validateEpic(epicId);
|
|
182
|
-
if (results == null && returns == null) {
|
|
183
|
-
throw new TypeError(
|
|
184
|
-
'runEpicExecuteRecordWave: either `results` or `returns` is required',
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
if (results != null && returns != null) {
|
|
188
|
-
throw new TypeError(
|
|
189
|
-
'runEpicExecuteRecordWave: pass `results` OR `returns`, not both',
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const config = injectedConfig ?? resolveConfig({ cwd });
|
|
194
|
-
const provider = injectedProvider ?? createProvider(config);
|
|
195
|
-
|
|
196
|
-
const existing = await epicRunStateStore.read({ provider, epicId });
|
|
197
|
-
if (!existing) {
|
|
198
|
-
throw new Error(
|
|
199
|
-
`runEpicExecuteRecordWave: no epic-run-state checkpoint found on Epic #${epicId}; ` +
|
|
200
|
-
'run `node .agents/scripts/epic-deliver-prepare.js --epic <id>` first.',
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
const firstRecord = !hasRecordedStory(existing.stories);
|
|
204
|
-
|
|
205
|
-
const deliverRunner = getRunners(config).deliverRunner ?? {};
|
|
206
|
-
|
|
207
|
-
// 1. Parse / reconcile the per-Story returns.
|
|
208
|
-
const { resolvedResults, parseFailures } = await resolveResolvedResults({
|
|
209
|
-
provider,
|
|
210
|
-
epicId,
|
|
211
|
-
results,
|
|
212
|
-
returns,
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
const validated = validateResults(resolvedResults);
|
|
216
|
-
|
|
217
|
-
// 2. Verify every `done` claim against the live ticket label.
|
|
218
|
-
const { verified, discrepancies } = await verifyWaveResults({
|
|
219
|
-
provider,
|
|
220
|
-
results: validated,
|
|
221
|
-
concurrencyCap: deliverRunner.verifyConcurrencyCap,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
// 3. Cross-look manifest titles for the rollup rows.
|
|
225
|
-
const titleById = await loadManifestTitleMap({ provider, epicId });
|
|
226
|
-
|
|
227
|
-
// 4. Record each Story's terminal status onto the checkpoint `stories`
|
|
228
|
-
// map. Recorded serially so the upserts do not race the same comment.
|
|
229
|
-
let state = existing;
|
|
230
|
-
for (const row of verified) {
|
|
231
|
-
state = await epicRunStateStore.recordStoryStatus({
|
|
232
|
-
provider,
|
|
233
|
-
epicId,
|
|
234
|
-
storyId: row.storyId,
|
|
235
|
-
status: row.status,
|
|
236
|
-
title: titleById.get(row.storyId),
|
|
237
|
-
blockerCommentId: row.blockerCommentId,
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// 5. Emit one `story.dispatch.end` per recorded Story. Closes the
|
|
242
|
-
// start/end pairing the tick reconciler and the `--check-idle`
|
|
243
|
-
// watchdog use to derive in-flight Stories. Best-effort: a failed
|
|
244
|
-
// append must not block the loop.
|
|
245
|
-
emitWaveDispatchEnds({ epicId, verified, config });
|
|
246
|
-
|
|
247
|
-
// 6. Re-render the unified `epic-run-progress` rollup from the checkpoint
|
|
248
|
-
// `stories` map. The single operator-facing summary.
|
|
249
|
-
const { body: renderedBody } = await upsertEpicRunProgress({
|
|
250
|
-
provider,
|
|
251
|
-
epicId,
|
|
252
|
-
stories: state.stories,
|
|
253
|
-
startedAt: existing.startedAt,
|
|
254
|
-
now,
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
const { status, nextAction, blockedStoryIds } =
|
|
258
|
-
classifyRecordOutcome(verified);
|
|
259
|
-
|
|
260
|
-
// 7. Fire the curated webhook events for this recorder beat. Each helper
|
|
261
|
-
// is fire-and-forget — webhook misconfig or a transient Slack outage
|
|
262
|
-
// must not block the loop.
|
|
263
|
-
await emitRecordNotifications({
|
|
264
|
-
injectedNotify,
|
|
265
|
-
defaultNotify: notify,
|
|
266
|
-
config,
|
|
267
|
-
provider,
|
|
268
|
-
epicId,
|
|
269
|
-
firstRecord,
|
|
270
|
-
stories: state.stories,
|
|
271
|
-
verified,
|
|
272
|
-
blockedStoryIds,
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
const envelope = {
|
|
276
|
-
epicId,
|
|
277
|
-
recorded: true,
|
|
278
|
-
status,
|
|
279
|
-
stories: verified.map((r) => ({ id: r.storyId, status: r.status })),
|
|
280
|
-
blockedStoryIds,
|
|
281
|
-
nextAction,
|
|
282
|
-
renderedBody,
|
|
283
|
-
};
|
|
284
|
-
if (discrepancies.length > 0) {
|
|
285
|
-
envelope.discrepancies = discrepancies;
|
|
286
|
-
}
|
|
287
|
-
if (parseFailures.length > 0) {
|
|
288
|
-
envelope.parseFailures = parseFailures.map((f) => ({
|
|
289
|
-
storyId: f.storyId,
|
|
290
|
-
error: f.error,
|
|
291
|
-
}));
|
|
292
|
-
}
|
|
293
|
-
return envelope;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Whether the checkpoint's per-Story `stories` map already carries a
|
|
298
|
-
* non-`pending` (recorded) status — used to fire `epic-started` exactly
|
|
299
|
-
* once, on the first recorder beat. Pure helper.
|
|
300
|
-
*
|
|
301
|
-
* @param {Record<string, { status?: string }>|undefined} stories
|
|
302
|
-
* @returns {boolean}
|
|
303
|
-
*/
|
|
304
|
-
function hasRecordedStory(stories) {
|
|
305
|
-
const map = stories && typeof stories === 'object' ? stories : {};
|
|
306
|
-
for (const rec of Object.values(map)) {
|
|
307
|
-
if (rec?.status && rec.status !== 'pending') return true;
|
|
308
|
-
}
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Append one `story.dispatch.end` lifecycle record per recorded Story
|
|
314
|
-
* (Story #3900). Each emit is independent and best-effort: a single failed
|
|
315
|
-
* append is logged and swallowed so one bad record never aborts the loop.
|
|
316
|
-
* The Story status taxonomy (`done`/`blocked`/`failed`) maps directly onto
|
|
317
|
-
* the `story.dispatch.end` outcome enum.
|
|
318
|
-
*
|
|
319
|
-
* Exported for unit testing.
|
|
320
|
-
*
|
|
321
|
-
* @param {{
|
|
322
|
-
* epicId: number,
|
|
323
|
-
* verified: Array<{ storyId: number, status: string }>,
|
|
324
|
-
* config?: object,
|
|
325
|
-
* emit?: typeof emitStoryDispatchEnd,
|
|
326
|
-
* }} args
|
|
327
|
-
* @returns {number} count of records successfully appended.
|
|
328
|
-
*/
|
|
329
|
-
export function emitWaveDispatchEnds({
|
|
330
|
-
epicId,
|
|
331
|
-
verified,
|
|
332
|
-
config,
|
|
333
|
-
emit = emitStoryDispatchEnd,
|
|
334
|
-
}) {
|
|
335
|
-
let emitted = 0;
|
|
336
|
-
for (const result of verified ?? []) {
|
|
337
|
-
const storyId = result?.storyId;
|
|
338
|
-
const status = result?.status;
|
|
339
|
-
if (!Number.isInteger(storyId) || storyId <= 0) continue;
|
|
340
|
-
try {
|
|
341
|
-
emit({
|
|
342
|
-
epicId,
|
|
343
|
-
storyId,
|
|
344
|
-
outcome: storyStatusToDispatchOutcome(status),
|
|
345
|
-
config,
|
|
346
|
-
});
|
|
347
|
-
emitted += 1;
|
|
348
|
-
} catch (err) {
|
|
349
|
-
Logger.warn(
|
|
350
|
-
`[record-wave] Non-fatal: could not emit story.dispatch.end for Story #${storyId} — ${err?.message ?? 'unknown error'}`,
|
|
351
|
-
);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return emitted;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Resolve the parsed `--results` / `--returns` argv into the input shape
|
|
359
|
-
* `runEpicExecuteRecordWave` expects.
|
|
360
|
-
*
|
|
361
|
-
* @param {{ resultsRaw?: string, returnsRaw?: string }} parsed
|
|
362
|
-
*/
|
|
363
|
-
export function resolveRecordInput(parsed) {
|
|
364
|
-
const flag = selectInputFlag(
|
|
365
|
-
Boolean(parsed?.resultsRaw),
|
|
366
|
-
Boolean(parsed?.returnsRaw),
|
|
367
|
-
);
|
|
368
|
-
if (flag === 'results') {
|
|
369
|
-
return { results: parseInputArg(parsed.resultsRaw, { flag: '--results' }) };
|
|
370
|
-
}
|
|
371
|
-
return { returns: parseInputArg(parsed.returnsRaw, { flag: '--returns' }) };
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Parse argv into the runner contract.
|
|
376
|
-
*
|
|
377
|
-
* @param {string[]} argv
|
|
378
|
-
*/
|
|
379
|
-
export function parseArgv(argv) {
|
|
380
|
-
const { values } = defineFlags(
|
|
381
|
-
{
|
|
382
|
-
epic: { type: 'integer', alias: 'epicId' },
|
|
383
|
-
results: { type: 'string', alias: 'resultsRaw' },
|
|
384
|
-
returns: { type: 'string', alias: 'returnsRaw' },
|
|
385
|
-
help: { type: 'boolean', short: 'h' },
|
|
386
|
-
},
|
|
387
|
-
argv,
|
|
388
|
-
);
|
|
389
|
-
return values;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Orchestration body of `main` extracted as a sibling exported function so
|
|
394
|
-
* the validate / dispatch / envelope-shape ladder is unit-testable without
|
|
395
|
-
* spawning a process. `main` becomes a thin shell: parse → call this →
|
|
396
|
-
* render → exit.
|
|
397
|
-
*
|
|
398
|
-
* @param {ReturnType<typeof parseArgv>} values
|
|
399
|
-
* @param {{
|
|
400
|
-
* runRecordWave?: typeof runEpicExecuteRecordWave,
|
|
401
|
-
* resolveRecordInput?: typeof resolveRecordInput,
|
|
402
|
-
* help?: string,
|
|
403
|
-
* }} [deps]
|
|
404
|
-
* @returns {Promise<{ exitCode: number, result: object }>}
|
|
405
|
-
* `result.kind` is one of: `'help'`, `'validation-error'`, `'envelope'`.
|
|
406
|
-
*/
|
|
407
|
-
export async function runRecordWaveCli(values, deps = {}) {
|
|
408
|
-
const helpText = deps.help ?? HELP;
|
|
409
|
-
if (values.help) {
|
|
410
|
-
return { exitCode: 0, result: { kind: 'help', text: helpText } };
|
|
411
|
-
}
|
|
412
|
-
if (!Number.isInteger(values.epicId) || values.epicId <= 0) {
|
|
413
|
-
return {
|
|
414
|
-
exitCode: 2,
|
|
415
|
-
result: {
|
|
416
|
-
kind: 'validation-error',
|
|
417
|
-
message:
|
|
418
|
-
'[epic-execute-record-wave] ERROR: --epic <epicId> is required.',
|
|
419
|
-
help: helpText,
|
|
420
|
-
},
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
const resolveInput = deps.resolveRecordInput ?? resolveRecordInput;
|
|
424
|
-
const runner = deps.runRecordWave ?? runEpicExecuteRecordWave;
|
|
425
|
-
const envelope = await runner({
|
|
426
|
-
epicId: values.epicId,
|
|
427
|
-
...resolveInput(values),
|
|
428
|
-
});
|
|
429
|
-
return { exitCode: 0, result: { kind: 'envelope', envelope } };
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
export async function main(argv = process.argv.slice(2)) {
|
|
433
|
-
const values = parseArgv(argv);
|
|
434
|
-
const { exitCode, result } = await runRecordWaveCli(values);
|
|
435
|
-
|
|
436
|
-
if (result.kind === 'help') {
|
|
437
|
-
process.stdout.write(result.text);
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
if (result.kind === 'validation-error') {
|
|
441
|
-
Logger.error(result.message);
|
|
442
|
-
Logger.error(result.help);
|
|
443
|
-
process.exit(exitCode);
|
|
444
|
-
}
|
|
445
|
-
process.stdout.write(`${JSON.stringify(result.envelope, null, 2)}\n`);
|
|
446
|
-
if (exitCode !== 0) process.exit(exitCode);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
runAsCli(import.meta.url, main, { source: 'epic-execute-record-wave' });
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* node:coverage ignore file */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* epic-plan-clarity.js — Phase 6 Epic Clarity Gate CLI.
|
|
6
|
-
*
|
|
7
|
-
* Two modes:
|
|
8
|
-
*
|
|
9
|
-
* 1. --emit-context --epic <id> [--pretty]
|
|
10
|
-
* Fetches the Epic body via the resolved ticketing provider, scores
|
|
11
|
-
* it against the five canonical sections from
|
|
12
|
-
* `.agents/templates/epic-from-idea.md`, and prints a JSON envelope
|
|
13
|
-
* to stdout: `{ epicId, epicBody, verdict, sections, missingOrPlaceholder }`.
|
|
14
|
-
* Read-only — no state mutations.
|
|
15
|
-
*
|
|
16
|
-
* 2. --epic <id> --updated-body <path>
|
|
17
|
-
* Reads the sharpened body from disk, compares it to the current
|
|
18
|
-
* Epic body, and (when different) persists via
|
|
19
|
-
* `provider.updateTicket(epicId, { body })`. Posts a
|
|
20
|
-
* `clarity-gate-update` structured audit comment recording the
|
|
21
|
-
* change. Idempotent: identical body → no-op (`changed: false`).
|
|
22
|
-
*
|
|
23
|
-
* Exit codes:
|
|
24
|
-
* 0 — mode completed.
|
|
25
|
-
* 1 — fatal error (see stderr).
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
import { readFile } from 'node:fs/promises';
|
|
29
|
-
import { parseArgs } from 'node:util';
|
|
30
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
31
|
-
import {
|
|
32
|
-
resolveConfig,
|
|
33
|
-
validateOrchestrationConfig,
|
|
34
|
-
} from './lib/config-resolver.js';
|
|
35
|
-
import { scoreEpicBody } from './lib/epic-plan-clarity.js';
|
|
36
|
-
import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
|
|
37
|
-
import { recordPlanInvocation } from './lib/orchestration/plan-metrics.js';
|
|
38
|
-
import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
|
|
39
|
-
import { createProvider } from './lib/provider-factory.js';
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Build the read-only emit-context envelope for an Epic.
|
|
43
|
-
*
|
|
44
|
-
* @param {{ epicId: number, provider: object }} args
|
|
45
|
-
* @returns {Promise<{ epicId: number, epicBody: string, verdict: string, sections: Array<{name:string,status:string}>, missingOrPlaceholder: string[] }>}
|
|
46
|
-
*/
|
|
47
|
-
export async function buildClarityContext({ epicId, provider }) {
|
|
48
|
-
const epic = await provider.getEpic(epicId);
|
|
49
|
-
if (!epic) {
|
|
50
|
-
throw new Error(`[epic-plan-clarity] Epic #${epicId} not found.`);
|
|
51
|
-
}
|
|
52
|
-
const body = epic.body ?? '';
|
|
53
|
-
const score = scoreEpicBody({ body });
|
|
54
|
-
return {
|
|
55
|
-
epicId,
|
|
56
|
-
epicBody: body,
|
|
57
|
-
verdict: score.verdict,
|
|
58
|
-
sections: score.sections,
|
|
59
|
-
missingOrPlaceholder: score.missingOrPlaceholder,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Persist a sharpened Epic body. Wraps `provider.updateTicket` behind the
|
|
65
|
-
* `updateEpicFromOnePager`-style port and posts the `clarity-gate-update`
|
|
66
|
-
* audit comment on success.
|
|
67
|
-
*
|
|
68
|
-
* @param {{
|
|
69
|
-
* epicId: number,
|
|
70
|
-
* updatedBody: string,
|
|
71
|
-
* provider: object,
|
|
72
|
-
* }} args
|
|
73
|
-
* @returns {Promise<{ epicId: number, changed: boolean, currentLength: number, updatedLength: number }>}
|
|
74
|
-
*/
|
|
75
|
-
export async function persistClarityUpdate({ epicId, updatedBody, provider }) {
|
|
76
|
-
const epic = await provider.getEpic(epicId);
|
|
77
|
-
if (!epic) {
|
|
78
|
-
throw new Error(`[epic-plan-clarity] Epic #${epicId} not found.`);
|
|
79
|
-
}
|
|
80
|
-
const currentBody = epic.body ?? '';
|
|
81
|
-
|
|
82
|
-
if (currentBody === updatedBody) {
|
|
83
|
-
Logger.info(
|
|
84
|
-
`[epic-plan-clarity] Epic #${epicId} body matches submitted update — no-op.`,
|
|
85
|
-
);
|
|
86
|
-
return {
|
|
87
|
-
epicId,
|
|
88
|
-
changed: false,
|
|
89
|
-
currentLength: currentBody.length,
|
|
90
|
-
updatedLength: updatedBody.length,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
await provider.updateTicket(epicId, { body: updatedBody });
|
|
95
|
-
Logger.info(`[epic-plan-clarity] Updated Epic #${epicId} body.`);
|
|
96
|
-
|
|
97
|
-
// Audit comment. Skip silently with a stderr warn when the provider does
|
|
98
|
-
// not implement comment surfacing — keeps the gate functional in stripped
|
|
99
|
-
// test doubles.
|
|
100
|
-
const timestamp = new Date().toISOString();
|
|
101
|
-
const auditBody = [
|
|
102
|
-
'```json',
|
|
103
|
-
JSON.stringify(
|
|
104
|
-
{
|
|
105
|
-
epicId,
|
|
106
|
-
timestamp,
|
|
107
|
-
changed: true,
|
|
108
|
-
currentLength: currentBody.length,
|
|
109
|
-
updatedLength: updatedBody.length,
|
|
110
|
-
},
|
|
111
|
-
null,
|
|
112
|
-
2,
|
|
113
|
-
),
|
|
114
|
-
'```',
|
|
115
|
-
'',
|
|
116
|
-
'Phase 6 Epic Clarity Gate persisted a sharpened Epic body. The previous body has been replaced; the rewrite was operator-approved via the HITL diff stop.',
|
|
117
|
-
].join('\n');
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
await upsertStructuredComment(
|
|
121
|
-
provider,
|
|
122
|
-
epicId,
|
|
123
|
-
'clarity-gate-update',
|
|
124
|
-
auditBody,
|
|
125
|
-
);
|
|
126
|
-
} catch (err) {
|
|
127
|
-
Logger.warn(
|
|
128
|
-
`[epic-plan-clarity] Failed to post clarity-gate-update audit comment: ${err.message}`,
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
epicId,
|
|
134
|
-
changed: true,
|
|
135
|
-
currentLength: currentBody.length,
|
|
136
|
-
updatedLength: updatedBody.length,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/* node:coverage ignore next */
|
|
141
|
-
async function main() {
|
|
142
|
-
const { values } = parseArgs({
|
|
143
|
-
options: {
|
|
144
|
-
epic: { type: 'string' },
|
|
145
|
-
'emit-context': { type: 'boolean', default: false },
|
|
146
|
-
'updated-body': { type: 'string' },
|
|
147
|
-
pretty: { type: 'boolean', default: false },
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
if (!values.epic) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
'Usage: epic-plan-clarity.js --epic <EpicId> (--emit-context [--pretty] | --updated-body <file>)',
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const epicId = Number.parseInt(values.epic, 10);
|
|
158
|
-
if (!Number.isInteger(epicId) || epicId <= 0) {
|
|
159
|
-
throw new Error(
|
|
160
|
-
`Invalid epic ID: "${values.epic}" — must be a positive integer.`,
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
let config;
|
|
165
|
-
try {
|
|
166
|
-
config = resolveConfig();
|
|
167
|
-
validateOrchestrationConfig(config);
|
|
168
|
-
} catch (err) {
|
|
169
|
-
throw new Error(`Config schema validation failed:\n${err.message}`);
|
|
170
|
-
}
|
|
171
|
-
const provider = createProvider(config);
|
|
172
|
-
|
|
173
|
-
// Story #2278 — in --emit-context mode stdout is reserved for the JSON
|
|
174
|
-
// envelope. Flip Logger sinks to stderr defensively even though
|
|
175
|
-
// buildClarityContext does not currently call Logger.info, so future
|
|
176
|
-
// additions cannot silently corrupt the captured file.
|
|
177
|
-
if (values['emit-context']) {
|
|
178
|
-
routeAllOutputToStderr();
|
|
179
|
-
// Plan-metrics ledger (#4474 PR1): stamp entry/exit + mode.
|
|
180
|
-
const envelope = await recordPlanInvocation(
|
|
181
|
-
{ cli: 'epic-plan-clarity', mode: 'emit-context', epicId, config },
|
|
182
|
-
() => buildClarityContext({ epicId, provider }),
|
|
183
|
-
);
|
|
184
|
-
const json = values.pretty
|
|
185
|
-
? JSON.stringify(envelope, null, 2)
|
|
186
|
-
: JSON.stringify(envelope);
|
|
187
|
-
process.stdout.write(`${json}\n`);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (!values['updated-body']) {
|
|
192
|
-
throw new Error(
|
|
193
|
-
'Missing mode flag: pass --emit-context or --updated-body <file>.',
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const updatedBody = await readFile(values['updated-body'], 'utf8');
|
|
198
|
-
// Plan-metrics ledger (#4474 PR1): stamp entry/exit + mode.
|
|
199
|
-
const result = await recordPlanInvocation(
|
|
200
|
-
{ cli: 'epic-plan-clarity', mode: 'persist', epicId, config },
|
|
201
|
-
() =>
|
|
202
|
-
persistClarityUpdate({
|
|
203
|
-
epicId,
|
|
204
|
-
updatedBody,
|
|
205
|
-
provider,
|
|
206
|
-
}),
|
|
207
|
-
);
|
|
208
|
-
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
runAsCli(import.meta.url, main, { source: 'epic-plan-clarity' });
|