mandrel 1.57.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 +954 -0
- package/.agents/docs/SDLC.md +1420 -0
- package/.agents/docs/agentrc-reference.json +278 -0
- package/.agents/docs/configuration.md +1040 -0
- package/.agents/docs/workflows.md +59 -0
- package/.agents/instructions.md +384 -0
- package/.agents/personas/architect.md +107 -0
- package/.agents/personas/devops-engineer.md +36 -0
- package/.agents/personas/engineer-mobile.md +119 -0
- package/.agents/personas/engineer-web.md +110 -0
- package/.agents/personas/engineer.md +90 -0
- package/.agents/personas/product.md +88 -0
- package/.agents/personas/project-manager.md +110 -0
- package/.agents/personas/qa-engineer.md +91 -0
- package/.agents/personas/refactorer.md +110 -0
- package/.agents/personas/security-engineer.md +112 -0
- package/.agents/personas/sre.md +86 -0
- package/.agents/personas/technical-writer.md +100 -0
- package/.agents/personas/ux-designer.md +95 -0
- package/.agents/rules/api-conventions.md +75 -0
- package/.agents/rules/changelog-style.md +238 -0
- package/.agents/rules/gherkin-standards.md +146 -0
- package/.agents/rules/git-conventions.md +146 -0
- package/.agents/rules/orchestration-error-handling.md +35 -0
- package/.agents/rules/security-baseline.md +92 -0
- package/.agents/rules/shell-conventions.md +70 -0
- package/.agents/rules/test-seams.md +59 -0
- package/.agents/rules/testing-standards.md +177 -0
- package/.agents/runtime-deps.json +18 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +93 -0
- package/.agents/schemas/agentrc.schema.json +1583 -0
- package/.agents/schemas/audit-results.schema.json +69 -0
- package/.agents/schemas/audit-rules.json +134 -0
- package/.agents/schemas/audit-rules.schema.json +69 -0
- package/.agents/schemas/baselines/baseline-envelope.schema.json +44 -0
- package/.agents/schemas/baselines/bundle-size.schema.json +47 -0
- package/.agents/schemas/baselines/coverage.schema.json +50 -0
- package/.agents/schemas/baselines/crap.schema.json +52 -0
- package/.agents/schemas/baselines/duplication.schema.json +62 -0
- package/.agents/schemas/baselines/lighthouse.schema.json +59 -0
- package/.agents/schemas/baselines/lint.schema.json +47 -0
- package/.agents/schemas/baselines/maintainability.schema.json +71 -0
- package/.agents/schemas/baselines/mutation.schema.json +52 -0
- package/.agents/schemas/crap-baseline.schema.json +57 -0
- package/.agents/schemas/crap-report.schema.json +102 -0
- package/.agents/schemas/dispatch-manifest.json +232 -0
- package/.agents/schemas/epic-perf-report.schema.json +89 -0
- package/.agents/schemas/epic-spec.schema.json +183 -0
- package/.agents/schemas/friction-event.schema.json +56 -0
- package/.agents/schemas/lifecycle/README.md +18 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +13 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +13 -0
- package/.agents/schemas/lifecycle/checkpoint.written.schema.json +13 -0
- package/.agents/schemas/lifecycle/close-validate.end.schema.json +18 -0
- package/.agents/schemas/lifecycle/close-validate.start.schema.json +13 -0
- package/.agents/schemas/lifecycle/code-review.end.schema.json +30 -0
- package/.agents/schemas/lifecycle/code-review.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +14 -0
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.complete.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +13 -0
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +14 -0
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +17 -0
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +15 -0
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +18 -0
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +16 -0
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +28 -0
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +16 -0
- package/.agents/schemas/lifecycle/intervention.recorded.schema.json +15 -0
- package/.agents/schemas/lifecycle/ledger-record.schema.json +59 -0
- package/.agents/schemas/lifecycle/notification.emitted.schema.json +18 -0
- package/.agents/schemas/lifecycle/pr.created.schema.json +14 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +16 -0
- package/.agents/schemas/lifecycle/retro.start.schema.json +12 -0
- package/.agents/schemas/lifecycle/story.blocked.schema.json +13 -0
- package/.agents/schemas/lifecycle/story.dispatch.end.schema.json +17 -0
- package/.agents/schemas/lifecycle/story.dispatch.start.schema.json +15 -0
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +20 -0
- package/.agents/schemas/lifecycle/story.merged.schema.json +13 -0
- package/.agents/schemas/mi-report.schema.json +58 -0
- package/.agents/schemas/model-attribution.schema.json +49 -0
- package/.agents/schemas/qa-finding.schema.json +133 -0
- package/.agents/schemas/qa-ledger.schema.json +89 -0
- package/.agents/schemas/risk-verdict.schema.json +53 -0
- package/.agents/schemas/signal-event.schema.json +58 -0
- package/.agents/schemas/skill.schema.json +31 -0
- package/.agents/schemas/skills-index.schema.json +81 -0
- package/.agents/schemas/story-perf-summary.schema.json +73 -0
- package/.agents/schemas/validation-evidence.schema.json +78 -0
- package/.agents/scripts/README.md +93 -0
- package/.agents/scripts/acceptance-eval.js +284 -0
- package/.agents/scripts/acceptance-spec-reconciler.js +556 -0
- package/.agents/scripts/agents-bootstrap-github.js +634 -0
- package/.agents/scripts/analyze-execution.js +369 -0
- package/.agents/scripts/assert-branch.js +83 -0
- package/.agents/scripts/audit-labels-bootstrap.js +253 -0
- package/.agents/scripts/audit-to-stories.js +257 -0
- package/.agents/scripts/bootstrap.js +1378 -0
- package/.agents/scripts/check-baselines.js +81 -0
- package/.agents/scripts/check-dead-exports.js +311 -0
- package/.agents/scripts/check-doc-links.js +401 -0
- package/.agents/scripts/check-gherkin-placeholders.js +663 -0
- package/.agents/scripts/check-lifecycle-doc-drift.js +402 -0
- package/.agents/scripts/check-lifecycle-lint.js +379 -0
- package/.agents/scripts/check-prepush-recovery.js +90 -0
- package/.agents/scripts/check-windows-git-perf.js +138 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +67 -0
- package/.agents/scripts/coverage-capture.js +112 -0
- package/.agents/scripts/detect-merges.js +111 -0
- package/.agents/scripts/diagnose-friction.js +257 -0
- package/.agents/scripts/diagnose.js +240 -0
- package/.agents/scripts/dispatcher.js +295 -0
- package/.agents/scripts/drain-pending-cleanup.js +147 -0
- package/.agents/scripts/epic-audit-prepare.js +419 -0
- package/.agents/scripts/epic-audit-recheck.js +241 -0
- package/.agents/scripts/epic-deliver-note-intervention.js +192 -0
- package/.agents/scripts/epic-deliver-preflight.js +407 -0
- package/.agents/scripts/epic-deliver-prepare.js +383 -0
- package/.agents/scripts/epic-execute-record-wave.js +463 -0
- package/.agents/scripts/epic-plan-clarity.js +201 -0
- package/.agents/scripts/epic-plan-decompose.js +79 -0
- package/.agents/scripts/epic-plan-healthcheck.js +363 -0
- package/.agents/scripts/epic-plan-spec-validate.js +111 -0
- package/.agents/scripts/epic-plan-spec.js +198 -0
- package/.agents/scripts/epic-reconcile.js +637 -0
- package/.agents/scripts/evidence-gate.js +235 -0
- package/.agents/scripts/generate-config-docs.js +516 -0
- package/.agents/scripts/generate-lifecycle-docs.js +224 -0
- package/.agents/scripts/generate-skills-index.js +252 -0
- package/.agents/scripts/generate-workflows-doc.js +168 -0
- package/.agents/scripts/git-cleanup.js +124 -0
- package/.agents/scripts/git-pr-quality-gate.js +203 -0
- package/.agents/scripts/git-rebase-and-resolve.js +234 -0
- package/.agents/scripts/hierarchy-gate.js +176 -0
- package/.agents/scripts/hydrate-context.js +179 -0
- package/.agents/scripts/install-matrix-assert.js +282 -0
- package/.agents/scripts/lib/Graph.js +326 -0
- package/.agents/scripts/lib/ITicketingProvider.js +349 -0
- package/.agents/scripts/lib/Logger.js +194 -0
- package/.agents/scripts/lib/audit-suite/cli.js +64 -0
- package/.agents/scripts/lib/audit-suite/findings.js +164 -0
- package/.agents/scripts/lib/audit-suite/frontmatter-lint.js +32 -0
- package/.agents/scripts/lib/audit-suite/frontmatter.js +110 -0
- package/.agents/scripts/lib/audit-suite/index.js +22 -0
- package/.agents/scripts/lib/audit-suite/runner.js +233 -0
- package/.agents/scripts/lib/audit-suite/selector.js +235 -0
- package/.agents/scripts/lib/audit-suite/substitutions.js +124 -0
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +49 -0
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +130 -0
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +114 -0
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +93 -0
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +265 -0
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +246 -0
- package/.agents/scripts/lib/audit-to-stories/seed-epic-from-findings.js +160 -0
- package/.agents/scripts/lib/auto-refresh-baselines.js +308 -0
- package/.agents/scripts/lib/baseline-loader.js +0 -0
- package/.agents/scripts/lib/baseline-schema-registry.js +69 -0
- package/.agents/scripts/lib/baseline-snapshot.js +716 -0
- package/.agents/scripts/lib/baselines/component-matcher.js +21 -0
- package/.agents/scripts/lib/baselines/components.js +126 -0
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +203 -0
- package/.agents/scripts/lib/baselines/duplication-scanner.js +220 -0
- package/.agents/scripts/lib/baselines/env-overrides.js +129 -0
- package/.agents/scripts/lib/baselines/envelope.js +368 -0
- package/.agents/scripts/lib/baselines/exit-codes.js +89 -0
- package/.agents/scripts/lib/baselines/git-base.js +0 -0
- package/.agents/scripts/lib/baselines/kernel.js +111 -0
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +220 -0
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +157 -0
- package/.agents/scripts/lib/baselines/kinds/coverage.js +194 -0
- package/.agents/scripts/lib/baselines/kinds/crap.js +555 -0
- package/.agents/scripts/lib/baselines/kinds/duplication.js +197 -0
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +185 -0
- package/.agents/scripts/lib/baselines/kinds/lint.js +172 -0
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +340 -0
- package/.agents/scripts/lib/baselines/kinds/mutation.js +153 -0
- package/.agents/scripts/lib/baselines/path-canon.js +279 -0
- package/.agents/scripts/lib/baselines/preview-gates.js +298 -0
- package/.agents/scripts/lib/baselines/reader.js +321 -0
- package/.agents/scripts/lib/baselines/refresh-service.js +733 -0
- package/.agents/scripts/lib/baselines/scope.js +291 -0
- package/.agents/scripts/lib/baselines/writer.js +312 -0
- package/.agents/scripts/lib/bdd-runner-detect.js +417 -0
- package/.agents/scripts/lib/bdd-scenario-scanner.js +310 -0
- package/.agents/scripts/lib/bootstrap/baselines-layout-migration.js +202 -0
- package/.agents/scripts/lib/bootstrap/branch-protection.js +222 -0
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +171 -0
- package/.agents/scripts/lib/bootstrap/commit-push.js +146 -0
- package/.agents/scripts/lib/bootstrap/gh-list.js +153 -0
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +306 -0
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +89 -0
- package/.agents/scripts/lib/bootstrap/install-ledger.js +174 -0
- package/.agents/scripts/lib/bootstrap/manifest.js +272 -0
- package/.agents/scripts/lib/bootstrap/merge-methods.js +108 -0
- package/.agents/scripts/lib/bootstrap/preflight.js +195 -0
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +801 -0
- package/.agents/scripts/lib/bootstrap/prompt.js +480 -0
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +370 -0
- package/.agents/scripts/lib/bootstrap/summary.js +75 -0
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +256 -0
- package/.agents/scripts/lib/branch-name-guard.js +98 -0
- package/.agents/scripts/lib/c8-cli-path.js +21 -0
- package/.agents/scripts/lib/changed-files.js +184 -0
- package/.agents/scripts/lib/checks/baseline-drift-main-checkout.js +104 -0
- package/.agents/scripts/lib/checks/core-bare-clean.js +48 -0
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +54 -0
- package/.agents/scripts/lib/checks/index.js +288 -0
- package/.agents/scripts/lib/checks/push-hook-parity.js +106 -0
- package/.agents/scripts/lib/checks/stale-origin-epic.js +49 -0
- package/.agents/scripts/lib/checks/state.js +558 -0
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +186 -0
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +182 -0
- package/.agents/scripts/lib/checks/windows-coverage-noise-floor.js +92 -0
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +81 -0
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +55 -0
- package/.agents/scripts/lib/cli/parse-numeric.js +60 -0
- package/.agents/scripts/lib/cli/standard-args.js +351 -0
- package/.agents/scripts/lib/cli-args.js +286 -0
- package/.agents/scripts/lib/cli-utils.js +69 -0
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +44 -0
- package/.agents/scripts/lib/close-validation/projections/inputs.js +86 -0
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +286 -0
- package/.agents/scripts/lib/close-validation.js +897 -0
- package/.agents/scripts/lib/codebase-snapshot.js +513 -0
- package/.agents/scripts/lib/command-header.js +33 -0
- package/.agents/scripts/lib/config/acceptance-eval.js +95 -0
- package/.agents/scripts/lib/config/baselines.js +60 -0
- package/.agents/scripts/lib/config/ci.js +30 -0
- package/.agents/scripts/lib/config/commands.js +36 -0
- package/.agents/scripts/lib/config/defaults.js +119 -0
- package/.agents/scripts/lib/config/explain.js +348 -0
- package/.agents/scripts/lib/config/gates/bundle-size.schema.js +23 -0
- package/.agents/scripts/lib/config/gates/coverage.schema.js +18 -0
- package/.agents/scripts/lib/config/gates/crap.schema.js +33 -0
- package/.agents/scripts/lib/config/gates/duplication.schema.js +26 -0
- package/.agents/scripts/lib/config/gates/index.js +36 -0
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +23 -0
- package/.agents/scripts/lib/config/gates/lint.schema.js +9 -0
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +20 -0
- package/.agents/scripts/lib/config/gates/mutation.schema.js +12 -0
- package/.agents/scripts/lib/config/gates/shared.js +117 -0
- package/.agents/scripts/lib/config/github.js +122 -0
- package/.agents/scripts/lib/config/lifecycle.js +40 -0
- package/.agents/scripts/lib/config/limits.js +211 -0
- package/.agents/scripts/lib/config/paths.js +73 -0
- package/.agents/scripts/lib/config/preflight.js +58 -0
- package/.agents/scripts/lib/config/quality.js +665 -0
- package/.agents/scripts/lib/config/retro.js +77 -0
- package/.agents/scripts/lib/config/runners.js +105 -0
- package/.agents/scripts/lib/config/runtime.js +167 -0
- package/.agents/scripts/lib/config/shared.js +46 -0
- package/.agents/scripts/lib/config/sync-agentrc.js +243 -0
- package/.agents/scripts/lib/config/temp-paths.js +373 -0
- package/.agents/scripts/lib/config/validate-orchestration.js +81 -0
- package/.agents/scripts/lib/config/worktree-isolation.js +80 -0
- package/.agents/scripts/lib/config-resolver.js +298 -0
- package/.agents/scripts/lib/config-schema-shared.js +32 -0
- package/.agents/scripts/lib/config-schema.js +20 -0
- package/.agents/scripts/lib/config-settings-schema-delivery.js +332 -0
- package/.agents/scripts/lib/config-settings-schema-quality.js +165 -0
- package/.agents/scripts/lib/config-settings-schema.js +420 -0
- package/.agents/scripts/lib/coverage-baseline.js +352 -0
- package/.agents/scripts/lib/coverage-capture.js +195 -0
- package/.agents/scripts/lib/coverage-utils.js +239 -0
- package/.agents/scripts/lib/cpu-pool.js +223 -0
- package/.agents/scripts/lib/crap-engine.js +119 -0
- package/.agents/scripts/lib/crap-utils.js +479 -0
- package/.agents/scripts/lib/degraded-mode.js +69 -0
- package/.agents/scripts/lib/dependency-parser.js +129 -0
- package/.agents/scripts/lib/duplicate-search.js +189 -0
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +70 -0
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +197 -0
- package/.agents/scripts/lib/dynamic-workflow/capability.js +396 -0
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +80 -0
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +72 -0
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +90 -0
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +43 -0
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +83 -0
- package/.agents/scripts/lib/env-loader.js +52 -0
- package/.agents/scripts/lib/epic-merge-lock.js +239 -0
- package/.agents/scripts/lib/epic-plan-clarity.js +142 -0
- package/.agents/scripts/lib/epic-plan-ideation.js +228 -0
- package/.agents/scripts/lib/error-redactor.js +125 -0
- package/.agents/scripts/lib/errors/index.js +67 -0
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +230 -0
- package/.agents/scripts/lib/feedback-loop/code-review-graduator.js +207 -0
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +421 -0
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +480 -0
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +229 -0
- package/.agents/scripts/lib/findings/classify-finding.js +195 -0
- package/.agents/scripts/lib/findings/promote-finding.js +353 -0
- package/.agents/scripts/lib/findings/route-finding.js +283 -0
- package/.agents/scripts/lib/findings/semantic-issue-search.js +179 -0
- package/.agents/scripts/lib/findings/severity.js +102 -0
- package/.agents/scripts/lib/gates/baseline-store.js +106 -0
- package/.agents/scripts/lib/gates/friction.js +43 -0
- package/.agents/scripts/lib/gh-exec.js +553 -0
- package/.agents/scripts/lib/git/cached-fetch.js +0 -0
- package/.agents/scripts/lib/git/sync-from-base.js +162 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +213 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +353 -0
- package/.agents/scripts/lib/git-merge-orchestrator.js +261 -0
- package/.agents/scripts/lib/git-utils.js +363 -0
- package/.agents/scripts/lib/github-url.js +29 -0
- package/.agents/scripts/lib/install-cmd-parser.js +51 -0
- package/.agents/scripts/lib/issue-link-parser.js +74 -0
- package/.agents/scripts/lib/json-utils.js +60 -0
- package/.agents/scripts/lib/label-constants.js +169 -0
- package/.agents/scripts/lib/label-taxonomy.js +200 -0
- package/.agents/scripts/lib/maintainability-engine.js +164 -0
- package/.agents/scripts/lib/maintainability-utils.js +343 -0
- package/.agents/scripts/lib/mandrel-catalog.js +170 -0
- package/.agents/scripts/lib/mutation/baseline-snapshot.js +238 -0
- package/.agents/scripts/lib/mutation/config-detector.js +119 -0
- package/.agents/scripts/lib/mutation/stryker-runner.js +306 -0
- package/.agents/scripts/lib/mutation/survivor-report.js +160 -0
- package/.agents/scripts/lib/notifications/notifier.js +75 -0
- package/.agents/scripts/lib/observability/active-story-env.js +182 -0
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +221 -0
- package/.agents/scripts/lib/observability/perf-aggregator.js +887 -0
- package/.agents/scripts/lib/observability/perf-report-readers.js +319 -0
- package/.agents/scripts/lib/observability/perf-report-render.js +182 -0
- package/.agents/scripts/lib/observability/signals-writer.js +296 -0
- package/.agents/scripts/lib/observability/source-classifier.js +103 -0
- package/.agents/scripts/lib/observability/tool-trace-hook.js +417 -0
- package/.agents/scripts/lib/onboard/detect-stack.js +300 -0
- package/.agents/scripts/lib/onboard/scaffold-docs.js +128 -0
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +173 -0
- package/.agents/scripts/lib/orchestration/cascade-grouping.js +275 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +131 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +80 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +132 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +142 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +149 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +158 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +56 -0
- package/.agents/scripts/lib/orchestration/code-review.js +652 -0
- package/.agents/scripts/lib/orchestration/column-sync.js +286 -0
- package/.agents/scripts/lib/orchestration/context-envelope.js +280 -0
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +581 -0
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +88 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +188 -0
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +144 -0
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +206 -0
- package/.agents/scripts/lib/orchestration/doc-reader.js +94 -0
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +473 -0
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +310 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/cli.js +167 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +151 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +74 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +78 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +72 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +155 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +321 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +75 -0
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +86 -0
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/authoring-context.js +197 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/cli-args.js +48 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +94 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +414 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/prompts.js +55 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +105 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +120 -0
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +118 -0
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +295 -0
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +186 -0
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +50 -0
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +146 -0
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +110 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +392 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +217 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +235 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter.js +69 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +32 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +291 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +175 -0
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +37 -0
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +127 -0
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +400 -0
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +285 -0
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +66 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +797 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +619 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +335 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +230 -0
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +363 -0
- package/.agents/scripts/lib/orchestration/error-journal.js +139 -0
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +31 -0
- package/.agents/scripts/lib/orchestration/file-assumptions.js +506 -0
- package/.agents/scripts/lib/orchestration/finalize/close-planning-tickets.js +116 -0
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +241 -0
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +489 -0
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +88 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +219 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +309 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +99 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +123 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +57 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +114 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +426 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +84 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +365 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +72 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +69 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +214 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +137 -0
- package/.agents/scripts/lib/orchestration/label-transitions.js +43 -0
- package/.agents/scripts/lib/orchestration/lifecycle/bus.js +309 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +147 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +155 -0
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +226 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +69 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +378 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +248 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +527 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +259 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +278 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +355 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +647 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +331 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +140 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +421 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +168 -0
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +668 -0
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +322 -0
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +114 -0
- package/.agents/scripts/lib/orchestration/manifest-builder.js +216 -0
- package/.agents/scripts/lib/orchestration/model-attribution.js +390 -0
- package/.agents/scripts/lib/orchestration/parked-follow-ons.js +147 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +87 -0
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +63 -0
- package/.agents/scripts/lib/orchestration/plan-runner/plan-router.js +86 -0
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +212 -0
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +213 -0
- package/.agents/scripts/lib/orchestration/planning-risk.js +155 -0
- package/.agents/scripts/lib/orchestration/planning-state-manager.js +318 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +56 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +33 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +78 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +68 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +118 -0
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +396 -0
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +205 -0
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +47 -0
- package/.agents/scripts/lib/orchestration/preflight-cache.js +164 -0
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +202 -0
- package/.agents/scripts/lib/orchestration/reconciler.js +137 -0
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +152 -0
- package/.agents/scripts/lib/orchestration/recut.js +56 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +127 -0
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +94 -0
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +448 -0
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +335 -0
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +133 -0
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +57 -0
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +275 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +395 -0
- package/.agents/scripts/lib/orchestration/retro-runner.js +171 -0
- package/.agents/scripts/lib/orchestration/review-depth.js +93 -0
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +363 -0
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +205 -0
- package/.agents/scripts/lib/orchestration/review-providers/native.js +805 -0
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +73 -0
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +396 -0
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +373 -0
- package/.agents/scripts/lib/orchestration/review-providers/types.js +89 -0
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +107 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +159 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +194 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +81 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +190 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +70 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +106 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +42 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +73 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +225 -0
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +315 -0
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +149 -0
- package/.agents/scripts/lib/orchestration/skill-capsule-loader.js +110 -0
- package/.agents/scripts/lib/orchestration/spec-freshness.js +320 -0
- package/.agents/scripts/lib/orchestration/spec-renderer.js +456 -0
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +80 -0
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +797 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +163 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +152 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +387 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +266 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +48 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +67 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +161 -0
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +117 -0
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +86 -0
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +147 -0
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +142 -0
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +62 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-scoped.js +221 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix-shared.js +123 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +216 -0
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +636 -0
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +198 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +105 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +222 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +220 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +291 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +234 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +110 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +86 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +112 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +157 -0
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +434 -0
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +290 -0
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +643 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +67 -0
- package/.agents/scripts/lib/orchestration/task-body-validator.js +391 -0
- package/.agents/scripts/lib/orchestration/ticket-lease.js +358 -0
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +783 -0
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +367 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +691 -0
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +723 -0
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +474 -0
- package/.agents/scripts/lib/orchestration/ticketing/state.js +559 -0
- package/.agents/scripts/lib/orchestration/ticketing.js +55 -0
- package/.agents/scripts/lib/orchestration/wave-marker.js +28 -0
- package/.agents/scripts/lib/orchestration/wave-record-io.js +277 -0
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +189 -0
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +423 -0
- package/.agents/scripts/lib/path-security.js +25 -0
- package/.agents/scripts/lib/plan-phase-cleanup.js +125 -0
- package/.agents/scripts/lib/preflight-runner.js +196 -0
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +95 -0
- package/.agents/scripts/lib/presentation/manifest-builder.js +245 -0
- package/.agents/scripts/lib/presentation/manifest-formatter.js +243 -0
- package/.agents/scripts/lib/presentation/manifest-helpers.js +213 -0
- package/.agents/scripts/lib/presentation/manifest-persistence.js +262 -0
- package/.agents/scripts/lib/presentation/manifest-procedures.js +55 -0
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +252 -0
- package/.agents/scripts/lib/presentation/manifest-renderer.js +188 -0
- package/.agents/scripts/lib/presentation/manifest-story-views.js +119 -0
- package/.agents/scripts/lib/provider-factory.js +80 -0
- package/.agents/scripts/lib/push-epic-retry.js +209 -0
- package/.agents/scripts/lib/qa/console-allowlist.js +151 -0
- package/.agents/scripts/lib/qa/coverage-report.js +181 -0
- package/.agents/scripts/lib/qa/coverage-verdict.js +296 -0
- package/.agents/scripts/lib/qa/propose-missing-test.js +95 -0
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +296 -0
- package/.agents/scripts/lib/qa/qa-session.js +197 -0
- package/.agents/scripts/lib/qa/redact-evidence.js +245 -0
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +190 -0
- package/.agents/scripts/lib/qa/resolve-selection.js +373 -0
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +100 -0
- package/.agents/scripts/lib/runtime-deps/manifest.js +96 -0
- package/.agents/scripts/lib/runtime-deps/preflight.js +78 -0
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +202 -0
- package/.agents/scripts/lib/signals/detectors/common.js +36 -0
- package/.agents/scripts/lib/signals/detectors/hotspot.js +298 -0
- package/.agents/scripts/lib/signals/detectors/index.js +14 -0
- package/.agents/scripts/lib/signals/detectors/retry.js +289 -0
- package/.agents/scripts/lib/signals/detectors/rework.js +204 -0
- package/.agents/scripts/lib/signals/index.js +39 -0
- package/.agents/scripts/lib/signals/read.js +268 -0
- package/.agents/scripts/lib/signals/schema.js +225 -0
- package/.agents/scripts/lib/signals/span-tree.js +290 -0
- package/.agents/scripts/lib/signals/write.js +19 -0
- package/.agents/scripts/lib/single-story/confirm-merge.js +201 -0
- package/.agents/scripts/lib/single-story/story-merged-notify.js +126 -0
- package/.agents/scripts/lib/single-story-sweep/protection.js +274 -0
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +169 -0
- package/.agents/scripts/lib/single-story-sweep.js +329 -0
- package/.agents/scripts/lib/skills/parse-skill.js +202 -0
- package/.agents/scripts/lib/skills/walk-skill-files.js +56 -0
- package/.agents/scripts/lib/spec/index.js +36 -0
- package/.agents/scripts/lib/spec/loader.js +425 -0
- package/.agents/scripts/lib/spec/state.js +217 -0
- package/.agents/scripts/lib/story-body/story-body.js +743 -0
- package/.agents/scripts/lib/story-init/blocker-validator.js +68 -0
- package/.agents/scripts/lib/story-init/branch-initializer.js +422 -0
- package/.agents/scripts/lib/story-init/context-resolver.js +92 -0
- package/.agents/scripts/lib/story-init/donor-precheck.js +207 -0
- package/.agents/scripts/lib/story-init/hierarchy-tracer.js +36 -0
- package/.agents/scripts/lib/story-init/state-transitioner.js +80 -0
- package/.agents/scripts/lib/story-init/task-graph-builder.js +114 -0
- package/.agents/scripts/lib/story-init/transition-summary.js +34 -0
- package/.agents/scripts/lib/story-lifecycle.js +186 -0
- package/.agents/scripts/lib/story-plan.js +246 -0
- package/.agents/scripts/lib/task-utils.js +26 -0
- package/.agents/scripts/lib/templates/decomposer-prompts.js +168 -0
- package/.agents/scripts/lib/test-env.js +30 -0
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +52 -0
- package/.agents/scripts/lib/test-isolate/list-files.js +90 -0
- package/.agents/scripts/lib/test-isolate/parse-tap.js +75 -0
- package/.agents/scripts/lib/test-isolate/runner.js +483 -0
- package/.agents/scripts/lib/test-profile/parse-tap.js +136 -0
- package/.agents/scripts/lib/test-profile/render-report.js +45 -0
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +35 -0
- package/.agents/scripts/lib/test-tiers.js +94 -0
- package/.agents/scripts/lib/util/concurrent-map.js +59 -0
- package/.agents/scripts/lib/util/phase-timer-state.js +72 -0
- package/.agents/scripts/lib/util/phase-timer.js +163 -0
- package/.agents/scripts/lib/util/poll-loop.js +86 -0
- package/.agents/scripts/lib/util/with-timeout.js +32 -0
- package/.agents/scripts/lib/validation-evidence.js +323 -0
- package/.agents/scripts/lib/wave-runner/tick.js +665 -0
- package/.agents/scripts/lib/wave-runner/wave-checkpoint.js +91 -0
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +19 -0
- package/.agents/scripts/lib/workers/crap-worker.js +197 -0
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +137 -0
- package/.agents/scripts/lib/workers/maintainability-worker.js +79 -0
- package/.agents/scripts/lib/workspace-provisioner.js +189 -0
- package/.agents/scripts/lib/worktree/bootstrapper.js +48 -0
- package/.agents/scripts/lib/worktree/inspector.js +140 -0
- package/.agents/scripts/lib/worktree/lifecycle/creation.js +118 -0
- package/.agents/scripts/lib/worktree/lifecycle/drift-detection.js +62 -0
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +276 -0
- package/.agents/scripts/lib/worktree/lifecycle/gc.js +49 -0
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +178 -0
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +264 -0
- package/.agents/scripts/lib/worktree/lifecycle/precheck.js +100 -0
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +588 -0
- package/.agents/scripts/lib/worktree/lifecycle/registry-sync.js +124 -0
- package/.agents/scripts/lib/worktree/lifecycle/shared.js +26 -0
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +40 -0
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +349 -0
- package/.agents/scripts/lib/worktree-manager.js +243 -0
- package/.agents/scripts/lifecycle-diff.js +206 -0
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +194 -0
- package/.agents/scripts/lifecycle-emit.js +479 -0
- package/.agents/scripts/lint-baseline.js +507 -0
- package/.agents/scripts/lint-label-vocabulary.js +237 -0
- package/.agents/scripts/loc-delta.js +205 -0
- package/.agents/scripts/notify.js +307 -0
- package/.agents/scripts/package.json +3 -0
- package/.agents/scripts/post-structured-comment.js +127 -0
- package/.agents/scripts/pr-watch-with-update.js +152 -0
- package/.agents/scripts/providers/github/auth.js +65 -0
- package/.agents/scripts/providers/github/board-add.js +63 -0
- package/.agents/scripts/providers/github/branch-protection.js +186 -0
- package/.agents/scripts/providers/github/cache.js +72 -0
- package/.agents/scripts/providers/github/comments.js +131 -0
- package/.agents/scripts/providers/github/compose.js +111 -0
- package/.agents/scripts/providers/github/errors.js +242 -0
- package/.agents/scripts/providers/github/issues.js +242 -0
- package/.agents/scripts/providers/github/labels.js +179 -0
- package/.agents/scripts/providers/github/mappers.js +126 -0
- package/.agents/scripts/providers/github/merge-methods.js +82 -0
- package/.agents/scripts/providers/github/project-board.js +47 -0
- package/.agents/scripts/providers/github/projects-v2-graphql.js +472 -0
- package/.agents/scripts/providers/github/prs.js +103 -0
- package/.agents/scripts/providers/github/request-helpers.js +110 -0
- package/.agents/scripts/providers/github/sub-issues.js +369 -0
- package/.agents/scripts/providers/github/tickets.js +381 -0
- package/.agents/scripts/providers/github/transient-retry.js +62 -0
- package/.agents/scripts/providers/github.js +157 -0
- package/.agents/scripts/quality-preview.js +327 -0
- package/.agents/scripts/quality-watch.js +223 -0
- package/.agents/scripts/render-manifest.js +143 -0
- package/.agents/scripts/resync-status-column.js +176 -0
- package/.agents/scripts/retro-run.js +167 -0
- package/.agents/scripts/run-audit-suite.js +97 -0
- package/.agents/scripts/run-coverage.js +103 -0
- package/.agents/scripts/run-lint.js +94 -0
- package/.agents/scripts/run-test-profile.js +126 -0
- package/.agents/scripts/run-tests.js +185 -0
- package/.agents/scripts/run-verify.js +56 -0
- package/.agents/scripts/select-audits.js +155 -0
- package/.agents/scripts/signals-view.js +294 -0
- package/.agents/scripts/single-story-close.js +83 -0
- package/.agents/scripts/single-story-confirm-merge.js +183 -0
- package/.agents/scripts/single-story-init.js +692 -0
- package/.agents/scripts/stories-wave-tick.js +415 -0
- package/.agents/scripts/story-close.js +246 -0
- package/.agents/scripts/story-deliver-prepare.js +267 -0
- package/.agents/scripts/story-init.js +516 -0
- package/.agents/scripts/story-phase.js +327 -0
- package/.agents/scripts/story-plan.js +284 -0
- package/.agents/scripts/sync-agentrc.js +71 -0
- package/.agents/scripts/sync-branch-from-base.js +138 -0
- package/.agents/scripts/sync-claude-commands.js +151 -0
- package/.agents/scripts/test-isolate.js +222 -0
- package/.agents/scripts/test-wrapper.js +108 -0
- package/.agents/scripts/update-coverage-baseline.js +129 -0
- package/.agents/scripts/update-crap-baseline.js +177 -0
- package/.agents/scripts/update-duplication-baseline.js +134 -0
- package/.agents/scripts/update-maintainability-baseline.js +183 -0
- package/.agents/scripts/update-mutation-baseline.js +189 -0
- package/.agents/scripts/update-ticket-state.js +107 -0
- package/.agents/scripts/validate-docs-freshness.js +259 -0
- package/.agents/scripts/validate-skills.js +278 -0
- package/.agents/scripts/wave-tick.js +335 -0
- package/.agents/skills/core/analyze-execution/SKILL.md +98 -0
- package/.agents/skills/core/api-and-interface-design/SKILL.md +327 -0
- package/.agents/skills/core/baseline-refresh/SKILL.md +181 -0
- package/.agents/skills/core/browser-testing-with-devtools/SKILL.md +352 -0
- package/.agents/skills/core/ci-cd-and-automation/SKILL.md +274 -0
- package/.agents/skills/core/ci-cd-and-automation/examples.md +211 -0
- package/.agents/skills/core/code-review-and-quality/SKILL.md +421 -0
- package/.agents/skills/core/code-simplification/SKILL.md +389 -0
- package/.agents/skills/core/context-engineering/SKILL.md +309 -0
- package/.agents/skills/core/context-engineering/examples.md +58 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +338 -0
- package/.agents/skills/core/deprecation-and-migration/SKILL.md +250 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +79 -0
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +323 -0
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +145 -0
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +425 -0
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +393 -0
- package/.agents/skills/core/frontend-ui-engineering/SKILL.md +357 -0
- package/.agents/skills/core/git-workflow-and-versioning/SKILL.md +352 -0
- package/.agents/skills/core/hydrate-context/SKILL.md +118 -0
- package/.agents/skills/core/idea-refinement/SKILL.md +317 -0
- package/.agents/skills/core/idea-refinement/examples.md +437 -0
- package/.agents/skills/core/idea-refinement/frameworks.md +135 -0
- package/.agents/skills/core/idea-refinement/refinement-criteria.md +155 -0
- package/.agents/skills/core/idea-refinement/scripts/idea-refine.sh +15 -0
- package/.agents/skills/core/incremental-implementation/SKILL.md +271 -0
- package/.agents/skills/core/introducing-a-baseline-gate/SKILL.md +213 -0
- package/.agents/skills/core/knowledge-transfer/SKILL.md +175 -0
- package/.agents/skills/core/mutation-survivor-remediation/SKILL.md +117 -0
- package/.agents/skills/core/performance-optimization/SKILL.md +314 -0
- package/.agents/skills/core/planning-and-task-breakdown/SKILL.md +277 -0
- package/.agents/skills/core/property-based-testing/SKILL.md +148 -0
- package/.agents/skills/core/qa-coverage-mapping/SKILL.md +105 -0
- package/.agents/skills/core/refactoring-discipline/SKILL.md +111 -0
- package/.agents/skills/core/scope-triage/SKILL.md +127 -0
- package/.agents/skills/core/security-and-hardening/SKILL.md +400 -0
- package/.agents/skills/core/shipping-and-launch/SKILL.md +328 -0
- package/.agents/skills/core/spec-driven-development/SKILL.md +252 -0
- package/.agents/skills/core/test-driven-development/SKILL.md +475 -0
- package/.agents/skills/core/using-agent-skills/SKILL.md +232 -0
- package/.agents/skills/skills.index.json +596 -0
- package/.agents/skills/stack/architecture/monorepo-path-strategist/SKILL.md +31 -0
- package/.agents/skills/stack/architecture/structured-output-zod/SKILL.md +51 -0
- package/.agents/skills/stack/architecture/subagent-orchestration/SKILL.md +48 -0
- package/.agents/skills/stack/backend/cloudflare-hono-architect/SKILL.md +31 -0
- package/.agents/skills/stack/backend/cloudflare-hono-architect/examples/route-template.ts +33 -0
- package/.agents/skills/stack/backend/cloudflare-queue-manager/SKILL.md +31 -0
- package/.agents/skills/stack/backend/cloudflare-workers/SKILL.md +51 -0
- package/.agents/skills/stack/backend/highlevel-crm/SKILL.md +54 -0
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/SKILL.md +29 -0
- package/.agents/skills/stack/backend/sqlite-drizzle-expert/examples/schema-template.ts +30 -0
- package/.agents/skills/stack/backend/stripe-integration/SKILL.md +57 -0
- package/.agents/skills/stack/backend/stripe-integration/scripts/listen-stripe.sh +9 -0
- package/.agents/skills/stack/backend/turso-sqlite/SKILL.md +48 -0
- package/.agents/skills/stack/frontend/astro/SKILL.md +62 -0
- package/.agents/skills/stack/frontend/astro-react-island-strategist/SKILL.md +30 -0
- package/.agents/skills/stack/frontend/expo-react-native-developer/SKILL.md +29 -0
- package/.agents/skills/stack/frontend/google-analytics-v4/SKILL.md +50 -0
- package/.agents/skills/stack/frontend/tailwind-v4/SKILL.md +58 -0
- package/.agents/skills/stack/frontend/ui-accessibility-engineer/SKILL.md +34 -0
- package/.agents/skills/stack/qa/audit-accessibility/SKILL.md +51 -0
- package/.agents/skills/stack/qa/gherkin-authoring/SKILL.md +257 -0
- package/.agents/skills/stack/qa/gherkin-authoring/examples/invoice-issue.feature +41 -0
- package/.agents/skills/stack/qa/lighthouse-baseline/SKILL.md +199 -0
- package/.agents/skills/stack/qa/playwright/SKILL.md +50 -0
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +188 -0
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +142 -0
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +220 -0
- package/.agents/skills/stack/qa/vitest/SKILL.md +51 -0
- package/.agents/skills/stack/security/backend-security-patterns/SKILL.md +68 -0
- package/.agents/starter-agentrc.json +22 -0
- package/.agents/templates/agent-protocol.md +72 -0
- package/.agents/templates/docs/architecture.md +30 -0
- package/.agents/templates/docs/decisions.md +24 -0
- package/.agents/templates/epic-from-idea.md +21 -0
- package/.agents/templates/single-story-body.md +17 -0
- package/.agents/workflows/agents-update.md +415 -0
- package/.agents/workflows/audit-architecture.md +312 -0
- package/.agents/workflows/audit-clean-code.md +179 -0
- package/.agents/workflows/audit-dependencies.md +91 -0
- package/.agents/workflows/audit-devops.md +110 -0
- package/.agents/workflows/audit-lighthouse.md +260 -0
- package/.agents/workflows/audit-performance.md +161 -0
- package/.agents/workflows/audit-privacy.md +104 -0
- package/.agents/workflows/audit-quality.md +191 -0
- package/.agents/workflows/audit-security.md +156 -0
- package/.agents/workflows/audit-seo.md +118 -0
- package/.agents/workflows/audit-sre.md +139 -0
- package/.agents/workflows/audit-to-stories.md +257 -0
- package/.agents/workflows/audit-ux-ui.md +102 -0
- package/.agents/workflows/epic-deliver.md +864 -0
- package/.agents/workflows/epic-plan.md +998 -0
- package/.agents/workflows/explain.md +118 -0
- package/.agents/workflows/git-cleanup.md +250 -0
- package/.agents/workflows/git-commit-all.md +15 -0
- package/.agents/workflows/git-merge-pr.md +377 -0
- package/.agents/workflows/git-pr-all.md +278 -0
- package/.agents/workflows/git-push.md +60 -0
- package/.agents/workflows/helpers/_merge-conflict-template.md +54 -0
- package/.agents/workflows/helpers/acceptance-self-eval.md +74 -0
- package/.agents/workflows/helpers/agents-sync-config.md +129 -0
- package/.agents/workflows/helpers/code-quality-guardrails.md +101 -0
- package/.agents/workflows/helpers/code-review.md +370 -0
- package/.agents/workflows/helpers/diagnose.md +117 -0
- package/.agents/workflows/helpers/epic-audit.md +295 -0
- package/.agents/workflows/helpers/epic-deliver-story.md +370 -0
- package/.agents/workflows/helpers/epic-plan-decompose.md +199 -0
- package/.agents/workflows/helpers/epic-plan-spec.md +184 -0
- package/.agents/workflows/helpers/epic-testing.md +125 -0
- package/.agents/workflows/helpers/parallel-tooling.md +88 -0
- package/.agents/workflows/helpers/signals.md +112 -0
- package/.agents/workflows/helpers/single-story-deliver.md +636 -0
- package/.agents/workflows/helpers/worktree-lifecycle.md +317 -0
- package/.agents/workflows/onboard.md +207 -0
- package/.agents/workflows/qa-assist.md +293 -0
- package/.agents/workflows/qa-explore.md +350 -0
- package/.agents/workflows/qa-run-harness.md +288 -0
- package/.agents/workflows/story-deliver.md +327 -0
- package/.agents/workflows/story-plan.md +233 -0
- package/LICENSE +21 -0
- package/README.md +193 -0
- package/bin/mandrel.js +56 -0
- package/bin/postinstall.js +195 -0
- package/lib/cli/__tests__/migrate.test.js +268 -0
- package/lib/cli/__tests__/sync-local-zone.test.js +247 -0
- package/lib/cli/__tests__/sync.test.js +372 -0
- package/lib/cli/__tests__/update-major.test.js +217 -0
- package/lib/cli/__tests__/update.test.js +696 -0
- package/lib/cli/__tests__/version-check.test.js +398 -0
- package/lib/cli/doctor.js +124 -0
- package/lib/cli/explain.js +107 -0
- package/lib/cli/migrate.js +260 -0
- package/lib/cli/registry.js +830 -0
- package/lib/cli/sync-commands.js +50 -0
- package/lib/cli/sync.js +200 -0
- package/lib/cli/uninstall.js +795 -0
- package/lib/cli/update.js +854 -0
- package/lib/cli/version-check.js +206 -0
- package/lib/migrations/README.md +69 -0
- package/lib/migrations/__tests__/index.test.js +216 -0
- package/lib/migrations/index.js +164 -0
- package/package.json +105 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file planning-state-manager.js
|
|
3
|
+
* Extracted state-healing and artifact idempotency logic for epic planning.
|
|
4
|
+
*
|
|
5
|
+
* Invariant: After planning completes, exactly ONE open PRD and ONE open
|
|
6
|
+
* Tech Spec must exist as sub-issues of the Epic. All others are closed
|
|
7
|
+
* (state_reason: 'not_planned') and detached.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Logger } from '../Logger.js';
|
|
11
|
+
import {
|
|
12
|
+
ACCEPTANCE_NA,
|
|
13
|
+
AGENT_LABELS,
|
|
14
|
+
CONTEXT_LABELS,
|
|
15
|
+
} from '../label-constants.js';
|
|
16
|
+
import { concurrentMap } from '../util/concurrent-map.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Snapshot of the Epic's planning-artifact state as seen / mutated by
|
|
20
|
+
* {@link PlanningStateManager}. Mirrors the `epic-plan-state` structured
|
|
21
|
+
* comment schema owned by `epic-plan-state-store.js`, narrowed to the fields
|
|
22
|
+
* this manager reads and rewrites.
|
|
23
|
+
*
|
|
24
|
+
* @typedef {object} PlanCheckpointState
|
|
25
|
+
* @property {number} epicId Epic ticket id.
|
|
26
|
+
* @property {{ prd: (number | null), techSpec: (number | null), acceptanceSpec: (number | null) }} linkedIssues Canonical planning-artifact references persisted on the Epic.
|
|
27
|
+
* @property {string} body Current Epic body (may include a `## Planning Artifacts` section).
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Heals and de-duplicates the Epic's PRD / Tech Spec planning artifacts so
|
|
32
|
+
* the post-state invariant holds: exactly ONE open PRD and ONE open Tech
|
|
33
|
+
* Spec, both linked from the Epic body. All redundant artifacts are closed
|
|
34
|
+
* (`state_reason: 'not_planned'`) and detached.
|
|
35
|
+
*/
|
|
36
|
+
export class PlanningStateManager {
|
|
37
|
+
/**
|
|
38
|
+
* @param {import('../ITicketingProvider.js').ITicketingProvider} provider Ticketing provider used for ticket + sub-issue mutations.
|
|
39
|
+
*/
|
|
40
|
+
constructor(provider) {
|
|
41
|
+
this.provider = provider;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Resolve existing planning artifacts and heal / clean up the graph.
|
|
46
|
+
*
|
|
47
|
+
* With `force=false` (normal run):
|
|
48
|
+
* - Pick the canonical PRD / Tech Spec (first open one, else first overall).
|
|
49
|
+
* - Heal dangling `epic.linkedIssues` references.
|
|
50
|
+
* - Close + detach any redundant artifacts (posting an audit-trace
|
|
51
|
+
* notification first).
|
|
52
|
+
* - Persist the healed references back to the Epic body if they were not
|
|
53
|
+
* already written.
|
|
54
|
+
*
|
|
55
|
+
* With `force=true` (re-plan requested): **overwrite the canonical
|
|
56
|
+
* context tickets in place.** Keep the canonical PRD / Tech Spec /
|
|
57
|
+
* Acceptance Spec **open** and keep `epic.linkedIssues` pointing at them
|
|
58
|
+
* (so the caller can refresh their bodies via `provider.updateTicket`),
|
|
59
|
+
* close + detach only the redundant duplicate artifacts (exactly as the
|
|
60
|
+
* non-force path does), and strip the `## Planning Artifacts` section
|
|
61
|
+
* from the Epic body so the caller re-appends it pointing at the same
|
|
62
|
+
* preserved IDs. Context tickets are no longer closed-and-recreated on a
|
|
63
|
+
* forced re-plan; only Feature/Story child tickets keep that behaviour
|
|
64
|
+
* (handled outside this manager by `forceCloseExistingChildren`).
|
|
65
|
+
*
|
|
66
|
+
* Mutates `epic.linkedIssues` and `epic.body` in place.
|
|
67
|
+
*
|
|
68
|
+
* @param {PlanCheckpointState & { linkedIssues: object, body: string, id: number }} epic Epic ticket with mutable planning state.
|
|
69
|
+
* @param {boolean} [force=false] When true, preserve canonical context tickets (overwrite-in-place) and strip the Planning Artifacts body section for a forced re-plan.
|
|
70
|
+
* @returns {Promise<void>}
|
|
71
|
+
* @throws {Error} Propagates non-404/410 errors from `provider.updateTicket`. All other provider errors are intentionally swallowed.
|
|
72
|
+
*/
|
|
73
|
+
async healAndCleanupArtifacts(epic, force = false) {
|
|
74
|
+
const epicId = epic.id;
|
|
75
|
+
const relatedTickets = await this.provider.getTickets(epicId);
|
|
76
|
+
this.provider.primeTicketCache(relatedTickets);
|
|
77
|
+
|
|
78
|
+
// One descriptor per planning-artifact type. Each entry parameterizes
|
|
79
|
+
// the label filter, the canonical reference key on `epic.linkedIssues`,
|
|
80
|
+
// and a human-readable name for the heal log line, so the per-type
|
|
81
|
+
// filter / canonical / heal / successor logic runs from a single loop
|
|
82
|
+
// instead of three inlined copies.
|
|
83
|
+
const ARTIFACT_TYPES = [
|
|
84
|
+
{ label: CONTEXT_LABELS.PRD, key: 'prd', name: 'PRD' },
|
|
85
|
+
{ label: CONTEXT_LABELS.TECH_SPEC, key: 'techSpec', name: 'Tech Spec' },
|
|
86
|
+
{
|
|
87
|
+
label: CONTEXT_LABELS.ACCEPTANCE_SPEC,
|
|
88
|
+
key: 'acceptanceSpec',
|
|
89
|
+
name: 'Acceptance Spec',
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
// Resolve each artifact type: collect ALL matching tickets (open AND
|
|
94
|
+
// closed) so stale sub-issue links get cleaned up regardless of state;
|
|
95
|
+
// pick the canonical one (first open, else first overall); heal a
|
|
96
|
+
// dangling `epic.linkedIssues` reference; and record the resolved
|
|
97
|
+
// canonical id for successor resolution below.
|
|
98
|
+
const resolved = ARTIFACT_TYPES.map((descriptor) => {
|
|
99
|
+
const all = relatedTickets.filter((t) =>
|
|
100
|
+
t.labels.includes(descriptor.label),
|
|
101
|
+
);
|
|
102
|
+
const canonical = all.find((t) => t.state === 'open') ?? all[0] ?? null;
|
|
103
|
+
|
|
104
|
+
if (!epic.linkedIssues[descriptor.key] && canonical?.state === 'open') {
|
|
105
|
+
epic.linkedIssues[descriptor.key] = canonical.id;
|
|
106
|
+
Logger.info(
|
|
107
|
+
`[Epic Planner] Healed dangling ${descriptor.name} reference: #${epic.linkedIssues[descriptor.key]}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const canonicalId = epic.linkedIssues[descriptor.key] ?? canonical?.id;
|
|
112
|
+
return { ...descriptor, all, canonicalId };
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Identify redundant artifacts: everything that is NOT the canonical one.
|
|
116
|
+
const redundant = resolved.flatMap((r) =>
|
|
117
|
+
r.all.filter((t) => t.id !== r.canonicalId),
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// Map artifact label → resolved canonical id, for successor resolution.
|
|
121
|
+
const successorByLabel = new Map(
|
|
122
|
+
resolved.map((r) => [r.label, r.canonicalId]),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// Bound the close+detach mutation burst at 3 so wide redundancy
|
|
126
|
+
// cleanup does not race the GitHub secondary rate limit.
|
|
127
|
+
await concurrentMap(
|
|
128
|
+
redundant,
|
|
129
|
+
async (t) => {
|
|
130
|
+
const descriptor = ARTIFACT_TYPES.find((d) =>
|
|
131
|
+
t.labels.includes(d.label),
|
|
132
|
+
);
|
|
133
|
+
const successorId = descriptor
|
|
134
|
+
? successorByLabel.get(descriptor.label)
|
|
135
|
+
: undefined;
|
|
136
|
+
Logger.info(
|
|
137
|
+
`[Epic Planner] Cleaning up redundant artifact #${t.id} (superseded by #${successorId})...`,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Close the issue if it's still open
|
|
141
|
+
if (t.state === 'open') {
|
|
142
|
+
try {
|
|
143
|
+
await this.provider.postComment(t.id, {
|
|
144
|
+
type: 'notification',
|
|
145
|
+
body: `⚠️ **Audit Trace**: This planning artifact was created during an interrupted or failed orchestration run and is now **superseded by #${successorId}**. \n\nClosing this issue to maintain a single source of truth for Epic #${epicId}.`,
|
|
146
|
+
});
|
|
147
|
+
} catch (err) {
|
|
148
|
+
Logger.warn(
|
|
149
|
+
`[Epic Planner] Could not post audit-trace comment on #${t.id}: ${err.message}`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
await this.provider.updateTicket(t.id, {
|
|
153
|
+
state: 'closed',
|
|
154
|
+
state_reason: 'not_planned',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Detach the sub-issue from the Epic to prevent orphaned links
|
|
159
|
+
try {
|
|
160
|
+
await this.provider.removeSubIssue(epicId, t.id);
|
|
161
|
+
Logger.info(
|
|
162
|
+
`[Epic Planner] Detached #${t.id} from Epic #${epicId}.`,
|
|
163
|
+
);
|
|
164
|
+
} catch (_err) {
|
|
165
|
+
// Already detached or API doesn't support — safe to ignore
|
|
166
|
+
Logger.info(
|
|
167
|
+
`[Epic Planner] Could not detach #${t.id} (may already be detached).`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
{ concurrency: 3 },
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Persist healed references to the body if needed.
|
|
175
|
+
if (
|
|
176
|
+
!force &&
|
|
177
|
+
epic.linkedIssues.prd &&
|
|
178
|
+
epic.linkedIssues.techSpec &&
|
|
179
|
+
!epic.body.includes('## Planning Artifacts')
|
|
180
|
+
) {
|
|
181
|
+
Logger.info(
|
|
182
|
+
`[Epic Planner] Persisting healed references to Epic body...`,
|
|
183
|
+
);
|
|
184
|
+
const appendBody = `\n\n## Planning Artifacts\n- [ ] PRD: #${epic.linkedIssues.prd}\n- [ ] Tech Spec: #${epic.linkedIssues.techSpec}\n`;
|
|
185
|
+
await this.provider.updateTicket(epicId, {
|
|
186
|
+
body: epic.body + appendBody,
|
|
187
|
+
});
|
|
188
|
+
epic.body += appendBody;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Force re-plan: overwrite the canonical context tickets in place.
|
|
192
|
+
// The redundant duplicates have already been closed + detached by the
|
|
193
|
+
// cleanup pass above. Here we only strip the `## Planning Artifacts`
|
|
194
|
+
// body section so `planEpic` re-appends it pointing at the same
|
|
195
|
+
// preserved canonical IDs. We deliberately DO NOT close the canonical
|
|
196
|
+
// PRD / Tech Spec / Acceptance Spec, and we keep `epic.linkedIssues`
|
|
197
|
+
// pointing at them so the caller can refresh their bodies.
|
|
198
|
+
if (force) {
|
|
199
|
+
const stripped = epic.body.replace(
|
|
200
|
+
/\n*## Planning Artifacts[\s\S]*$/,
|
|
201
|
+
'',
|
|
202
|
+
);
|
|
203
|
+
if (stripped !== epic.body) {
|
|
204
|
+
await this.provider.updateTicket(epicId, { body: stripped });
|
|
205
|
+
epic.body = stripped;
|
|
206
|
+
Logger.info(
|
|
207
|
+
'[Epic Planner] Stripped old Planning Artifacts section from Epic body (canonical context tickets preserved for in-place overwrite).',
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Compute whether an Epic is ready to transition from `agent::review-spec`
|
|
215
|
+
* to `agent::ready` by inspecting the state of its context tickets.
|
|
216
|
+
*
|
|
217
|
+
* An Epic is ready when **all three** context tickets — PRD, Tech Spec, and
|
|
218
|
+
* Acceptance Spec — exist and are closed. The acceptance-spec requirement
|
|
219
|
+
* can be waived by attaching the `acceptance::n-a` label to the Epic, in
|
|
220
|
+
* which case acceptance-spec presence and state are ignored. Missing PRD
|
|
221
|
+
* or Tech Spec is never waivable through this method.
|
|
222
|
+
*
|
|
223
|
+
* This predicate is **pure** with respect to the world: it reads tickets
|
|
224
|
+
* via the provider and computes a verdict. Callers (e.g. the planning
|
|
225
|
+
* runner) are responsible for actually flipping the label when
|
|
226
|
+
* `ready === true`.
|
|
227
|
+
*
|
|
228
|
+
* @param {number} epicId Epic ticket id.
|
|
229
|
+
* @returns {Promise<{ ready: boolean, reason: string, contexts: { prd: ('open' | 'closed' | 'missing'), techSpec: ('open' | 'closed' | 'missing'), acceptanceSpec: ('open' | 'closed' | 'missing' | 'waived') } }>}
|
|
230
|
+
* `ready` is `true` when the Epic satisfies the readiness gate.
|
|
231
|
+
* `reason` is a machine-readable code suitable for logging / metrics
|
|
232
|
+
* (`all-context-closed`, `acceptance-waived`, `prd-missing`,
|
|
233
|
+
* `prd-open`, `tech-spec-missing`, `tech-spec-open`,
|
|
234
|
+
* `acceptance-spec-missing`, `acceptance-spec-open`).
|
|
235
|
+
* `contexts` is per-axis status for callers that want to render the
|
|
236
|
+
* verdict alongside ticket links.
|
|
237
|
+
*/
|
|
238
|
+
async computeReviewReadiness(epicId) {
|
|
239
|
+
const epic = await this.provider.getTicket(epicId);
|
|
240
|
+
const relatedTickets = await this.provider.getTickets(epicId);
|
|
241
|
+
this.provider.primeTicketCache(relatedTickets);
|
|
242
|
+
|
|
243
|
+
const epicLabels = epic?.labels ?? [];
|
|
244
|
+
const acceptanceWaived = epicLabels.includes(ACCEPTANCE_NA);
|
|
245
|
+
|
|
246
|
+
const findByLabel = (label) =>
|
|
247
|
+
relatedTickets.find((t) => (t.labels ?? []).includes(label)) ?? null;
|
|
248
|
+
|
|
249
|
+
const prd = findByLabel(CONTEXT_LABELS.PRD);
|
|
250
|
+
const techSpec = findByLabel(CONTEXT_LABELS.TECH_SPEC);
|
|
251
|
+
const acceptanceSpec = findByLabel(CONTEXT_LABELS.ACCEPTANCE_SPEC);
|
|
252
|
+
|
|
253
|
+
const axisStatus = (ticket) => {
|
|
254
|
+
if (!ticket) return 'missing';
|
|
255
|
+
return ticket.state === 'closed' ? 'closed' : 'open';
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const contexts = {
|
|
259
|
+
prd: axisStatus(prd),
|
|
260
|
+
techSpec: axisStatus(techSpec),
|
|
261
|
+
acceptanceSpec: acceptanceWaived ? 'waived' : axisStatus(acceptanceSpec),
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
if (contexts.prd === 'missing') {
|
|
265
|
+
return { ready: false, reason: 'prd-missing', contexts };
|
|
266
|
+
}
|
|
267
|
+
if (contexts.prd === 'open') {
|
|
268
|
+
return { ready: false, reason: 'prd-open', contexts };
|
|
269
|
+
}
|
|
270
|
+
if (contexts.techSpec === 'missing') {
|
|
271
|
+
return { ready: false, reason: 'tech-spec-missing', contexts };
|
|
272
|
+
}
|
|
273
|
+
if (contexts.techSpec === 'open') {
|
|
274
|
+
return { ready: false, reason: 'tech-spec-open', contexts };
|
|
275
|
+
}
|
|
276
|
+
if (!acceptanceWaived) {
|
|
277
|
+
if (contexts.acceptanceSpec === 'missing') {
|
|
278
|
+
return { ready: false, reason: 'acceptance-spec-missing', contexts };
|
|
279
|
+
}
|
|
280
|
+
if (contexts.acceptanceSpec === 'open') {
|
|
281
|
+
return { ready: false, reason: 'acceptance-spec-open', contexts };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
ready: true,
|
|
287
|
+
reason: acceptanceWaived ? 'acceptance-waived' : 'all-context-closed',
|
|
288
|
+
contexts,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* If the Epic satisfies {@link computeReviewReadiness}, flip it from
|
|
294
|
+
* `agent::review-spec` to `agent::ready`. Returns the verdict plus the
|
|
295
|
+
* label transition that was applied (if any). No-ops when readiness is
|
|
296
|
+
* not yet satisfied — callers are expected to retry on the next planning
|
|
297
|
+
* tick rather than block.
|
|
298
|
+
*
|
|
299
|
+
* @param {number} epicId
|
|
300
|
+
* @returns {Promise<{ ready: boolean, reason: string, contexts: object, transitioned: boolean }>}
|
|
301
|
+
*/
|
|
302
|
+
async flipEpicToReadyIfContextClosed(epicId) {
|
|
303
|
+
const verdict = await this.computeReviewReadiness(epicId);
|
|
304
|
+
if (!verdict.ready) {
|
|
305
|
+
return { ...verdict, transitioned: false };
|
|
306
|
+
}
|
|
307
|
+
await this.provider.updateTicket(epicId, {
|
|
308
|
+
labels: {
|
|
309
|
+
add: [AGENT_LABELS.READY],
|
|
310
|
+
remove: [AGENT_LABELS.REVIEW_SPEC],
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
Logger.info(
|
|
314
|
+
`[Epic Planner] Epic #${epicId} → ${AGENT_LABELS.READY} (${verdict.reason}).`,
|
|
315
|
+
);
|
|
316
|
+
return { ...verdict, transitioned: true };
|
|
317
|
+
}
|
|
318
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phases/branch-cleanup.js — post-merge Story branch deletion phase.
|
|
3
|
+
*
|
|
4
|
+
* Delegates the "delete this branch from local + remote, treat not-found
|
|
5
|
+
* as success" idempotency contract to `lib/git-branch-cleanup.js` so the
|
|
6
|
+
* deletion rules live in one place. A local delete failure is logged
|
|
7
|
+
* loudly (operators usually need to investigate a stale worktree),
|
|
8
|
+
* while a remote not-found is treated as a no-op.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { deleteBranchBoth } from '../../../git-branch-cleanup.js';
|
|
12
|
+
|
|
13
|
+
function reapPhaseLogger(progress) {
|
|
14
|
+
return progress ?? (() => {});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function branchCleanupPhase(ctx, state = {}) {
|
|
18
|
+
const {
|
|
19
|
+
storyBranch,
|
|
20
|
+
repoRoot,
|
|
21
|
+
progress,
|
|
22
|
+
logger,
|
|
23
|
+
branchCleanup = deleteBranchBoth,
|
|
24
|
+
} = ctx;
|
|
25
|
+
const log = reapPhaseLogger(progress);
|
|
26
|
+
log('CLEANUP', `Deleting story branch: ${storyBranch}`);
|
|
27
|
+
|
|
28
|
+
const result = branchCleanup(storyBranch, {
|
|
29
|
+
cwd: repoRoot,
|
|
30
|
+
noVerify: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (!result.local.deleted) {
|
|
34
|
+
const stderr = (result.local.stderr || '').trim();
|
|
35
|
+
const reapStatus = state.worktreeReap?.status;
|
|
36
|
+
logger.error(
|
|
37
|
+
` Local branch ${storyBranch} delete failed: ${stderr || 'unknown'}. ` +
|
|
38
|
+
`Check for stale worktrees (git worktree list).` +
|
|
39
|
+
(reapStatus ? ` worktreeReap=${reapStatus}.` : ''),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
if (result.remote.deleted) {
|
|
43
|
+
if (result.remote.reason === 'not-found') {
|
|
44
|
+
log('CLEANUP', `Remote branch ${storyBranch} not found — skipped`);
|
|
45
|
+
} else {
|
|
46
|
+
log('CLEANUP', `✅ Remote branch ${storyBranch} deleted`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
localDeleted: result.local.deleted,
|
|
52
|
+
remoteDeleted: result.remote.deleted,
|
|
53
|
+
localReason: result.local.reason,
|
|
54
|
+
remoteReason: result.remote.reason,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phases/dashboard-refresh.js — regenerate the dispatch manifest after
|
|
3
|
+
* a Story merges into its Epic branch. Honors `--skip-dashboard` so
|
|
4
|
+
* operators running an out-of-band close can suppress the I/O.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { generateAndSaveManifest } from '../../../../dispatcher.js';
|
|
8
|
+
|
|
9
|
+
function reapPhaseLogger(progress) {
|
|
10
|
+
return progress ?? (() => {});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function dashboardRefreshPhase(ctx) {
|
|
14
|
+
const {
|
|
15
|
+
epicId,
|
|
16
|
+
provider,
|
|
17
|
+
skipDashboard,
|
|
18
|
+
progress,
|
|
19
|
+
generateManifestFn = generateAndSaveManifest,
|
|
20
|
+
} = ctx;
|
|
21
|
+
const log = reapPhaseLogger(progress);
|
|
22
|
+
if (skipDashboard) {
|
|
23
|
+
log(
|
|
24
|
+
'DASHBOARD',
|
|
25
|
+
'⏭️ Skipping dashboard refresh (--skip-dashboard flag set)',
|
|
26
|
+
);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
log('DASHBOARD', 'Regenerating dispatch manifest...');
|
|
30
|
+
await generateManifestFn(epicId, true, { provider });
|
|
31
|
+
log('DASHBOARD', '✅ Dashboard manifest updated (temp/)');
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phases/notification.js — post-merge story-complete notification phase.
|
|
3
|
+
*
|
|
4
|
+
* Fires a single consolidated story-merged webhook, then a rolled-up
|
|
5
|
+
* `epic-progress` webhook (comment-suppressed) so operators see the
|
|
6
|
+
* Epic's stories-done count tick up at each story-close without
|
|
7
|
+
* subscribing to the per-story `story-merged` channel. The rolled-up
|
|
8
|
+
* dispatch is best-effort — a flaky webhook MUST NOT block story-close.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { notify } from '../../../../notify.js';
|
|
12
|
+
import { Logger } from '../../../Logger.js';
|
|
13
|
+
|
|
14
|
+
function reapPhaseLogger(progress) {
|
|
15
|
+
return progress ?? (() => {});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function notificationPhase(ctx, state) {
|
|
19
|
+
const {
|
|
20
|
+
epicId,
|
|
21
|
+
storyId,
|
|
22
|
+
story,
|
|
23
|
+
epicBranch,
|
|
24
|
+
orchestration,
|
|
25
|
+
progress,
|
|
26
|
+
provider,
|
|
27
|
+
notifyFn = notify,
|
|
28
|
+
logger = Logger,
|
|
29
|
+
} = ctx;
|
|
30
|
+
const closedTickets = state.ticketClosure?.closedTickets ?? [];
|
|
31
|
+
const log = reapPhaseLogger(progress);
|
|
32
|
+
log('NOTIFY', `Sending story-complete notification for Story #${storyId}...`);
|
|
33
|
+
await notifyFn(
|
|
34
|
+
epicId,
|
|
35
|
+
{
|
|
36
|
+
severity: 'medium',
|
|
37
|
+
message: `✅ Story #${storyId} — *${story.title}* — has been completed and merged into \`${epicBranch}\`. ${closedTickets.length} ticket(s) closed.`,
|
|
38
|
+
event: 'story-merged',
|
|
39
|
+
level: 'story',
|
|
40
|
+
epicId,
|
|
41
|
+
},
|
|
42
|
+
{ orchestration },
|
|
43
|
+
);
|
|
44
|
+
// Fire a rolled-up `epic-progress` webhook so operators see the Epic's
|
|
45
|
+
// overall stories-done count tick up at each story-close, without
|
|
46
|
+
// subscribing to the per-story `story-merged` channel. Comment is
|
|
47
|
+
// suppressed (skipComment: true) — the operator-facing GitHub
|
|
48
|
+
// comment is owned by the wave-record path; this fire is webhook-only.
|
|
49
|
+
// Failures are swallowed by design (warn-then-continue) so a flaky
|
|
50
|
+
// webhook never blocks story-close.
|
|
51
|
+
if (provider && epicId) {
|
|
52
|
+
try {
|
|
53
|
+
const subs = (await provider.getSubTickets?.(epicId)) ?? [];
|
|
54
|
+
const stories = subs.filter(
|
|
55
|
+
(t) => Array.isArray(t.labels) && t.labels.includes('type::story'),
|
|
56
|
+
);
|
|
57
|
+
const total = stories.length;
|
|
58
|
+
const done = stories.filter((s) => s.state === 'closed').length;
|
|
59
|
+
const pct = total === 0 ? 0 : Math.round((done / total) * 100);
|
|
60
|
+
await notifyFn(
|
|
61
|
+
epicId,
|
|
62
|
+
{
|
|
63
|
+
severity: 'medium',
|
|
64
|
+
message: `Epic #${epicId} progress · ${done}/${total} stories done (${pct}%) · Story #${storyId} merged`,
|
|
65
|
+
event: 'epic-progress',
|
|
66
|
+
level: 'epic',
|
|
67
|
+
epicId,
|
|
68
|
+
},
|
|
69
|
+
{ orchestration, skipComment: true },
|
|
70
|
+
);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
logger?.warn?.(
|
|
73
|
+
`[notificationPhase] rolled-up epic-progress dispatch failed (swallowed): ${err?.message ?? err}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
log('NOTIFY', '✅ Notification sent');
|
|
78
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phases/temp-cleanup.js — remove the per-Story manifest pair under
|
|
3
|
+
* `temp/epic-<eid>/stories/story-<sid>/manifest.{md,json}` (Epic #1030
|
|
4
|
+
* Story #1040). Falls back to the legacy flat
|
|
5
|
+
* `temp/story-manifest-<id>.{md,json}` layout when `epicId` is unknown
|
|
6
|
+
* — both paths are tried so partial migrations don't leak files in
|
|
7
|
+
* either layout. All deletes are idempotent; ENOENT is silently
|
|
8
|
+
* absorbed.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { storyArtifactPath } from '../../../config/temp-paths.js';
|
|
13
|
+
|
|
14
|
+
function reapPhaseLogger(progress) {
|
|
15
|
+
return progress ?? (() => {});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function tempCleanupPhase(ctx) {
|
|
19
|
+
const { storyId, epicId, projectRoot, progress, unlinkFn, config } = ctx;
|
|
20
|
+
const log = reapPhaseLogger(progress);
|
|
21
|
+
const unlink = unlinkFn ?? (await import('node:fs/promises')).unlink;
|
|
22
|
+
|
|
23
|
+
// Per-Epic layout (Epic #1030 Story #1040): `temp/epic-<eid>/stories/story-<sid>/manifest.{md,json}`.
|
|
24
|
+
// Legacy flat layout: `temp/story-manifest-<sid>.{md,json}`. The migration
|
|
25
|
+
// tolerates both — try the per-Epic path first when `epicId` is known,
|
|
26
|
+
// and always sweep the legacy path so a half-migrated cohort doesn't
|
|
27
|
+
// leave residue.
|
|
28
|
+
const targets = [];
|
|
29
|
+
if (epicId) {
|
|
30
|
+
const eid = Number(epicId);
|
|
31
|
+
const sid = Number(storyId);
|
|
32
|
+
targets.push(
|
|
33
|
+
{
|
|
34
|
+
path: storyArtifactPath(eid, sid, 'manifest.md', config),
|
|
35
|
+
label: `temp/epic-${epicId}/stories/story-${storyId}/manifest.md`,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
path: storyArtifactPath(eid, sid, 'manifest.json', config),
|
|
39
|
+
label: `temp/epic-${epicId}/stories/story-${storyId}/manifest.json`,
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
// Legacy flat layout is rooted at the framework's projectRoot — this is
|
|
44
|
+
// a half-migrated-cohort sweep, not a configured-tempRoot target. Once
|
|
45
|
+
// the legacy paths can no longer exist on any live install, this block
|
|
46
|
+
// can be deleted entirely.
|
|
47
|
+
const legacyBase = path.join(
|
|
48
|
+
projectRoot,
|
|
49
|
+
'temp',
|
|
50
|
+
`story-manifest-${storyId}`,
|
|
51
|
+
);
|
|
52
|
+
targets.push(
|
|
53
|
+
{ path: `${legacyBase}.md`, label: `temp/story-manifest-${storyId}.md` },
|
|
54
|
+
{
|
|
55
|
+
path: `${legacyBase}.json`,
|
|
56
|
+
label: `temp/story-manifest-${storyId}.json`,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
for (const target of targets) {
|
|
61
|
+
try {
|
|
62
|
+
await unlink(target.path);
|
|
63
|
+
log('CLEANUP', `🗑️ Deleted ${target.label}`);
|
|
64
|
+
} catch {
|
|
65
|
+
// File may not exist — deletion is idempotent.
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phases/ticket-closure.js — post-merge ticket transition + cascade phase.
|
|
3
|
+
*
|
|
4
|
+
* Transitions the Story to `agent::done`, then runs cascade completion
|
|
5
|
+
* so any parent Feature/Epic that is now fully resolved closes too.
|
|
6
|
+
*
|
|
7
|
+
* **3-tier closure (Story #3127).** Under the 3-tier hierarchy a Story
|
|
8
|
+
* is the leaf unit of execution and has no child tickets — `tasks`
|
|
9
|
+
* arrives as an empty array. `batchTransitionTickets` handles the empty
|
|
10
|
+
* input cleanly (the loop trivially completes), the Story is
|
|
11
|
+
* transitioned alone, and cascade completion walks upward to
|
|
12
|
+
* Feature/Epic. No branch on hierarchy mode is required here.
|
|
13
|
+
*
|
|
14
|
+
* Notifications are intentionally
|
|
15
|
+
* NOT routed through the per-ticket transitions here — `notificationPhase`
|
|
16
|
+
* fires a single rolled-up story-complete message immediately after this
|
|
17
|
+
* phase, so threading `notify` through would double-emit events on every
|
|
18
|
+
* close (Story #2534 / Task #2539).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { batchTransitionTickets } from '../../../story-lifecycle.js';
|
|
22
|
+
import { toDone } from '../../label-transitions.js';
|
|
23
|
+
import { cascadeCompletion, STATE_LABELS } from '../../ticketing.js';
|
|
24
|
+
|
|
25
|
+
function reapPhaseLogger(progress) {
|
|
26
|
+
return progress ?? (() => {});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function ticketClosurePhase(ctx) {
|
|
30
|
+
const { provider, tasks, storyId, progress, logger } = ctx;
|
|
31
|
+
const log = reapPhaseLogger(progress);
|
|
32
|
+
|
|
33
|
+
// The `notify` function is intentionally NOT forwarded to per-ticket
|
|
34
|
+
// transitions here. `notificationPhase` fires a single consolidated
|
|
35
|
+
// story-complete message immediately after this phase; passing notify
|
|
36
|
+
// through would emit redundant state-transition events (one from the
|
|
37
|
+
// cascade-up triggered by any child ticket, one from the explicit
|
|
38
|
+
// Story toDone below) that show up as duplicate Slack/webhook lines per
|
|
39
|
+
// story close.
|
|
40
|
+
log(
|
|
41
|
+
'TICKETS',
|
|
42
|
+
`Transitioning ${tasks.length} child ticket(s) to agent::done...`,
|
|
43
|
+
);
|
|
44
|
+
const batch = await batchTransitionTickets(
|
|
45
|
+
provider,
|
|
46
|
+
tasks,
|
|
47
|
+
STATE_LABELS.DONE,
|
|
48
|
+
{ progress: log },
|
|
49
|
+
);
|
|
50
|
+
const closedTickets = [...batch.transitioned, ...batch.skipped];
|
|
51
|
+
|
|
52
|
+
// Story #2534 / Task #2539 — auto-transition `agent::closing →
|
|
53
|
+
// agent::done` deterministically and idempotently on every successful
|
|
54
|
+
// merge. The pre-Story #2534 path silently swallowed transport errors
|
|
55
|
+
// here, which made an already-merged-but-not-labelled Story look closed
|
|
56
|
+
// in the close-result envelope. We now:
|
|
57
|
+
// - read the Story snapshot first to detect an "already done" state
|
|
58
|
+
// (label `agent::done` AND issue state `closed`) and treat re-runs
|
|
59
|
+
// as a no-op record, satisfying the idempotency contract;
|
|
60
|
+
// - otherwise call `toDone` unconditionally — there is no other
|
|
61
|
+
// conditional skip in any normal exit path;
|
|
62
|
+
// - rethrow transport errors so the surrounding
|
|
63
|
+
// `runPhase('ticket-closure', ...)` logs the failure loudly via
|
|
64
|
+
// `[phase=ticket-closure] <message>` instead of letting the close
|
|
65
|
+
// report success on a half-failed transition.
|
|
66
|
+
log('TICKETS', `Transitioning Story #${storyId} to agent::done...`);
|
|
67
|
+
let storySnapshot = null;
|
|
68
|
+
try {
|
|
69
|
+
storySnapshot = await provider.getTicket(storyId);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
logger?.warn?.(
|
|
72
|
+
`[phase=tickets] Story #${storyId} snapshot read failed (continuing with transition): ${err?.message ?? err}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
const alreadyDone =
|
|
76
|
+
storySnapshot &&
|
|
77
|
+
Array.isArray(storySnapshot.labels) &&
|
|
78
|
+
storySnapshot.labels.includes(STATE_LABELS.DONE) &&
|
|
79
|
+
storySnapshot.state === 'closed';
|
|
80
|
+
if (alreadyDone) {
|
|
81
|
+
log(
|
|
82
|
+
'TICKETS',
|
|
83
|
+
` #${storyId} already agent::done — no-op (idempotent re-run)`,
|
|
84
|
+
);
|
|
85
|
+
closedTickets.push(storyId);
|
|
86
|
+
} else {
|
|
87
|
+
await toDone(provider, [storyId]);
|
|
88
|
+
closedTickets.push(storyId);
|
|
89
|
+
log('TICKETS', ` #${storyId} → agent::done ✅`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
log('TICKETS', 'Running cascade completion...');
|
|
93
|
+
let cascadedTo = [];
|
|
94
|
+
let cascadeFailed = [];
|
|
95
|
+
try {
|
|
96
|
+
const cascade = (await cascadeCompletion(provider, storyId)) ?? {
|
|
97
|
+
cascadedTo: [],
|
|
98
|
+
failed: [],
|
|
99
|
+
};
|
|
100
|
+
cascadedTo = cascade.cascadedTo ?? [];
|
|
101
|
+
cascadeFailed = cascade.failed ?? [];
|
|
102
|
+
if (cascadedTo.length > 0) {
|
|
103
|
+
log(
|
|
104
|
+
'TICKETS',
|
|
105
|
+
` Cascaded to: ${cascadedTo.map((id) => `#${id}`).join(', ')}`,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
for (const { parentId, error } of cascadeFailed) {
|
|
109
|
+
logger.error(
|
|
110
|
+
` Cascade partial-failure on parent #${parentId}: ${error}`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
logger.error(` Cascade fully failed (non-fatal): ${err.message}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return { closedTickets, cascadedTo, cascadeFailed };
|
|
118
|
+
}
|