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,462 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* node:coverage ignore file */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* epic-deliver-preflight.js — Story #2899 (Epic #2880, F13).
|
|
6
|
-
*
|
|
7
|
-
* Estimates the cost of an upcoming `/deliver` run *before* Story
|
|
8
|
-
* fan-out and surfaces the result to the operator on two channels:
|
|
9
|
-
*
|
|
10
|
-
* 1. A JSON envelope on stdout (always) with the keys
|
|
11
|
-
* `storyCount`, `installCostSeconds`, `dependencyDepth`,
|
|
12
|
-
* `githubApiRequests`, `claudeQuotaTokens`, plus `breaches`
|
|
13
|
-
* (the non-empty subset of `delivery.preflight.max*` thresholds the
|
|
14
|
-
* estimate exceeds), plus `remoteVerified` / `remoteProbe` — the
|
|
15
|
-
* issue #4483 deterministic remote evidence (`git remote get-url
|
|
16
|
-
* origin` + bounded `git ls-remote origin HEAD`). On
|
|
17
|
-
* `remoteVerified: false` the workflow MUST flip the Epic to
|
|
18
|
-
* `agent::blocked` quoting `remoteProbe.detail` — inline delivery to
|
|
19
|
-
* local `main` is never a sanctioned fallback.
|
|
20
|
-
* 2. When `--post` is set (and `--dry-run` is not), an upserted
|
|
21
|
-
* `delivery-preflight` structured comment on the Epic ticket so
|
|
22
|
-
* reviewers reading the Epic discover the same numbers without
|
|
23
|
-
* shelling out.
|
|
24
|
-
*
|
|
25
|
-
* The CLI is intentionally side-effect-light when `--dry-run` is set: no
|
|
26
|
-
* comment write, no lifecycle emit. The slash-command workflow
|
|
27
|
-
* (`/deliver` Phase 1) calls the CLI without `--dry-run` so the
|
|
28
|
-
* comment is upserted; if any threshold is breached, the workflow flips
|
|
29
|
-
* the Epic to `agent::blocked` and surfaces the envelope in chat for
|
|
30
|
-
* operator review. The CLI itself does NOT flip labels — the workflow
|
|
31
|
-
* owns the HITL transition so a re-invocation against a recovered Epic
|
|
32
|
-
* does not double-flip.
|
|
33
|
-
*
|
|
34
|
-
* Estimate model (kept simple and deterministic so a sub-agent reviewing
|
|
35
|
-
* the comment can reason about the numbers):
|
|
36
|
-
*
|
|
37
|
-
* - `storyCount` = number of child `type::story` tickets.
|
|
38
|
-
* - `dependencyDepth` = longest dependency chain through the Story
|
|
39
|
-
* DAG (Story #4155). The ready-set runtime has
|
|
40
|
-
* no wave barrier, so wall-clock is bounded
|
|
41
|
-
* below by this depth, not by a wave count: a
|
|
42
|
-
* depth-1 Epic (all Stories independent) can run
|
|
43
|
-
* fully parallel, while a depth-N chain forces N
|
|
44
|
-
* sequential beats regardless of cap. Computed
|
|
45
|
-
* as the dependency-DAG layer count.
|
|
46
|
-
* - `installCostSeconds` = `storyCount * perStoryInstallSeconds`
|
|
47
|
-
* (default 45s, override via
|
|
48
|
-
* `--per-story-install-seconds`). Models a
|
|
49
|
-
* per-worktree `npm ci`.
|
|
50
|
-
* - `githubApiRequests` = base 30 (snapshot + plan) +
|
|
51
|
-
* `storyCount * perStoryApiRequests`
|
|
52
|
-
* (default 25 — story-init + per-Task label
|
|
53
|
-
* transitions + close-validation).
|
|
54
|
-
* - `claudeQuotaTokens` = `storyCount * perStoryClaudeTokens`
|
|
55
|
-
* (default 200000 — covers full Story loop
|
|
56
|
-
* hydration + 4-Task implementation).
|
|
57
|
-
*
|
|
58
|
-
* Operators tune the per-Story constants on the CLI when their project's
|
|
59
|
-
* empirical numbers diverge; the defaults are framework guidance, not
|
|
60
|
-
* physics.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
import { parseArgs } from 'node:util';
|
|
64
|
-
|
|
65
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
66
|
-
import { getPreflight, resolveConfig } from './lib/config-resolver.js';
|
|
67
|
-
import { Logger } from './lib/Logger.js';
|
|
68
|
-
import { runBuildWaveDagPhase } from './lib/orchestration/epic-runner/phases/build-wave-dag.js';
|
|
69
|
-
import { runSnapshotPhase } from './lib/orchestration/epic-runner/phases/snapshot.js';
|
|
70
|
-
import {
|
|
71
|
-
computeBaseSha,
|
|
72
|
-
writePreflightCache,
|
|
73
|
-
} from './lib/orchestration/preflight-cache.js';
|
|
74
|
-
import { verifyRemote } from './lib/orchestration/remote-verifier.js';
|
|
75
|
-
import { upsertStructuredComment } from './lib/orchestration/ticketing.js';
|
|
76
|
-
import { createProvider } from './lib/provider-factory.js';
|
|
77
|
-
|
|
78
|
-
const HELP = `Usage: node .agents/scripts/epic-deliver-preflight.js \\
|
|
79
|
-
--epic <epicId> [--dry-run] [--post] \\
|
|
80
|
-
[--per-story-install-seconds <n>] \\
|
|
81
|
-
[--per-story-api-requests <n>] \\
|
|
82
|
-
[--per-story-claude-tokens <n>]
|
|
83
|
-
|
|
84
|
-
Estimates Story count, install cost, wave count, GitHub API request volume,
|
|
85
|
-
and Claude Max quota burn for an Epic *before* /deliver fan-out.
|
|
86
|
-
|
|
87
|
-
Flags:
|
|
88
|
-
--dry-run Compute the estimate and print the JSON
|
|
89
|
-
envelope on stdout. Does NOT upsert the
|
|
90
|
-
delivery-preflight comment.
|
|
91
|
-
--post Upsert the delivery-preflight structured
|
|
92
|
-
comment on the Epic ticket. Required when
|
|
93
|
-
--dry-run is absent and the caller wants
|
|
94
|
-
side effects on the ticket.
|
|
95
|
-
--per-story-install-seconds <n> Override the per-Story install-cost
|
|
96
|
-
constant (default 45).
|
|
97
|
-
--per-story-api-requests <n> Override the per-Story API-request
|
|
98
|
-
estimate (default 25).
|
|
99
|
-
--per-story-claude-tokens <n> Override the per-Story Claude-token
|
|
100
|
-
estimate (default 200000).
|
|
101
|
-
--help Show this message.
|
|
102
|
-
|
|
103
|
-
Output (stdout, always): JSON envelope with the estimate plus a 'breaches'
|
|
104
|
-
array describing any \`delivery.preflight.max*\` thresholds the estimate
|
|
105
|
-
exceeds. A non-empty 'breaches' array does NOT cause the CLI to exit
|
|
106
|
-
non-zero — the slash-command workflow owns the agent::blocked transition.
|
|
107
|
-
|
|
108
|
-
Exit codes:
|
|
109
|
-
0 — estimate computed; stdout carries the envelope.
|
|
110
|
-
1 — provider, config, or wave-DAG failure (no envelope written).
|
|
111
|
-
`;
|
|
112
|
-
|
|
113
|
-
const DEFAULTS = Object.freeze({
|
|
114
|
-
perStoryInstallSeconds: 45,
|
|
115
|
-
perStoryApiRequests: 25,
|
|
116
|
-
perStoryClaudeTokens: 200_000,
|
|
117
|
-
// Base GH API budget: snapshot getTicket + getSubTickets + plan/manifest
|
|
118
|
-
// reads/writes that happen once per /deliver run regardless of
|
|
119
|
-
// Story count. Empirical observation from a 5-Story Epic shows ~30
|
|
120
|
-
// requests for the non-per-Story floor.
|
|
121
|
-
baseApiRequests: 30,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Pure estimate calculator. Exported for unit tests so the math is
|
|
126
|
-
* exercised without spinning up a provider.
|
|
127
|
-
*
|
|
128
|
-
* @param {{
|
|
129
|
-
* storyCount: number,
|
|
130
|
-
* dependencyDepth: number,
|
|
131
|
-
* perStoryInstallSeconds?: number,
|
|
132
|
-
* perStoryApiRequests?: number,
|
|
133
|
-
* perStoryClaudeTokens?: number,
|
|
134
|
-
* baseApiRequests?: number,
|
|
135
|
-
* }} input
|
|
136
|
-
* @returns {{
|
|
137
|
-
* storyCount: number,
|
|
138
|
-
* installCostSeconds: number,
|
|
139
|
-
* dependencyDepth: number,
|
|
140
|
-
* githubApiRequests: number,
|
|
141
|
-
* claudeQuotaTokens: number,
|
|
142
|
-
* }}
|
|
143
|
-
*/
|
|
144
|
-
export function computeEstimate({
|
|
145
|
-
storyCount,
|
|
146
|
-
dependencyDepth,
|
|
147
|
-
perStoryInstallSeconds = DEFAULTS.perStoryInstallSeconds,
|
|
148
|
-
perStoryApiRequests = DEFAULTS.perStoryApiRequests,
|
|
149
|
-
perStoryClaudeTokens = DEFAULTS.perStoryClaudeTokens,
|
|
150
|
-
baseApiRequests = DEFAULTS.baseApiRequests,
|
|
151
|
-
}) {
|
|
152
|
-
if (!Number.isInteger(storyCount) || storyCount < 0) {
|
|
153
|
-
throw new TypeError(
|
|
154
|
-
'computeEstimate: storyCount must be a non-negative integer',
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
if (!Number.isInteger(dependencyDepth) || dependencyDepth < 0) {
|
|
158
|
-
throw new TypeError(
|
|
159
|
-
'computeEstimate: dependencyDepth must be a non-negative integer',
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
return {
|
|
163
|
-
storyCount,
|
|
164
|
-
installCostSeconds: storyCount * perStoryInstallSeconds,
|
|
165
|
-
dependencyDepth,
|
|
166
|
-
githubApiRequests: baseApiRequests + storyCount * perStoryApiRequests,
|
|
167
|
-
claudeQuotaTokens: storyCount * perStoryClaudeTokens,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Compare the estimate against the resolved `delivery.preflight.max*`
|
|
173
|
-
* thresholds. A `null` floor is treated as "no cap" and skipped.
|
|
174
|
-
*
|
|
175
|
-
* @param {ReturnType<typeof computeEstimate>} estimate
|
|
176
|
-
* @param {ReturnType<typeof getPreflight>} thresholds
|
|
177
|
-
* @returns {Array<{ key: string, observed: number, max: number }>}
|
|
178
|
-
*/
|
|
179
|
-
export function detectBreaches(estimate, thresholds) {
|
|
180
|
-
const mapping = [
|
|
181
|
-
{ key: 'storyCount', observedKey: 'storyCount', maxKey: 'maxStories' },
|
|
182
|
-
// Story #4155 — `dependencyDepth` replaces the retired `waveCount`
|
|
183
|
-
// estimate; it is still gated by the `maxWaves` config threshold (the
|
|
184
|
-
// published config key is left unchanged for contract stability).
|
|
185
|
-
{
|
|
186
|
-
key: 'dependencyDepth',
|
|
187
|
-
observedKey: 'dependencyDepth',
|
|
188
|
-
maxKey: 'maxWaves',
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
key: 'installCostSeconds',
|
|
192
|
-
observedKey: 'installCostSeconds',
|
|
193
|
-
maxKey: 'maxInstallCostSeconds',
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
key: 'githubApiRequests',
|
|
197
|
-
observedKey: 'githubApiRequests',
|
|
198
|
-
maxKey: 'maxGithubApiRequests',
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
key: 'claudeQuotaTokens',
|
|
202
|
-
observedKey: 'claudeQuotaTokens',
|
|
203
|
-
maxKey: 'maxClaudeQuotaTokens',
|
|
204
|
-
},
|
|
205
|
-
];
|
|
206
|
-
const breaches = [];
|
|
207
|
-
for (const m of mapping) {
|
|
208
|
-
const max = thresholds[m.maxKey];
|
|
209
|
-
if (max === null || max === undefined) continue;
|
|
210
|
-
const observed = estimate[m.observedKey];
|
|
211
|
-
if (observed > max) {
|
|
212
|
-
breaches.push({ key: m.key, observed, max });
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return breaches;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Render the markdown body of the `delivery-preflight` structured
|
|
220
|
-
* comment. Pure helper — exported for tests.
|
|
221
|
-
*/
|
|
222
|
-
export function renderPreflightBody({
|
|
223
|
-
epicId,
|
|
224
|
-
estimate,
|
|
225
|
-
breaches,
|
|
226
|
-
thresholds,
|
|
227
|
-
remote,
|
|
228
|
-
}) {
|
|
229
|
-
const lines = [];
|
|
230
|
-
lines.push(`### 🛫 Delivery preflight — Epic #${epicId}`);
|
|
231
|
-
lines.push('');
|
|
232
|
-
// Issue #4483 — verified remote evidence at entry. Rendered before the
|
|
233
|
-
// metric table so a reviewer (and the orchestrating agent) sees the
|
|
234
|
-
// land-or-block fact first. Omitted when the caller has no probe result
|
|
235
|
-
// (legacy callers / tests that only exercise the estimate math).
|
|
236
|
-
if (remote) {
|
|
237
|
-
lines.push(
|
|
238
|
-
remote.remoteVerified
|
|
239
|
-
? `✅ **remoteVerified: true** — ${remote.detail}`
|
|
240
|
-
: `⛔ **remoteVerified: false** — ${remote.detail} — \`/deliver\` MUST transition the Epic to \`agent::blocked\` quoting this probe; inline delivery to local \`main\` is forbidden.`,
|
|
241
|
-
);
|
|
242
|
-
lines.push('');
|
|
243
|
-
}
|
|
244
|
-
lines.push('| Metric | Estimate | Threshold |');
|
|
245
|
-
lines.push('| --- | ---: | ---: |');
|
|
246
|
-
const rows = [
|
|
247
|
-
['storyCount', estimate.storyCount, thresholds.maxStories],
|
|
248
|
-
['dependencyDepth', estimate.dependencyDepth, thresholds.maxWaves],
|
|
249
|
-
[
|
|
250
|
-
'installCostSeconds',
|
|
251
|
-
estimate.installCostSeconds,
|
|
252
|
-
thresholds.maxInstallCostSeconds,
|
|
253
|
-
],
|
|
254
|
-
[
|
|
255
|
-
'githubApiRequests',
|
|
256
|
-
estimate.githubApiRequests,
|
|
257
|
-
thresholds.maxGithubApiRequests,
|
|
258
|
-
],
|
|
259
|
-
[
|
|
260
|
-
'claudeQuotaTokens',
|
|
261
|
-
estimate.claudeQuotaTokens,
|
|
262
|
-
thresholds.maxClaudeQuotaTokens,
|
|
263
|
-
],
|
|
264
|
-
];
|
|
265
|
-
for (const [k, v, t] of rows) {
|
|
266
|
-
lines.push(`| ${k} | ${v} | ${t == null ? '—' : t} |`);
|
|
267
|
-
}
|
|
268
|
-
lines.push('');
|
|
269
|
-
if (breaches.length === 0) {
|
|
270
|
-
lines.push(
|
|
271
|
-
'✅ All metrics within configured `delivery.preflight.*` thresholds.',
|
|
272
|
-
);
|
|
273
|
-
} else {
|
|
274
|
-
lines.push(
|
|
275
|
-
'⛔ **Threshold breaches** — `/deliver` will flip the Epic to `agent::blocked` for operator review:',
|
|
276
|
-
);
|
|
277
|
-
for (const b of breaches) {
|
|
278
|
-
lines.push(`- \`${b.key}\` = ${b.observed} (max ${b.max})`);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return lines.join('\n');
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* End-to-end preflight. DI-friendly so tests can swap the provider and
|
|
286
|
-
* config without shelling out.
|
|
287
|
-
*
|
|
288
|
-
* @param {{
|
|
289
|
-
* epicId: number,
|
|
290
|
-
* dryRun?: boolean,
|
|
291
|
-
* post?: boolean,
|
|
292
|
-
* cwd?: string,
|
|
293
|
-
* perStoryInstallSeconds?: number,
|
|
294
|
-
* perStoryApiRequests?: number,
|
|
295
|
-
* perStoryClaudeTokens?: number,
|
|
296
|
-
* injectedProvider?: object,
|
|
297
|
-
* injectedConfig?: object,
|
|
298
|
-
* verifyRemoteFn?: typeof verifyRemote,
|
|
299
|
-
* }} args
|
|
300
|
-
*/
|
|
301
|
-
export async function runPreflight({
|
|
302
|
-
epicId,
|
|
303
|
-
dryRun = false,
|
|
304
|
-
post = false,
|
|
305
|
-
cwd,
|
|
306
|
-
perStoryInstallSeconds,
|
|
307
|
-
perStoryApiRequests,
|
|
308
|
-
perStoryClaudeTokens,
|
|
309
|
-
injectedProvider,
|
|
310
|
-
injectedConfig,
|
|
311
|
-
verifyRemoteFn = verifyRemote,
|
|
312
|
-
}) {
|
|
313
|
-
if (!Number.isInteger(epicId) || epicId <= 0) {
|
|
314
|
-
throw new TypeError('runPreflight: --epic must be a positive integer');
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const config = injectedConfig ?? resolveConfig({ cwd });
|
|
318
|
-
const provider = injectedProvider ?? createProvider(config);
|
|
319
|
-
const thresholds = getPreflight(config);
|
|
320
|
-
|
|
321
|
-
// Issue #4483 — deterministic remote evidence at entry. Probe BEFORE any
|
|
322
|
-
// provider work so the envelope always carries verified fact (not the
|
|
323
|
-
// agent's perception) about whether a live, pushable `origin` exists.
|
|
324
|
-
// The CLI records; the `/deliver` workflow owns the `agent::blocked`
|
|
325
|
-
// transition on `remoteVerified: false` (same split as breach handling).
|
|
326
|
-
const remote = verifyRemoteFn({ cwd });
|
|
327
|
-
|
|
328
|
-
// Compose the same two phases /deliver Phase 1 runs so the
|
|
329
|
-
// preflight numbers match the actual dispatch plan.
|
|
330
|
-
const ctx = { epicId, provider };
|
|
331
|
-
let state = {};
|
|
332
|
-
state = await runSnapshotPhase(ctx, {}, state);
|
|
333
|
-
state = await runBuildWaveDagPhase(ctx, {}, state);
|
|
334
|
-
|
|
335
|
-
const storyCount = Array.isArray(state.stories) ? state.stories.length : 0;
|
|
336
|
-
// Dependency depth = the dependency-DAG layer count (the longest chain of
|
|
337
|
-
// `blocked by` edges). `runBuildWaveDagPhase` already computes this layering
|
|
338
|
-
// as `state.waves`, so its length is the depth even though the ready-set
|
|
339
|
-
// runtime no longer dispatches by wave (Story #4155).
|
|
340
|
-
const dependencyDepth = Array.isArray(state.waves) ? state.waves.length : 0;
|
|
341
|
-
|
|
342
|
-
// Persist the snapshot/DAG envelope so `epic-deliver-prepare.js` can
|
|
343
|
-
// reuse it instead of re-walking the hierarchy. The cache key is a
|
|
344
|
-
// deterministic fingerprint of the Epic ticket returned by the same
|
|
345
|
-
// `getTicket(epicId)` call that drove `runSnapshotPhase` **plus** the
|
|
346
|
-
// Story snapshots that drove the wave DAG (Story #4019), so any drift —
|
|
347
|
-
// Epic label/body/updatedAt or a Story-dependency edit — forces a cache
|
|
348
|
-
// miss in prepare.
|
|
349
|
-
const baseSha = computeBaseSha(state.epic, state.stories);
|
|
350
|
-
let cacheWritten = false;
|
|
351
|
-
if (!dryRun) {
|
|
352
|
-
await writePreflightCache({
|
|
353
|
-
epicId,
|
|
354
|
-
baseSha,
|
|
355
|
-
epic: state.epic,
|
|
356
|
-
stories: state.stories,
|
|
357
|
-
waves: state.waves,
|
|
358
|
-
cwd,
|
|
359
|
-
});
|
|
360
|
-
cacheWritten = true;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const estimate = computeEstimate({
|
|
364
|
-
storyCount,
|
|
365
|
-
dependencyDepth,
|
|
366
|
-
perStoryInstallSeconds,
|
|
367
|
-
perStoryApiRequests,
|
|
368
|
-
perStoryClaudeTokens,
|
|
369
|
-
});
|
|
370
|
-
const breaches = detectBreaches(estimate, thresholds);
|
|
371
|
-
|
|
372
|
-
const envelope = {
|
|
373
|
-
epicId,
|
|
374
|
-
...estimate,
|
|
375
|
-
breaches,
|
|
376
|
-
thresholds,
|
|
377
|
-
baseSha,
|
|
378
|
-
cacheWritten,
|
|
379
|
-
// Issue #4483 — verified remote evidence. `remoteVerified: false`
|
|
380
|
-
// REQUIRES the workflow to block explicitly (never build inline).
|
|
381
|
-
remoteVerified: remote.remoteVerified,
|
|
382
|
-
remoteProbe: {
|
|
383
|
-
remoteUrl: remote.remoteUrl,
|
|
384
|
-
detail: remote.detail,
|
|
385
|
-
},
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
if (post && !dryRun) {
|
|
389
|
-
const body = renderPreflightBody({
|
|
390
|
-
epicId,
|
|
391
|
-
estimate,
|
|
392
|
-
breaches,
|
|
393
|
-
thresholds,
|
|
394
|
-
remote,
|
|
395
|
-
});
|
|
396
|
-
await upsertStructuredComment(provider, epicId, 'delivery-preflight', body);
|
|
397
|
-
envelope.commentUpserted = true;
|
|
398
|
-
} else {
|
|
399
|
-
envelope.commentUpserted = false;
|
|
400
|
-
}
|
|
401
|
-
return envelope;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export function parseArgv(argv) {
|
|
405
|
-
const { values } = parseArgs({
|
|
406
|
-
args: argv,
|
|
407
|
-
options: {
|
|
408
|
-
epic: { type: 'string' },
|
|
409
|
-
'dry-run': { type: 'boolean' },
|
|
410
|
-
post: { type: 'boolean' },
|
|
411
|
-
'per-story-install-seconds': { type: 'string' },
|
|
412
|
-
'per-story-api-requests': { type: 'string' },
|
|
413
|
-
'per-story-claude-tokens': { type: 'string' },
|
|
414
|
-
help: { type: 'boolean', short: 'h' },
|
|
415
|
-
},
|
|
416
|
-
strict: false,
|
|
417
|
-
});
|
|
418
|
-
return values;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
function parseIntOrDefault(raw) {
|
|
422
|
-
if (raw == null) return undefined;
|
|
423
|
-
const n = Number.parseInt(raw, 10);
|
|
424
|
-
if (!Number.isInteger(n) || n < 0) {
|
|
425
|
-
throw new RangeError(
|
|
426
|
-
`expected non-negative integer, got ${JSON.stringify(raw)}`,
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
return n;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
export async function main(argv = process.argv.slice(2)) {
|
|
433
|
-
const values = parseArgv(argv);
|
|
434
|
-
if (values.help) {
|
|
435
|
-
process.stdout.write(HELP);
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
const epicId = Number.parseInt(values.epic ?? '', 10);
|
|
439
|
-
if (!Number.isInteger(epicId) || epicId <= 0) {
|
|
440
|
-
process.stderr.write(
|
|
441
|
-
'[epic-deliver-preflight] ERROR: --epic <epicId> is required.\n',
|
|
442
|
-
);
|
|
443
|
-
process.stderr.write(HELP);
|
|
444
|
-
process.exit(2);
|
|
445
|
-
}
|
|
446
|
-
const envelope = await runPreflight({
|
|
447
|
-
epicId,
|
|
448
|
-
dryRun: values['dry-run'] === true,
|
|
449
|
-
post: values.post === true,
|
|
450
|
-
perStoryInstallSeconds: parseIntOrDefault(
|
|
451
|
-
values['per-story-install-seconds'],
|
|
452
|
-
),
|
|
453
|
-
perStoryApiRequests: parseIntOrDefault(values['per-story-api-requests']),
|
|
454
|
-
perStoryClaudeTokens: parseIntOrDefault(values['per-story-claude-tokens']),
|
|
455
|
-
});
|
|
456
|
-
Logger.info(JSON.stringify(envelope, null, 2));
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Re-export for tests that want to inspect the framework defaults.
|
|
460
|
-
export const PREFLIGHT_DEFAULTS = DEFAULTS;
|
|
461
|
-
|
|
462
|
-
runAsCli(import.meta.url, main, { source: 'epic-deliver-preflight' });
|