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,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dag.js — Phase 2 of the epic-plan-decompose pipeline (Story #2466).
|
|
3
|
+
*
|
|
4
|
+
* Owns the deterministic DAG helpers used by the reconciler pipeline:
|
|
5
|
+
* - `resolveDependencies(ticket, slugMap)`
|
|
6
|
+
* - `orderTicketsForCreation(validated)` (topological sort within each
|
|
7
|
+
* (parent_slug, type) group, concatenated in feature → story → task
|
|
8
|
+
* order so parents always exist before their children get created)
|
|
9
|
+
*
|
|
10
|
+
* Extracted verbatim from `epic-plan-decompose.js` so the named exports
|
|
11
|
+
* (`resolveDependencies`, `orderTicketsForCreation`) that the
|
|
12
|
+
* `tests/ticket-decomposer.test.js` suite imports keep their contract.
|
|
13
|
+
*
|
|
14
|
+
* @module lib/orchestration/epic-plan-decompose/phases/dag
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export function resolveDependencies(ticket, slugMap) {
|
|
18
|
+
const resolved = [];
|
|
19
|
+
for (const dep of ticket.depends_on || []) {
|
|
20
|
+
const depId = slugMap.get(dep);
|
|
21
|
+
if (depId === undefined) {
|
|
22
|
+
// Unreachable through normal flow: validateAndNormalizeTickets
|
|
23
|
+
// already rejects unknown slugs and the topological sort guarantees
|
|
24
|
+
// creation order. A throw here turns a future regression (e.g.
|
|
25
|
+
// someone bypassing the validator) into a loud failure instead of a
|
|
26
|
+
// silently-dropped DAG edge.
|
|
27
|
+
throw new Error(
|
|
28
|
+
`[Decomposer] ${ticket.type.toUpperCase()} "${ticket.title}" (${ticket.slug}) depends on unresolved slug "${dep}". This indicates a planner bug or out-of-order ticket creation.`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
resolved.push(depId);
|
|
32
|
+
}
|
|
33
|
+
return resolved;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function topoSortGroup(group) {
|
|
37
|
+
const slugToTicket = new Map(group.map((t) => [t.slug, t]));
|
|
38
|
+
const visited = new Set();
|
|
39
|
+
const sorted = [];
|
|
40
|
+
|
|
41
|
+
function visit(t) {
|
|
42
|
+
if (visited.has(t.slug)) return;
|
|
43
|
+
visited.add(t.slug);
|
|
44
|
+
for (const dep of t.depends_on ?? []) {
|
|
45
|
+
const depTicket = slugToTicket.get(dep);
|
|
46
|
+
if (depTicket) visit(depTicket);
|
|
47
|
+
}
|
|
48
|
+
sorted.push(t);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const t of group) visit(t);
|
|
52
|
+
return sorted;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Topologically sort tickets within each (parent_slug, type) group, then
|
|
57
|
+
* concatenate groups in typeOrder so parents are always created before
|
|
58
|
+
* children (Feature → Story → Task) and intra-group dep chains resolve
|
|
59
|
+
* before their dependents are created.
|
|
60
|
+
*/
|
|
61
|
+
export function orderTicketsForCreation(validated) {
|
|
62
|
+
const typeOrder = { feature: 0, story: 1, task: 2 };
|
|
63
|
+
const groups = new Map();
|
|
64
|
+
for (const t of validated) {
|
|
65
|
+
const parentKey = t.parent_slug ?? '__epic__';
|
|
66
|
+
const key = `${t.type}::${parentKey}`;
|
|
67
|
+
if (!groups.has(key)) groups.set(key, { type: t.type, items: [] });
|
|
68
|
+
groups.get(key).items.push(t);
|
|
69
|
+
}
|
|
70
|
+
const ordered = [...groups.values()].sort(
|
|
71
|
+
(a, b) => typeOrder[a.type] - typeOrder[b.type],
|
|
72
|
+
);
|
|
73
|
+
const result = [];
|
|
74
|
+
for (const group of ordered) {
|
|
75
|
+
for (const t of topoSortGroup(group.items)) result.push(t);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* diagnostics.js — partial-failure diagnostics for epic-plan-decompose
|
|
3
|
+
* (Story #2466).
|
|
4
|
+
*
|
|
5
|
+
* `reportPartialFailure({ epicId, provider, err })` is invoked from the
|
|
6
|
+
* CLI shell after `runDecomposePhase` throws — typically GitHub
|
|
7
|
+
* secondary-RL after dozens of issue creations. The function is
|
|
8
|
+
* intentionally defensive: never throws, never eclipses the original
|
|
9
|
+
* failure, and always emits the "to resume" hint as the final lines.
|
|
10
|
+
*
|
|
11
|
+
* @module lib/orchestration/epic-plan-decompose/phases/diagnostics
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { Logger } from '../../../Logger.js';
|
|
15
|
+
import { TYPE_LABELS } from '../../../label-constants.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Count open child tickets under the Epic without distinguishing by
|
|
19
|
+
* type. Under the 3-tier hierarchy (Epic → Feature → Story), child
|
|
20
|
+
* tickets are always Feature or Story.
|
|
21
|
+
*/
|
|
22
|
+
async function emitOpenChildrenDiagnostic(provider, epicId) {
|
|
23
|
+
if (typeof provider.getSubTickets !== 'function') return;
|
|
24
|
+
// Story #3455 — scope to the Epic's sub-issue graph instead of
|
|
25
|
+
// `getTickets`'s repo-wide `state=all` scan. The diagnostic explicitly
|
|
26
|
+
// counts `state !== 'closed'`, so the scoped fetch (which still surfaces
|
|
27
|
+
// closed children) yields the same open-child count without paging
|
|
28
|
+
// every issue in the repo.
|
|
29
|
+
const existing = await provider.getSubTickets(epicId);
|
|
30
|
+
const childTypes = [TYPE_LABELS.FEATURE, TYPE_LABELS.STORY];
|
|
31
|
+
const created = (existing || []).filter(
|
|
32
|
+
(t) =>
|
|
33
|
+
(t.labels || []).some((l) => childTypes.includes(l)) &&
|
|
34
|
+
t.state !== 'closed',
|
|
35
|
+
).length;
|
|
36
|
+
Logger.error(
|
|
37
|
+
`[epic-plan-decompose] Children currently open under Epic: ${created}`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function emitLifecycleLabelDiagnostic(provider, epicId) {
|
|
42
|
+
if (typeof provider.getEpic !== 'function') return;
|
|
43
|
+
const epic = await provider.getEpic(epicId);
|
|
44
|
+
const lifecycleLabel =
|
|
45
|
+
(epic?.labels || []).find((l) => l.startsWith('agent::')) ?? 'unknown';
|
|
46
|
+
Logger.error(
|
|
47
|
+
`[epic-plan-decompose] Epic #${epicId} current label: ${lifecycleLabel}`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Best-effort recovery diagnostics. Never throws.
|
|
53
|
+
*/
|
|
54
|
+
export async function reportPartialFailure({ epicId, provider, err }) {
|
|
55
|
+
Logger.error('');
|
|
56
|
+
Logger.error('[epic-plan-decompose] ❌ Decompose phase aborted.');
|
|
57
|
+
Logger.error(`[epic-plan-decompose] Reason: ${err?.message ?? err}`);
|
|
58
|
+
try {
|
|
59
|
+
await emitLifecycleLabelDiagnostic(provider, epicId);
|
|
60
|
+
await emitOpenChildrenDiagnostic(provider, epicId);
|
|
61
|
+
} catch (probeErr) {
|
|
62
|
+
Logger.error(
|
|
63
|
+
`[epic-plan-decompose] (diagnostics probe failed: ${probeErr.message})`,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
Logger.error('');
|
|
67
|
+
Logger.error('[epic-plan-decompose] To resume from the partial backlog:');
|
|
68
|
+
Logger.error(
|
|
69
|
+
`[epic-plan-decompose] node .agents/scripts/epic-plan-decompose.js --epic ${epicId} --tickets <tickets-file> --resume`,
|
|
70
|
+
);
|
|
71
|
+
Logger.error('');
|
|
72
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* persist-helpers.js — pure helpers split out of `persist.js` so the
|
|
3
|
+
* orchestrator stays under Story #2466's 200-LOC ceiling.
|
|
4
|
+
*
|
|
5
|
+
* Exports:
|
|
6
|
+
* - `assertDecomposeInputs(epic, epicId, tickets)` — entry guards.
|
|
7
|
+
* - `buildEpicSpecInput(epic, epicId)` — projection used by
|
|
8
|
+
* `renderSpec`; runs `ensurePlanningArtifacts` defensively so the
|
|
9
|
+
* spec body carries the `## Planning Artifacts` section the
|
|
10
|
+
* cascade-close path depends on.
|
|
11
|
+
* - `validateTickets(tickets, config)` — runs the cross-link / freshness
|
|
12
|
+
* normaliser and the task-body validator in one pass.
|
|
13
|
+
* - `seedPlanState(provider, epicId, epic)` — initialise + flip the
|
|
14
|
+
* `epic-plan-state` checkpoint to the decomposing phase.
|
|
15
|
+
* - `recordCheckpoint(provider, epicId, tickets)` — write the final
|
|
16
|
+
* `decompose.completedAt` + `ticketCount` checkpoint after apply.
|
|
17
|
+
* - `logCleanupSummary(cleanup, epicId, ticketCount)` — terminal log.
|
|
18
|
+
*
|
|
19
|
+
* @module lib/orchestration/epic-plan-decompose/phases/persist-helpers
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { gitSpawn } from '../../../git-utils.js';
|
|
23
|
+
import { Logger } from '../../../Logger.js';
|
|
24
|
+
import { TYPE_LABELS } from '../../../label-constants.js';
|
|
25
|
+
import {
|
|
26
|
+
initialize as initializePlanState,
|
|
27
|
+
read as readPlanState,
|
|
28
|
+
write as writePlanState,
|
|
29
|
+
} from '../../epic-plan-state-store.js';
|
|
30
|
+
import { validateTaskBodies } from '../../task-body-validator.js';
|
|
31
|
+
import { validateAndNormalizeTickets } from '../../ticket-validator.js';
|
|
32
|
+
import {
|
|
33
|
+
ensurePlanningArtifacts,
|
|
34
|
+
resolveConflictPolicy,
|
|
35
|
+
} from './planning-artifacts.js';
|
|
36
|
+
|
|
37
|
+
export function assertDecomposeInputs(epic, epicId, tickets) {
|
|
38
|
+
if (!epic) {
|
|
39
|
+
throw new Error(`[epic-plan-decompose] Epic #${epicId} not found.`);
|
|
40
|
+
}
|
|
41
|
+
if (!epic.labels?.includes(TYPE_LABELS.EPIC)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`[epic-plan-decompose] Ticket #${epicId} is not a ${TYPE_LABELS.EPIC}.`,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (!epic.linkedIssues?.prd || !epic.linkedIssues?.techSpec) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`[epic-plan-decompose] Epic #${epicId} is missing a linked PRD or Tech Spec. Run /epic-plan-spec first.`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (!Array.isArray(tickets)) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`[epic-plan-decompose] tickets must be an array (got ${typeof tickets}).`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function buildEpicSpecInput(epic, epicId) {
|
|
59
|
+
const epicBody = ensurePlanningArtifacts(epic.body ?? '', epic.linkedIssues);
|
|
60
|
+
const epicSpecInput = { id: epicId, title: epic.title };
|
|
61
|
+
if (epicBody.length > 0) epicSpecInput.body = epicBody;
|
|
62
|
+
return epicSpecInput;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Default fan-out counter — counts distinct files at `baseBranchRef` that
|
|
67
|
+
* reference the basename (without extension) of the deleted path. Uses
|
|
68
|
+
* `git grep -l` for a streaming-friendly probe; an empty grep returns
|
|
69
|
+
* exit code 1 which we map to a count of 0.
|
|
70
|
+
*
|
|
71
|
+
* Story #2962. Injected via opts in tests; this default runs in production.
|
|
72
|
+
*/
|
|
73
|
+
export function makeDefaultFanOutCounter({ baseBranchRef, cwd }) {
|
|
74
|
+
return ({ path }) => {
|
|
75
|
+
const lastSlash = path.lastIndexOf('/');
|
|
76
|
+
const base = lastSlash === -1 ? path : path.slice(lastSlash + 1);
|
|
77
|
+
const dotIdx = base.lastIndexOf('.');
|
|
78
|
+
const stem = dotIdx > 0 ? base.slice(0, dotIdx) : base;
|
|
79
|
+
if (stem.length < 3) return 0;
|
|
80
|
+
const result = gitSpawn(
|
|
81
|
+
cwd ?? process.cwd(),
|
|
82
|
+
'grep',
|
|
83
|
+
'-l',
|
|
84
|
+
'--fixed-strings',
|
|
85
|
+
stem,
|
|
86
|
+
baseBranchRef,
|
|
87
|
+
);
|
|
88
|
+
if (result.status !== 0) return 0;
|
|
89
|
+
const lines = result.stdout.split('\n').filter((l) => l.trim().length > 0);
|
|
90
|
+
// Exclude the deleted file itself from the call-site count.
|
|
91
|
+
return lines.filter((l) => !l.endsWith(`:${path}`)).length;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function validateTickets(tickets, config, opts = {}) {
|
|
96
|
+
const baseBranchRef = config?.baseBranch ?? 'main';
|
|
97
|
+
const conflictPolicy = resolveConflictPolicy(config);
|
|
98
|
+
if (typeof opts.fanOutCounter === 'function') {
|
|
99
|
+
conflictPolicy.fanOutCounter = opts.fanOutCounter;
|
|
100
|
+
} else if (!conflictPolicy.fanOutCounter) {
|
|
101
|
+
conflictPolicy.fanOutCounter = makeDefaultFanOutCounter({
|
|
102
|
+
baseBranchRef,
|
|
103
|
+
cwd: opts.cwd,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const validated = validateAndNormalizeTickets(tickets, {
|
|
107
|
+
baseBranchRef,
|
|
108
|
+
conflictPolicy,
|
|
109
|
+
});
|
|
110
|
+
validateTaskBodies(validated);
|
|
111
|
+
return validated;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function seedPlanState(provider, epicId, epic) {
|
|
115
|
+
await initializePlanState({
|
|
116
|
+
provider,
|
|
117
|
+
epicId,
|
|
118
|
+
seed: {
|
|
119
|
+
spec: {
|
|
120
|
+
prdId: epic.linkedIssues.prd,
|
|
121
|
+
techSpecId: epic.linkedIssues.techSpec,
|
|
122
|
+
completedAt: null,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function recordCheckpoint(provider, epicId, tickets) {
|
|
129
|
+
const currentState =
|
|
130
|
+
(await readPlanState({ provider, epicId })) ??
|
|
131
|
+
(await initializePlanState({ provider, epicId }));
|
|
132
|
+
return writePlanState({
|
|
133
|
+
provider,
|
|
134
|
+
epicId,
|
|
135
|
+
state: {
|
|
136
|
+
...currentState,
|
|
137
|
+
decompose: {
|
|
138
|
+
...currentState.decompose,
|
|
139
|
+
ticketCount: tickets.length,
|
|
140
|
+
completedAt: new Date().toISOString(),
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function logCleanupSummary(cleanup, epicId, ticketCount) {
|
|
147
|
+
Logger.info(
|
|
148
|
+
`[epic-plan-decompose] ✅ Decompose phase complete for Epic #${epicId}. ${ticketCount} ticket(s) persisted via reconciler.`,
|
|
149
|
+
);
|
|
150
|
+
if (cleanup.deleted.length > 0) {
|
|
151
|
+
Logger.info(
|
|
152
|
+
`[epic-plan-decompose] 🧹 Cleaned up ${cleanup.deleted.length} temp file(s).`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* persist.js — Phase 5 of the epic-plan-decompose pipeline (Story #2466).
|
|
3
|
+
*
|
|
4
|
+
* Owns the reconciler-based persist flow:
|
|
5
|
+
* 1. validate + normalise the ticket array
|
|
6
|
+
* 2. render the structural spec
|
|
7
|
+
* 3. write the YAML spec under `.agents/epics/<epicId>.yaml`
|
|
8
|
+
* 4. spawn `epic-reconcile.js --apply --yes`
|
|
9
|
+
* 5. run the sub-issue link safety net
|
|
10
|
+
* 6. update the `epic-plan-state` checkpoint
|
|
11
|
+
* 7. flip the Epic to `agent::ready`
|
|
12
|
+
* 8. clean up phase temp files
|
|
13
|
+
*
|
|
14
|
+
* Pure helpers (input guards, spec input projection, validation, state
|
|
15
|
+
* seed/checkpoint, cleanup logging) live in the sibling
|
|
16
|
+
* `persist-helpers.js` module so this orchestrator stays under Story
|
|
17
|
+
* #2466's 200-LOC ceiling.
|
|
18
|
+
*
|
|
19
|
+
* @module lib/orchestration/epic-plan-decompose/phases/persist
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { spawnSync as defaultSpawnSync } from 'node:child_process';
|
|
23
|
+
|
|
24
|
+
import { runPlanHealthcheck as defaultRunPlanHealthcheck } from '../../../../epic-plan-healthcheck.js';
|
|
25
|
+
import { getLimits, PROJECT_ROOT } from '../../../config-resolver.js';
|
|
26
|
+
import { Logger } from '../../../Logger.js';
|
|
27
|
+
import {
|
|
28
|
+
AGENT_LABELS,
|
|
29
|
+
PLANNING_HEALTHCHECK_WAIVED,
|
|
30
|
+
} from '../../../label-constants.js';
|
|
31
|
+
import { cleanupPhaseTempFiles } from '../../../plan-phase-cleanup.js';
|
|
32
|
+
import { writeSpec } from '../../../spec/index.js';
|
|
33
|
+
import {
|
|
34
|
+
assertNoOpenPlanChildren,
|
|
35
|
+
releaseEpicPlanLease,
|
|
36
|
+
} from '../../epic-plan-lease-guard.js';
|
|
37
|
+
import { renderSpec } from '../../spec-renderer.js';
|
|
38
|
+
import { renderHardConflictError } from '../../ticket-validator-conflicts.js';
|
|
39
|
+
import {
|
|
40
|
+
reconcileSubIssueLinks,
|
|
41
|
+
setEpicLabel,
|
|
42
|
+
warnTicketCapNearLimit,
|
|
43
|
+
} from './creation.js';
|
|
44
|
+
import {
|
|
45
|
+
assertDecomposeInputs,
|
|
46
|
+
buildEpicSpecInput,
|
|
47
|
+
logCleanupSummary,
|
|
48
|
+
recordCheckpoint,
|
|
49
|
+
seedPlanState,
|
|
50
|
+
validateTickets,
|
|
51
|
+
} from './persist-helpers.js';
|
|
52
|
+
import { RECONCILE_CLI, spawnReconcilerApply } from './reconcile-spawn.js';
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Execute the decompose phase end to end. See module-doc for the 8-step
|
|
56
|
+
* flow.
|
|
57
|
+
*
|
|
58
|
+
* @param {number} epicId
|
|
59
|
+
* @param {import('../../../ITicketingProvider.js').ITicketingProvider} provider
|
|
60
|
+
* @param {{ tickets: Array<object> }} payload
|
|
61
|
+
* @param {object} config
|
|
62
|
+
* @param {{ force?: boolean, resume?: boolean, allowOverBudget?: boolean, allowLargeFanOut?: boolean, fanOutCounter?: (arg: { path: string }) => number, spawnSync?: typeof defaultSpawnSync, reconcileCli?: string, writeSpecFn?: typeof writeSpec, renderSpecFn?: typeof renderSpec, cwd?: string, runHealthcheckFn?: typeof defaultRunPlanHealthcheck, skipHealthcheck?: boolean }} [opts]
|
|
63
|
+
*/
|
|
64
|
+
export async function runDecomposePhase(
|
|
65
|
+
epicId,
|
|
66
|
+
provider,
|
|
67
|
+
{ tickets },
|
|
68
|
+
config = {},
|
|
69
|
+
{
|
|
70
|
+
force = false,
|
|
71
|
+
resume = false,
|
|
72
|
+
allowOverBudget = false,
|
|
73
|
+
allowLargeFanOut = false,
|
|
74
|
+
fanOutCounter = undefined,
|
|
75
|
+
spawnSync = defaultSpawnSync,
|
|
76
|
+
reconcileCli = RECONCILE_CLI,
|
|
77
|
+
writeSpecFn = writeSpec,
|
|
78
|
+
renderSpecFn = renderSpec,
|
|
79
|
+
cwd = PROJECT_ROOT,
|
|
80
|
+
runHealthcheckFn = defaultRunPlanHealthcheck,
|
|
81
|
+
skipHealthcheck = false,
|
|
82
|
+
} = {},
|
|
83
|
+
) {
|
|
84
|
+
if (force && resume) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
'[epic-plan-decompose] --force and --resume are mutually exclusive.',
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const epic = await provider.getEpic(epicId);
|
|
90
|
+
assertDecomposeInputs(epic, epicId, tickets);
|
|
91
|
+
const maxTickets = getLimits(config).maxTickets;
|
|
92
|
+
// Story #2798 — `maxTickets` is a reviewability budget. Over-budget
|
|
93
|
+
// persistence requires an explicit `--allow-over-budget` override so
|
|
94
|
+
// an accidental over-budget plan does not silently land.
|
|
95
|
+
if (tickets.length > maxTickets && !allowOverBudget) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`[epic-plan-decompose] Tickets (${tickets.length}) exceed the reviewability budget (${maxTickets}). ` +
|
|
98
|
+
`Re-scope the Epic into a smaller plan, or rerun with --allow-over-budget after confirming the over-budget rationale on the Epic.`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
warnTicketCapNearLimit(tickets, maxTickets);
|
|
102
|
+
if (tickets.length > maxTickets && allowOverBudget) {
|
|
103
|
+
Logger.warn(
|
|
104
|
+
`[epic-plan-decompose] Persisting an over-budget decomposition: ${tickets.length} tickets vs. budget ${maxTickets} (operator override --allow-over-budget).`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
// Story #2962 — run cross-validation BEFORE the plan-state mutation so
|
|
108
|
+
// the fan-out gate (and any future hard gate) can refuse persist
|
|
109
|
+
// without leaving a half-initialised epic-plan-state behind.
|
|
110
|
+
Logger.info(
|
|
111
|
+
`[epic-plan-decompose] Running cross-validation on ${tickets.length} tickets...`,
|
|
112
|
+
);
|
|
113
|
+
const validated = validateTickets(tickets, config, { fanOutCounter, cwd });
|
|
114
|
+
|
|
115
|
+
// Refuse to persist when any Task declares a deletion whose call-site
|
|
116
|
+
// fan-out exceeds the configured threshold, unless the operator has
|
|
117
|
+
// passed `--allow-large-fan-out`. The planner cannot reduce call sites
|
|
118
|
+
// by re-prompting, so this gate sits at persist time (like
|
|
119
|
+
// `--allow-over-budget`) rather than in the auto-redrive loop.
|
|
120
|
+
enforceFanOutGate(validated.findings, allowLargeFanOut);
|
|
121
|
+
|
|
122
|
+
// Story #3957 — surface soft cross-Story conflict findings on the
|
|
123
|
+
// validator's warning channel. `failOnSharedEditors` defaults to `false`,
|
|
124
|
+
// so a real shared-editor / implicit-dep hazard lands as `'soft'` and would
|
|
125
|
+
// otherwise be invisible during the Phase-8 operator review. Logging each
|
|
126
|
+
// soft finding here puts it in the same decompose output the operator reads
|
|
127
|
+
// before approving the plan.
|
|
128
|
+
surfaceSoftConflictFindings(validated.findings);
|
|
129
|
+
|
|
130
|
+
// Workflow-guards (Story #3481): refuse to persist when the Epic already has
|
|
131
|
+
// open Feature/Story children unless this is a deliberate re-decompose
|
|
132
|
+
// (`--force` closes + recreates the tree; `--resume` continues a partial
|
|
133
|
+
// persist). Sits immediately before the first plan-state mutation so a
|
|
134
|
+
// refusal never leaves a half-initialised epic-plan-state behind.
|
|
135
|
+
await assertNoOpenPlanChildren({
|
|
136
|
+
provider,
|
|
137
|
+
epicId,
|
|
138
|
+
force: force || resume,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await seedPlanState(provider, epicId, epic);
|
|
142
|
+
|
|
143
|
+
Logger.info(
|
|
144
|
+
`[epic-plan-decompose] Rendering spec for Epic #${epicId} (${validated.length} tickets)...`,
|
|
145
|
+
);
|
|
146
|
+
const spec = renderSpecFn(validated, {
|
|
147
|
+
epic: buildEpicSpecInput(epic, epicId),
|
|
148
|
+
});
|
|
149
|
+
const specFilePath = writeSpecFn(epicId, spec, { epicsDir: undefined });
|
|
150
|
+
Logger.info(`[epic-plan-decompose] Wrote spec → ${specFilePath}`);
|
|
151
|
+
|
|
152
|
+
Logger.info(
|
|
153
|
+
`[epic-plan-decompose] Spawning epic-reconcile.js --apply --yes for Epic #${epicId}...`,
|
|
154
|
+
);
|
|
155
|
+
// Story #3905 — a `--force` re-plan with a changed ticket set produces
|
|
156
|
+
// a plan carrying close ops for the dropped slugs. `epic-reconcile.js`
|
|
157
|
+
// hard-exits 2 on close ops unless `--explicit-delete` is passed, so a
|
|
158
|
+
// force re-decompose must thread the flag through or it fails *after*
|
|
159
|
+
// the spec was already overwritten and plan-state flipped.
|
|
160
|
+
const reconcile = spawnReconcilerApply({
|
|
161
|
+
spawnSync,
|
|
162
|
+
reconcileCli,
|
|
163
|
+
epicId,
|
|
164
|
+
cwd,
|
|
165
|
+
explicitDelete: force,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Sub-issue link safety net — Story #2063. The reconciler's apply path
|
|
169
|
+
// opportunistically calls `addSubIssue` and swallows transient failures;
|
|
170
|
+
// re-establish missing native links before flipping the Epic to ready.
|
|
171
|
+
await reconcileSubIssueLinks(epicId, provider);
|
|
172
|
+
|
|
173
|
+
const checkpoint = await recordCheckpoint(provider, epicId, tickets);
|
|
174
|
+
|
|
175
|
+
// Story #2921 (Epic #2880 F7) — `agent::ready` handoff gate. The
|
|
176
|
+
// post-plan readiness healthcheck (`epic-plan-healthcheck.js`) is now
|
|
177
|
+
// blocking: a failing healthcheck refuses the `agent::ready` flip
|
|
178
|
+
// unless the operator has applied the `planning::healthcheck-waived`
|
|
179
|
+
// label. See `.agents/docs/SDLC.md` § "`agent::ready` exit conditions" for
|
|
180
|
+
// the full contract. Tests inject `skipHealthcheck: true` to bypass
|
|
181
|
+
// the network-bound check; production callers must not set this.
|
|
182
|
+
const healthcheck = skipHealthcheck
|
|
183
|
+
? { ok: true, skipped: true }
|
|
184
|
+
: await runHealthcheckGate({
|
|
185
|
+
epicId,
|
|
186
|
+
epic,
|
|
187
|
+
runHealthcheckFn,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
Logger.info(
|
|
191
|
+
`[epic-plan-decompose] Flipping Epic #${epicId} to ${AGENT_LABELS.READY}...`,
|
|
192
|
+
);
|
|
193
|
+
await setEpicLabel(provider, epicId, AGENT_LABELS.READY);
|
|
194
|
+
|
|
195
|
+
const cleanup = await cleanupPhaseTempFiles({ phase: 'decompose', epicId });
|
|
196
|
+
logCleanupSummary(cleanup, epicId, tickets.length);
|
|
197
|
+
|
|
198
|
+
// Workflow-guards (Story #3481): release the Epic-lease now that Phase 8 has
|
|
199
|
+
// persisted the plan. Best-effort — a release failure never fails decompose.
|
|
200
|
+
await releaseEpicPlanLease({ provider, epicId, config });
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
epicId,
|
|
204
|
+
ticketCount: tickets.length,
|
|
205
|
+
checkpoint,
|
|
206
|
+
cleanup,
|
|
207
|
+
reconcile,
|
|
208
|
+
specPath: specFilePath,
|
|
209
|
+
healthcheck,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Run the post-plan readiness healthcheck and enforce the
|
|
215
|
+
* `agent::ready` handoff gate. Returns the healthcheck result on
|
|
216
|
+
* success (either `ok: true` or `ok: false` with the waiver label
|
|
217
|
+
* applied). Throws when the healthcheck failed and the operator has
|
|
218
|
+
* not applied `planning::healthcheck-waived` to the Epic.
|
|
219
|
+
*
|
|
220
|
+
* Extracted from `runDecomposePhase` so the gate is a single named
|
|
221
|
+
* code path the contract tests can target.
|
|
222
|
+
*
|
|
223
|
+
* @param {object} args
|
|
224
|
+
* @param {number} args.epicId
|
|
225
|
+
* @param {{ labels?: string[] }} args.epic
|
|
226
|
+
* @param {typeof defaultRunPlanHealthcheck} args.runHealthcheckFn
|
|
227
|
+
* @returns {Promise<{ ok: boolean, waived?: boolean, reason?: string|null }>}
|
|
228
|
+
*/
|
|
229
|
+
function enforceFanOutGate(findings, allowLargeFanOut) {
|
|
230
|
+
const fanOut = (findings ?? []).filter((f) => f.kind === 'fan-out-warning');
|
|
231
|
+
if (fanOut.length === 0) return;
|
|
232
|
+
if (allowLargeFanOut) {
|
|
233
|
+
for (const f of fanOut) {
|
|
234
|
+
Logger.warn(
|
|
235
|
+
`[epic-plan-decompose] Persisting a large-fan-out deletion: ` +
|
|
236
|
+
`Task "${f.taskSlug}" deletes "${f.path}" with ${f.callSiteCount} ` +
|
|
237
|
+
`call site(s) (threshold ${f.threshold}). Operator override --allow-large-fan-out.`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const lines = fanOut
|
|
243
|
+
.map(
|
|
244
|
+
(f) =>
|
|
245
|
+
` - Task "${f.taskSlug}" (Story "${f.storySlug}") deletes "${f.path}" — ${f.callSiteCount} call site(s) (threshold ${f.threshold})`,
|
|
246
|
+
)
|
|
247
|
+
.join('\n');
|
|
248
|
+
throw new Error(
|
|
249
|
+
`[epic-plan-decompose] ${fanOut.length} Task(s) declare large-fan-out deletions:\n${lines}\n\n` +
|
|
250
|
+
`Split each deletion into a subsystem-by-subsystem migration across multiple Stories, ` +
|
|
251
|
+
`or rerun --allow-large-fan-out after confirming the deletion is intentional.`,
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Story #3957 — log every `'soft'` cross-Story conflict finding on the
|
|
257
|
+
* validator's warning channel so it is visible during the Phase-8 operator
|
|
258
|
+
* review even when its policy flag (e.g. `failOnSharedEditors`) is `false`
|
|
259
|
+
* and the finding never reaches the AC-visible `errors[]` path.
|
|
260
|
+
*
|
|
261
|
+
* `fan-out-warning` findings are excluded: `enforceFanOutGate` already emits
|
|
262
|
+
* a dedicated warn/throw line for those, and double-logging would be noise.
|
|
263
|
+
* Hard findings are excluded too — they are already rendered into `errors[]`
|
|
264
|
+
* and block the decompose, so they need no advisory echo here.
|
|
265
|
+
*
|
|
266
|
+
* Each line reuses `renderHardConflictError` for the message body (the
|
|
267
|
+
* remediation hint is identical regardless of severity) under a `soft
|
|
268
|
+
* conflict:` prefix so the operator can tell advisory findings apart from
|
|
269
|
+
* blocking ones.
|
|
270
|
+
*
|
|
271
|
+
* @param {object[]} findings
|
|
272
|
+
*/
|
|
273
|
+
function surfaceSoftConflictFindings(findings) {
|
|
274
|
+
const soft = (findings ?? []).filter(
|
|
275
|
+
(f) => f?.severity === 'soft' && f?.kind !== 'fan-out-warning',
|
|
276
|
+
);
|
|
277
|
+
if (soft.length === 0) return;
|
|
278
|
+
Logger.warn(
|
|
279
|
+
`[epic-plan-decompose] ${soft.length} soft cross-Story conflict finding(s) — review before approving the plan:`,
|
|
280
|
+
);
|
|
281
|
+
for (const finding of soft) {
|
|
282
|
+
Logger.warn(
|
|
283
|
+
`[epic-plan-decompose] soft conflict: ${renderHardConflictError(finding)}`,
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async function runHealthcheckGate({ epicId, epic, runHealthcheckFn }) {
|
|
289
|
+
Logger.info(
|
|
290
|
+
`[epic-plan-decompose] Running post-plan readiness healthcheck for Epic #${epicId}...`,
|
|
291
|
+
);
|
|
292
|
+
let result;
|
|
293
|
+
try {
|
|
294
|
+
result = await runHealthcheckFn({ epicId });
|
|
295
|
+
} catch (err) {
|
|
296
|
+
// A throwing healthcheck is itself a failure — surface it as the
|
|
297
|
+
// gate reason rather than letting the throw propagate raw, so the
|
|
298
|
+
// operator sees a uniform "handoff refused" diagnostic.
|
|
299
|
+
result = { ok: false, reason: `healthcheck threw: ${err.message}` };
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (result?.ok) {
|
|
303
|
+
return { ok: true };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const labels = Array.isArray(epic?.labels) ? epic.labels : [];
|
|
307
|
+
const waived = labels.includes(PLANNING_HEALTHCHECK_WAIVED);
|
|
308
|
+
if (waived) {
|
|
309
|
+
Logger.warn(
|
|
310
|
+
`[epic-plan-decompose] Healthcheck failed for Epic #${epicId} but '${PLANNING_HEALTHCHECK_WAIVED}' is applied — proceeding with agent::ready handoff. Reason: ${result?.reason ?? '(no reason reported)'}`,
|
|
311
|
+
);
|
|
312
|
+
return { ok: false, waived: true, reason: result?.reason ?? null };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
throw new Error(
|
|
316
|
+
`[epic-plan-decompose] Refusing agent::ready handoff for Epic #${epicId}: ` +
|
|
317
|
+
`post-plan healthcheck failed (${result?.reason ?? '(no reason reported)'}). ` +
|
|
318
|
+
`Resolve the failing check(s), or apply the '${PLANNING_HEALTHCHECK_WAIVED}' ` +
|
|
319
|
+
`label to the Epic to override and rerun the persist phase.`,
|
|
320
|
+
);
|
|
321
|
+
}
|