mandrel 1.94.0 → 2.1.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 +116 -99
- package/.agents/agents/acceptance-critic.md +9 -7
- package/.agents/agents/story-worker.md +45 -51
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +498 -1287
- package/.agents/docs/agentrc-reference.json +185 -80
- package/.agents/docs/configuration.md +132 -190
- package/.agents/docs/execution-reference.md +51 -25
- package/.agents/docs/quality-gates.md +25 -33
- package/.agents/docs/workflows.md +8 -8
- package/.agents/instructions.md +113 -139
- package/.agents/rules/ci-remediation.md +11 -15
- package/.agents/rules/git-conventions-reference.md +48 -58
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +83 -254
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +22 -66
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +7 -10
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- 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 +328 -28
- 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 -15
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
- package/.agents/scripts/lib/checks/index.js +3 -2
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +39 -9
- package/.agents/scripts/lib/close-validation/gates.js +15 -15
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +52 -35
- package/.agents/scripts/lib/config/explain.js +61 -48
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +29 -80
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +12 -15
- package/.agents/scripts/lib/config/runners.js +20 -66
- package/.agents/scripts/lib/config/temp-paths.js +30 -63
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +2 -7
- package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
- package/.agents/scripts/lib/config-settings-schema.js +100 -60
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +2 -2
- package/.agents/scripts/lib/duplicate-search.js +242 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -190
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
- package/.agents/scripts/lib/git-utils.js +32 -20
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +10 -38
- package/.agents/scripts/lib/label-taxonomy.js +10 -55
- package/.agents/scripts/lib/observability/active-story-env.js +44 -165
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +5 -5
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
- package/.agents/scripts/lib/orchestration/code-review.js +78 -436
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- 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/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- 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 +52 -51
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- 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/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
- package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -281
- package/.agents/scripts/lib/preflight-runner.js +4 -4
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +17 -19
- package/.agents/scripts/lib/story-body/story-body.js +130 -75
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
- package/.agents/scripts/lib/validation-evidence.js +32 -60
- package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- 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 +102 -80
- package/.agents/scripts/plan-persist.js +230 -279
- package/.agents/scripts/plan-run-epilogue.js +142 -0
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +13 -39
- package/.agents/scripts/providers/github/mappers.js +5 -12
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -156
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +25 -21
- package/.agents/scripts/single-story-close.js +178 -26
- package/.agents/scripts/single-story-confirm-merge.js +313 -24
- package/.agents/scripts/single-story-init.js +35 -30
- package/.agents/scripts/stories-wave-tick.js +85 -10
- package/.agents/scripts/story-plan.js +28 -49
- package/.agents/scripts/update-ticket-state.js +14 -65
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
- package/.agents/skills/core/scope-triage/SKILL.md +31 -172
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +3 -53
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +6 -7
- package/.agents/workflows/audit-clean-code.md +7 -7
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +9 -10
- package/.agents/workflows/audit-lighthouse.md +11 -3
- package/.agents/workflows/audit-navigability.md +13 -2
- package/.agents/workflows/audit-performance.md +5 -6
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +11 -12
- package/.agents/workflows/audit-security.md +4 -5
- package/.agents/workflows/audit-seo.md +13 -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 +10 -3
- package/.agents/workflows/deliver.md +177 -176
- package/.agents/workflows/git-cleanup.md +5 -6
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +75 -196
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
- package/.agents/workflows/helpers/deliver-story.md +606 -0
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +3 -3
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +277 -145
- package/.agents/workflows/qa-assist.md +27 -33
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -6
- package/README.md +9 -8
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +70 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +12 -8
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/package.json +2 -2
- package/.agents/agents/retro.md +0 -42
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer.md +0 -33
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/security-engineer.md +0 -111
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
- package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -66
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/dispatcher.js +0 -295
- package/.agents/scripts/epic-audit-prepare.js +0 -497
- package/.agents/scripts/epic-audit-recheck.js +0 -274
- package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
- package/.agents/scripts/epic-deliver-preflight.js +0 -462
- package/.agents/scripts/epic-deliver-prepare.js +0 -852
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-reconcile.js +0 -625
- package/.agents/scripts/lib/baseline-snapshot.js +0 -979
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
- package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
- package/.agents/scripts/lib/config/lifecycle.js +0 -40
- package/.agents/scripts/lib/config/preflight.js +0 -58
- package/.agents/scripts/lib/config/retro.js +0 -77
- package/.agents/scripts/lib/epic-merge-lock.js +0 -322
- package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
- package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
- package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
- 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/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- 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/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- 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-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
- package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
- package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
- package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
- package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
- package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
- package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
- package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
- package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
- package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
- package/.agents/scripts/lib/push-epic-retry.js +0 -209
- package/.agents/scripts/lib/spec/index.js +0 -36
- package/.agents/scripts/lib/spec/loader.js +0 -425
- package/.agents/scripts/lib/spec/state.js +0 -208
- package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
- package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
- package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
- package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
- package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
- package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
- package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
- package/.agents/scripts/lib/wave-runner/tick.js +0 -754
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
- package/.agents/scripts/lifecycle-emit.js +0 -510
- package/.agents/scripts/retro-run.js +0 -218
- package/.agents/scripts/slice-phase.js +0 -361
- package/.agents/scripts/standalone-feedback-rollup.js +0 -188
- package/.agents/scripts/story-close.js +0 -294
- package/.agents/scripts/story-init.js +0 -599
- package/.agents/scripts/story-phase.js +0 -369
- package/.agents/scripts/wave-tick.js +0 -464
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
- package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
- package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
- package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
- package/.agents/workflows/helpers/deliver-epic.md +0 -998
- package/.agents/workflows/helpers/deliver-stories.md +0 -450
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
- package/.agents/workflows/helpers/epic-testing.md +0 -125
- package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
- package/.agents/workflows/helpers/plan-epic.md +0 -353
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- package/.agents/workflows/helpers/single-story-deliver.md +0 -557
|
@@ -1,97 +1,68 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* plan-persist.js —
|
|
5
|
-
*
|
|
4
|
+
* plan-persist.js — flat Story GitHub-write surface for v2 `/plan`
|
|
5
|
+
* (Stage 3 — `docs/roadmap.md`).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* release). Given the author-written planning artifacts
|
|
10
|
-
* (Tech Spec, optional Acceptance Table, risk verdict, tickets JSON), this
|
|
11
|
-
* CLI performs every GitHub mutation of the plan flow in one ordered,
|
|
12
|
-
* fail-closed pass:
|
|
7
|
+
* Given the author-written planning artifacts (`stories.json`, optional shared
|
|
8
|
+
* Tech Spec), this CLI validates and creates Story issue(s) directly:
|
|
13
9
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* the dry-run wave table → temp cleanup at terminal success only.
|
|
10
|
+
* ticket validator / DAG / capacity → reachability →
|
|
11
|
+
* split-policy partition → fold/spill Spec into each Story body →
|
|
12
|
+
* createIssue(s) with type::story, resumably by plan fingerprint (NOT
|
|
13
|
+
* agent::ready) → story-plan-state on every Story;
|
|
14
|
+
* plan-summary on the primary → flip every Story to agent::ready →
|
|
15
|
+
* comment + close superseded source tickets → temp cleanup + stale reap.
|
|
21
16
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* present).
|
|
28
|
-
* --one-pager <path> Ideation mode: render + open the Epic from a
|
|
29
|
-
* sharpened one-pager first (folds the former
|
|
30
|
-
* Phase 3/4 steps in). Artifact paths must be
|
|
31
|
-
* explicit (there is no Epic id to derive them from).
|
|
17
|
+
* Story #4542 retired the authored risk verdict: persist neither requires nor
|
|
18
|
+
* accepts one, and no plan-time step produces one. Review depth and the
|
|
19
|
+
* acceptance-critic mode are derived from the diff at close time
|
|
20
|
+
* (`review-depth.js#deriveChangeLevel`). `--force-review` is the only review
|
|
21
|
+
* gate the planner still carries, and it is an explicit operator flag.
|
|
32
22
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* --
|
|
50
|
-
*
|
|
51
|
-
* idempotently, the reconciler creates only the
|
|
52
|
-
* missing slugs from its per-slug state ledger.
|
|
53
|
-
* --amend Change-request delta persist: every ticket carries
|
|
54
|
-
* `op: add|modify|keep|close`; close-and-recreate is
|
|
55
|
-
* scoped to modify/close slugs only, keeps are
|
|
56
|
-
* untouched, and the DAG is validated over the
|
|
57
|
-
* merged set.
|
|
58
|
-
* --explicit-delete Confirm the close ops of an --amend plan (mirrors
|
|
59
|
-
* epic-reconcile.js). Without it, an amend carrying
|
|
60
|
-
* close ops prints the dry-run diff and exits 2.
|
|
61
|
-
* --steal Force-transfer a live foreign Epic-lease claim.
|
|
62
|
-
* --force-review Operator-forced review routing (recorded in the
|
|
63
|
-
* checkpoint's reviewRouting envelope).
|
|
23
|
+
* CLI:
|
|
24
|
+
* --stories <file> Required Story ticket array (default length 1)
|
|
25
|
+
* --tech-spec <file> Optional shared Tech Spec folded into each Story
|
|
26
|
+
* --plan-dir <dir> Optional temp dir deleted at terminal success.
|
|
27
|
+
* Also where the `plan-context.json` envelope is
|
|
28
|
+
* auto-discovered from (see --plan-context)
|
|
29
|
+
* --plan-context <file> Optional explicit path to the `plan-context.js`
|
|
30
|
+
* envelope. Its `sourceTickets[]` is what makes
|
|
31
|
+
* `--tickets` superseding work without a flag
|
|
32
|
+
* --plan-acceptance <file> Optional JSON string[] for partition coverage
|
|
33
|
+
* --source-tickets <ids> Explicit OVERRIDE of the envelope-derived source
|
|
34
|
+
* ids, for hand-driven runs. Each id must be
|
|
35
|
+
* claimed by exactly one Story's `supersedes[]`;
|
|
36
|
+
* they are commented on and closed as superseded
|
|
37
|
+
* --no-close-superseded Keep the source tickets open (no comment, no
|
|
38
|
+
* close) — for a genuinely partial supersede
|
|
39
|
+
* --dry-run Assemble + validate without GitHub writes
|
|
40
|
+
* --force-review Operator-forced review stop before persist lands
|
|
64
41
|
* --allow-over-budget / --allow-large-fan-out
|
|
65
|
-
* Same overrides as the retired split persist.
|
|
66
42
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
43
|
+
* Run `--dry-run` first. It exercises every gate — validator, DAG, capacity,
|
|
44
|
+
* budget, reachability, split/supersede partition, Spec fold — write-free, so
|
|
45
|
+
* an authoring mistake surfaces before a single issue exists.
|
|
46
|
+
*
|
|
47
|
+
* stdout is reserved for the JSON result (Story #2278 discipline, extended to
|
|
48
|
+
* this CLI by Story #4541): `routeAllOutputToStderr()` runs before any
|
|
49
|
+
* pipeline code so a headless driver can `JSON.parse` stdout unconditionally.
|
|
50
|
+
* Human-readable log lines go to stderr, matching the sibling `plan-context`.
|
|
51
|
+
*
|
|
52
|
+
* Exit codes: 0 success; 1 fatal; 3 reachability orphans (nothing mutated).
|
|
75
53
|
*/
|
|
76
54
|
|
|
77
|
-
// Fail-fast if the framework's runtime deps are not installed — must be the
|
|
78
|
-
// first import so the check runs before any third-party-importing sibling
|
|
79
|
-
// module is evaluated (Story #3432).
|
|
80
55
|
import './lib/runtime-deps/ensure-installed.js';
|
|
81
56
|
import { readFile } from 'node:fs/promises';
|
|
82
57
|
import path from 'node:path';
|
|
83
58
|
import { parseArgs } from 'node:util';
|
|
84
59
|
|
|
85
60
|
import { runAsCli } from './lib/cli-utils.js';
|
|
86
|
-
import { epicArtifactPath } from './lib/config/temp-paths.js';
|
|
87
61
|
import {
|
|
88
|
-
PROJECT_ROOT,
|
|
89
62
|
resolveConfig,
|
|
90
63
|
validateOrchestrationConfig,
|
|
91
64
|
} from './lib/config-resolver.js';
|
|
92
|
-
import { Logger } from './lib/Logger.js';
|
|
93
|
-
import { drainPendingCleanupAtBoot } from './lib/orchestration/epic-plan-spec/phases/drain.js';
|
|
94
|
-
import { loadRiskVerdict } from './lib/orchestration/epic-plan-spec/phases/risk-verdict.js';
|
|
65
|
+
import { Logger, routeAllOutputToStderr } from './lib/Logger.js';
|
|
95
66
|
import {
|
|
96
67
|
readPlanMetrics,
|
|
97
68
|
recordPlanInvocation,
|
|
@@ -99,7 +70,10 @@ import {
|
|
|
99
70
|
summarizePlanMetrics,
|
|
100
71
|
} from './lib/orchestration/plan-metrics.js';
|
|
101
72
|
import {
|
|
102
|
-
|
|
73
|
+
loadPlanContextEnvelope,
|
|
74
|
+
resolvePlanContextPath,
|
|
75
|
+
} from './lib/orchestration/plan-persist/plan-context-source.js';
|
|
76
|
+
import {
|
|
103
77
|
runPlanPersist,
|
|
104
78
|
writeCheckpointV2,
|
|
105
79
|
} from './lib/orchestration/plan-persist/run-plan-persist.js';
|
|
@@ -108,128 +82,220 @@ import {
|
|
|
108
82
|
buildWaveTable,
|
|
109
83
|
PLAN_SUMMARY_COMMENT_TYPE,
|
|
110
84
|
} from './lib/orchestration/plan-persist/summary.js';
|
|
85
|
+
import { resolveSourceTicketIds } from './lib/orchestration/plan-persist/supersede-ops.js';
|
|
111
86
|
import { createProvider } from './lib/provider-factory.js';
|
|
112
87
|
|
|
113
|
-
// Re-exports for the stable public API (tests import through the CLI
|
|
114
|
-
// module, mirroring the plan-context.js CLI-shell shape).
|
|
115
88
|
export {
|
|
116
89
|
buildPlanSummaryCommentBody,
|
|
117
90
|
buildWaveTable,
|
|
118
91
|
PLAN_SUMMARY_COMMENT_TYPE,
|
|
119
|
-
resolveDeliveryMode,
|
|
120
92
|
runPlanPersist,
|
|
121
93
|
writeCheckpointV2,
|
|
122
94
|
};
|
|
123
95
|
|
|
124
|
-
export const EPIC_FROM_IDEA_TEMPLATE_PATH = path.resolve(
|
|
125
|
-
PROJECT_ROOT,
|
|
126
|
-
'.agents',
|
|
127
|
-
'templates',
|
|
128
|
-
'epic-from-idea.md',
|
|
129
|
-
);
|
|
130
|
-
|
|
131
96
|
const CLI_OPTIONS = {
|
|
132
|
-
|
|
133
|
-
'one-pager': { type: 'string' },
|
|
97
|
+
stories: { type: 'string' },
|
|
134
98
|
'tech-spec': { type: 'string' },
|
|
135
|
-
'
|
|
136
|
-
'
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
99
|
+
'plan-dir': { type: 'string' },
|
|
100
|
+
'plan-context': { type: 'string' },
|
|
101
|
+
'plan-acceptance': { type: 'string' },
|
|
102
|
+
'source-tickets': { type: 'string' },
|
|
103
|
+
'close-superseded': { type: 'boolean', default: true },
|
|
104
|
+
'no-close-superseded': { type: 'boolean', default: false },
|
|
105
|
+
'dry-run': { type: 'boolean', default: false },
|
|
141
106
|
'force-review': { type: 'boolean', default: false },
|
|
142
107
|
'allow-over-budget': { type: 'boolean', default: false },
|
|
143
108
|
'allow-large-fan-out': { type: 'boolean', default: false },
|
|
144
|
-
amend: { type: 'boolean', default: false },
|
|
145
|
-
'explicit-delete': { type: 'boolean', default: false },
|
|
146
109
|
};
|
|
147
110
|
|
|
148
111
|
const USAGE =
|
|
149
|
-
'Usage: plan-persist.js
|
|
150
|
-
'[--tech-spec <file>] [--
|
|
151
|
-
'[--
|
|
152
|
-
'[--
|
|
112
|
+
'Usage: plan-persist.js --stories <file> ' +
|
|
113
|
+
'[--tech-spec <file>] [--plan-dir <dir>] [--plan-context <file>] ' +
|
|
114
|
+
'[--plan-acceptance <file>] ' +
|
|
115
|
+
'[--source-tickets <ids>] [--no-close-superseded] ' +
|
|
116
|
+
'[--dry-run] [--force-review] ' +
|
|
117
|
+
'[--allow-over-budget] [--allow-large-fan-out]';
|
|
153
118
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
119
|
+
async function readOptional(filePath, { required }) {
|
|
120
|
+
try {
|
|
121
|
+
return await readFile(filePath, 'utf8');
|
|
122
|
+
} catch (err) {
|
|
123
|
+
if (!required && err?.code === 'ENOENT') return null;
|
|
124
|
+
throw new Error(`Cannot read ${filePath}: ${err.message}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function readJsonFile(filePath, label) {
|
|
129
|
+
const raw = await readOptional(filePath, { required: true });
|
|
130
|
+
try {
|
|
131
|
+
return JSON.parse(raw);
|
|
132
|
+
} catch (err) {
|
|
161
133
|
throw new Error(
|
|
162
|
-
`
|
|
134
|
+
`Failed to parse ${label} file "${filePath}" as JSON: ${err.message}`,
|
|
163
135
|
);
|
|
164
136
|
}
|
|
165
|
-
return epicId;
|
|
166
137
|
}
|
|
167
138
|
|
|
168
139
|
/**
|
|
169
|
-
* Resolve
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
* deferred). Ideation mode has no Epic id to derive from, so the paths must
|
|
174
|
-
* be explicit.
|
|
140
|
+
* Resolve every input path the CLI accepts, including where the
|
|
141
|
+
* `plan-context.js` envelope is discovered from. Exported for tests.
|
|
142
|
+
*
|
|
143
|
+
* @param {object} values Parsed `parseArgs` values.
|
|
175
144
|
*/
|
|
176
|
-
function
|
|
177
|
-
const
|
|
178
|
-
epicId === null ? undefined : epicArtifactPath(epicId, basename, config);
|
|
179
|
-
const techSpecPath = values['tech-spec'] ?? fallback('techspec.md');
|
|
180
|
-
const riskVerdictPath =
|
|
181
|
-
values['risk-verdict'] ?? fallback('risk-verdict.json');
|
|
182
|
-
const ticketsPath = values.tickets ?? fallback('tickets.json');
|
|
183
|
-
const acceptancePath =
|
|
184
|
-
values['acceptance-table'] ?? fallback('acceptance-spec.md');
|
|
185
|
-
if (!techSpecPath || !riskVerdictPath) {
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Missing artifact path(s): ideation mode requires explicit --tech-spec and --risk-verdict.\n${USAGE}`,
|
|
188
|
-
);
|
|
189
|
-
}
|
|
145
|
+
export function resolveInputPaths(values) {
|
|
146
|
+
const planDir = values['plan-dir'] ? path.resolve(values['plan-dir']) : null;
|
|
190
147
|
return {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
148
|
+
storiesPath: path.resolve(values.stories),
|
|
149
|
+
techSpecPath: values['tech-spec']
|
|
150
|
+
? path.resolve(values['tech-spec'])
|
|
151
|
+
: null,
|
|
152
|
+
planAcceptancePath: values['plan-acceptance']
|
|
153
|
+
? path.resolve(values['plan-acceptance'])
|
|
154
|
+
: null,
|
|
155
|
+
planDir,
|
|
156
|
+
planContextPath: resolvePlanContextPath(values['plan-context'], planDir),
|
|
197
157
|
};
|
|
198
158
|
}
|
|
199
159
|
|
|
200
|
-
async function
|
|
160
|
+
async function loadArtifacts(paths) {
|
|
161
|
+
const stories = await readJsonFile(paths.storiesPath, 'stories');
|
|
162
|
+
const techSpecContent = paths.techSpecPath
|
|
163
|
+
? await readOptional(paths.techSpecPath, { required: true })
|
|
164
|
+
: null;
|
|
165
|
+
const planAcceptance = paths.planAcceptancePath
|
|
166
|
+
? await readJsonFile(paths.planAcceptancePath, 'plan-acceptance')
|
|
167
|
+
: null;
|
|
168
|
+
const planContextEnvelope = await loadPlanContextEnvelope(
|
|
169
|
+
paths.planContextPath,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
stories,
|
|
174
|
+
techSpecContent,
|
|
175
|
+
planAcceptance,
|
|
176
|
+
planContextEnvelope,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Assemble the `runPlanPersist` opts bag from parsed CLI values.
|
|
182
|
+
*
|
|
183
|
+
* Exported for tests: this is the join where the envelope-derived source ids
|
|
184
|
+
* meet the persist engine, so a regression here silently un-wires
|
|
185
|
+
* `/plan --tickets` superseding (Story #4554).
|
|
186
|
+
*
|
|
187
|
+
* @param {object} values Parsed `parseArgs` values.
|
|
188
|
+
* @param {ReturnType<typeof resolveInputPaths>} paths
|
|
189
|
+
* @param {object|null} planContextEnvelope
|
|
190
|
+
* @returns {object} opts for `runPlanPersist`.
|
|
191
|
+
*/
|
|
192
|
+
export function buildPersistOptions(values, paths, planContextEnvelope) {
|
|
193
|
+
const source = resolveSourceTicketIds({
|
|
194
|
+
explicitIds: values['source-tickets'],
|
|
195
|
+
envelope: planContextEnvelope,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
forceReview: values['force-review'],
|
|
200
|
+
allowOverBudget: values['allow-over-budget'],
|
|
201
|
+
allowLargeFanOut: values['allow-large-fan-out'],
|
|
202
|
+
dryRun: values['dry-run'],
|
|
203
|
+
planDir: paths.planDir,
|
|
204
|
+
skipCleanup: values['dry-run'],
|
|
205
|
+
sourceTicketIds: source.ids,
|
|
206
|
+
sourceTicketOrigin: source.origin,
|
|
207
|
+
// Default-on: `--no-close-superseded` is the explicit escape and always
|
|
208
|
+
// wins over the (default `true`) `--close-superseded`.
|
|
209
|
+
closeSuperseded:
|
|
210
|
+
values['no-close-superseded'] === true
|
|
211
|
+
? false
|
|
212
|
+
: values['close-superseded'] !== false,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
async function runPersistInvocation({
|
|
217
|
+
values,
|
|
218
|
+
config,
|
|
219
|
+
provider,
|
|
220
|
+
artifacts,
|
|
221
|
+
metricsSince,
|
|
222
|
+
}) {
|
|
223
|
+
const paths = resolveInputPaths(values);
|
|
224
|
+
const settings = {
|
|
225
|
+
baseBranch: config.project?.baseBranch,
|
|
226
|
+
paths: config.project?.paths,
|
|
227
|
+
planning: config.planning,
|
|
228
|
+
docsContextFiles: config.project?.docsContextFiles,
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
return recordPlanInvocation(
|
|
232
|
+
{
|
|
233
|
+
cli: 'plan-persist',
|
|
234
|
+
mode: values['dry-run'] ? 'dry-run' : 'persist',
|
|
235
|
+
config,
|
|
236
|
+
},
|
|
237
|
+
() =>
|
|
238
|
+
runPlanPersist({
|
|
239
|
+
provider,
|
|
240
|
+
artifacts,
|
|
241
|
+
config,
|
|
242
|
+
settings,
|
|
243
|
+
opts: {
|
|
244
|
+
...buildPersistOptions(values, paths, artifacts.planContextEnvelope),
|
|
245
|
+
metricsSince,
|
|
246
|
+
},
|
|
247
|
+
}),
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Attach the plan-metrics roll-up for **this** invocation.
|
|
253
|
+
*
|
|
254
|
+
* Two Story #4541 fixes meet here. `readPlanMetrics` is declared
|
|
255
|
+
* `(epicId, config)` but was called with `config` first, so it threw its
|
|
256
|
+
* `epicId` guard on every run and the catch below turned that into a
|
|
257
|
+
* silently missing summary — v2 persist is always Epic-less, hence the
|
|
258
|
+
* explicit `null`. And the Epic-less ledger is shared across every plan the
|
|
259
|
+
* repo has ever run, so `since` scopes the counts to the current invocation
|
|
260
|
+
* instead of reporting lifetime totals under an invocation-shaped line.
|
|
261
|
+
*
|
|
262
|
+
* This runs *after* `recordPlanInvocation` has appended this run's own
|
|
263
|
+
* record, so the summary always has at least that one entry to report.
|
|
264
|
+
*
|
|
265
|
+
* @param {object} result Mutated in place with `planMetrics`.
|
|
266
|
+
* @param {object} config
|
|
267
|
+
* @param {string} since ISO-8601 instant this invocation started.
|
|
268
|
+
*/
|
|
269
|
+
async function attachPlanMetrics(result, config, since) {
|
|
201
270
|
try {
|
|
202
|
-
|
|
271
|
+
const summary = summarizePlanMetrics(await readPlanMetrics(null, config), {
|
|
272
|
+
since,
|
|
273
|
+
});
|
|
274
|
+
if (summary) {
|
|
275
|
+
result.planMetrics = summary;
|
|
276
|
+
Logger.info(`[plan-persist] ${renderPlanMetricsSummaryLine(summary)}`);
|
|
277
|
+
}
|
|
203
278
|
} catch (err) {
|
|
204
|
-
|
|
205
|
-
throw new Error(`Cannot read ${filePath}: ${err.message}`);
|
|
279
|
+
Logger.warn(`[plan-persist] plan-metrics summary skipped: ${err.message}`);
|
|
206
280
|
}
|
|
207
281
|
}
|
|
208
282
|
|
|
209
283
|
async function main() {
|
|
210
284
|
const { values } = parseArgs({ options: CLI_OPTIONS });
|
|
211
285
|
|
|
212
|
-
if (values.
|
|
213
|
-
throw new Error('--force and --resume are mutually exclusive.');
|
|
214
|
-
}
|
|
215
|
-
if (values.amend && (values.force || values.resume)) {
|
|
216
|
-
throw new Error(
|
|
217
|
-
'--amend is mutually exclusive with --force/--resume — the amend ' +
|
|
218
|
-
'delta is already an incremental re-persist.',
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const epicId = parseEpicId(values.epic);
|
|
223
|
-
const onePagerPath = values['one-pager'];
|
|
224
|
-
if (epicId === null && !onePagerPath) {
|
|
286
|
+
if (!values.stories) {
|
|
225
287
|
throw new Error(USAGE);
|
|
226
288
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
289
|
+
|
|
290
|
+
// stdout is reserved for the JSON result: flip every Logger sink that could
|
|
291
|
+
// land on stdout to stderr BEFORE any pipeline code runs (Story #2278
|
|
292
|
+
// discipline, extended here by Story #4541 — this CLI interleaved Logger
|
|
293
|
+
// lines with its own JSON, so a headless driver could not parse stdout).
|
|
294
|
+
routeAllOutputToStderr();
|
|
295
|
+
|
|
296
|
+
// Boundary for this invocation's plan-metrics roll-up — stamped before any
|
|
297
|
+
// ledger-writing work so every record this run appends falls inside it.
|
|
298
|
+
const metricsSince = new Date().toISOString();
|
|
233
299
|
|
|
234
300
|
let config;
|
|
235
301
|
try {
|
|
@@ -238,123 +304,20 @@ async function main() {
|
|
|
238
304
|
} catch (err) {
|
|
239
305
|
throw new Error(`Config schema validation failed:\n${err.message}`);
|
|
240
306
|
}
|
|
241
|
-
const settings = {
|
|
242
|
-
baseBranch: config.project?.baseBranch,
|
|
243
|
-
paths: config.project?.paths,
|
|
244
|
-
planning: config.planning,
|
|
245
|
-
docsContextFiles: config.project?.docsContextFiles,
|
|
246
|
-
};
|
|
247
307
|
const provider = createProvider(config);
|
|
308
|
+
const paths = resolveInputPaths(values);
|
|
309
|
+
const artifacts = await loadArtifacts(paths);
|
|
248
310
|
|
|
311
|
+
let result;
|
|
249
312
|
try {
|
|
250
|
-
await
|
|
251
|
-
|
|
313
|
+
result = await runPersistInvocation({
|
|
314
|
+
values,
|
|
252
315
|
config,
|
|
253
316
|
provider,
|
|
317
|
+
artifacts,
|
|
318
|
+
metricsSince,
|
|
254
319
|
});
|
|
255
320
|
} catch (err) {
|
|
256
|
-
Logger.warn(`[plan-persist] pending-cleanup drain skipped: ${err.message}`);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const {
|
|
260
|
-
techSpecPath,
|
|
261
|
-
riskVerdictPath,
|
|
262
|
-
ticketsPath,
|
|
263
|
-
acceptancePath,
|
|
264
|
-
acceptanceExplicit,
|
|
265
|
-
ticketsExplicit,
|
|
266
|
-
} = resolveArtifactPaths({ epicId, values, config });
|
|
267
|
-
|
|
268
|
-
// Deterministic local reads + validation before any GitHub call. A
|
|
269
|
-
// malformed risk verdict fails closed here (Epic #3865); the section
|
|
270
|
-
// gate itself runs first inside runPlanPersist.
|
|
271
|
-
const techSpecContent = await readOptional(techSpecPath, { required: true });
|
|
272
|
-
const riskVerdict = loadRiskVerdict(riskVerdictPath);
|
|
273
|
-
// Tickets are mode-dependent (#4474 PR4): required when explicitly
|
|
274
|
-
// passed or in --amend mode; otherwise best-effort — a single-delivery
|
|
275
|
-
// plan authors no tickets file at all, and the mode-coherence gate
|
|
276
|
-
// (`resolveDeliveryMode`) hard-errors on every contradictory combination
|
|
277
|
-
// (including a stale tickets.json next to a `deliveryShape: "single"`
|
|
278
|
-
// verdict).
|
|
279
|
-
const ticketsRequired = ticketsExplicit || values.amend;
|
|
280
|
-
const ticketsRaw = ticketsPath
|
|
281
|
-
? await readOptional(ticketsPath, { required: ticketsRequired })
|
|
282
|
-
: null;
|
|
283
|
-
let tickets = null;
|
|
284
|
-
if (ticketsRaw !== null) {
|
|
285
|
-
try {
|
|
286
|
-
tickets = JSON.parse(ticketsRaw);
|
|
287
|
-
} catch (err) {
|
|
288
|
-
throw new Error(
|
|
289
|
-
`Failed to parse tickets file "${ticketsPath}" as JSON: ${err.message}`,
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
// Acceptance table: explicit path is required to exist; the per-Epic
|
|
294
|
-
// default is best-effort (absent file → no acceptance section, matching
|
|
295
|
-
// the waived/none dispositions).
|
|
296
|
-
const acceptanceSpecContent = acceptancePath
|
|
297
|
-
? await readOptional(acceptancePath, { required: acceptanceExplicit })
|
|
298
|
-
: null;
|
|
299
|
-
const onePagerContent = onePagerPath
|
|
300
|
-
? await readOptional(onePagerPath, { required: true })
|
|
301
|
-
: null;
|
|
302
|
-
const templateContent = onePagerContent
|
|
303
|
-
? await readOptional(EPIC_FROM_IDEA_TEMPLATE_PATH, { required: true })
|
|
304
|
-
: null;
|
|
305
|
-
|
|
306
|
-
// Plan-metrics ledger (#4474 PR1): stamp entry/exit + mode. Ideation runs
|
|
307
|
-
// have no Epic id at entry, so they stamp on the standalone stream.
|
|
308
|
-
const mode = values.amend
|
|
309
|
-
? 'amend'
|
|
310
|
-
: values.resume
|
|
311
|
-
? 'resume'
|
|
312
|
-
: values.force
|
|
313
|
-
? 'force'
|
|
314
|
-
: 'persist';
|
|
315
|
-
let result;
|
|
316
|
-
try {
|
|
317
|
-
result = await recordPlanInvocation(
|
|
318
|
-
{ cli: 'plan-persist', mode, epicId, config },
|
|
319
|
-
() =>
|
|
320
|
-
runPlanPersist({
|
|
321
|
-
epicId,
|
|
322
|
-
provider,
|
|
323
|
-
artifacts: {
|
|
324
|
-
techSpecContent,
|
|
325
|
-
acceptanceSpecContent,
|
|
326
|
-
riskVerdict,
|
|
327
|
-
tickets,
|
|
328
|
-
onePagerContent,
|
|
329
|
-
templateContent,
|
|
330
|
-
},
|
|
331
|
-
config,
|
|
332
|
-
settings,
|
|
333
|
-
opts: {
|
|
334
|
-
force: values.force,
|
|
335
|
-
resume: values.resume,
|
|
336
|
-
amend: values.amend,
|
|
337
|
-
explicitDelete: values['explicit-delete'],
|
|
338
|
-
steal: values.steal,
|
|
339
|
-
forceReview: values['force-review'],
|
|
340
|
-
allowOverBudget: values['allow-over-budget'],
|
|
341
|
-
allowLargeFanOut: values['allow-large-fan-out'],
|
|
342
|
-
},
|
|
343
|
-
}),
|
|
344
|
-
);
|
|
345
|
-
} catch (err) {
|
|
346
|
-
// Amend close-op confirmation gate (exit 2, mirroring the
|
|
347
|
-
// epic-reconcile.js contract): print the dry-run diff so the operator
|
|
348
|
-
// reviews exactly what would close, mutate nothing, and exit 2 so
|
|
349
|
-
// non-interactive callers can branch on the code.
|
|
350
|
-
if (err?.code === 'PLAN_AMEND_EXPLICIT_DELETE_REQUIRED') {
|
|
351
|
-
process.stdout.write(`${err.diff}\n\n${err.message}\n`);
|
|
352
|
-
process.exitCode = 2;
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
// Reachability soft failure (#4474 PR6): the orphan-surface list is the
|
|
356
|
-
// message; nothing was mutated (the check runs before any provider
|
|
357
|
-
// call). Exit 3 so non-interactive callers can branch on the code.
|
|
358
321
|
if (err?.code === 'PLAN_REACHABILITY_ORPHANS') {
|
|
359
322
|
process.stdout.write(`${err.message}\n`);
|
|
360
323
|
process.exitCode = 3;
|
|
@@ -363,19 +326,7 @@ async function main() {
|
|
|
363
326
|
throw err;
|
|
364
327
|
}
|
|
365
328
|
|
|
366
|
-
|
|
367
|
-
// (#4474 PR1). Additive and best-effort.
|
|
368
|
-
try {
|
|
369
|
-
const summary = summarizePlanMetrics(
|
|
370
|
-
await readPlanMetrics(result.epicId, config),
|
|
371
|
-
);
|
|
372
|
-
if (summary) {
|
|
373
|
-
result.planMetrics = summary;
|
|
374
|
-
Logger.info(`[plan-persist] ${renderPlanMetricsSummaryLine(summary)}`);
|
|
375
|
-
}
|
|
376
|
-
} catch (err) {
|
|
377
|
-
Logger.warn(`[plan-persist] plan-metrics summary skipped: ${err.message}`);
|
|
378
|
-
}
|
|
329
|
+
await attachPlanMetrics(result, config, metricsSince);
|
|
379
330
|
|
|
380
331
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
381
332
|
}
|