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,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* epic-deliver-lease-guard.js — preflight guards for `/epic-deliver`
|
|
3
|
+
* (Story #3482, Epic #3457).
|
|
4
|
+
*
|
|
5
|
+
* `/epic-deliver`'s prepare phase used to checkout `epic/<id>` over whatever
|
|
6
|
+
* the operator had checked out, yanking HEAD and resetting baselines under a
|
|
7
|
+
* live working session (the documented "epic-deliver shares the main checkout"
|
|
8
|
+
* footgun). This module supplies the two preflight guards the Tech Spec
|
|
9
|
+
* (#3476) wires into `epic-deliver-prepare.js` *before* any mutating git work:
|
|
10
|
+
*
|
|
11
|
+
* 1. **Epic-lease preflight.** Acquire the assignee-as-lease on the Epic
|
|
12
|
+
* ticket via `ticket-lease.acquireLease`. On a live foreign claim the
|
|
13
|
+
* guard **fails closed** — it throws a clear, operator-facing error that
|
|
14
|
+
* names the current owner (the `critical-workflow` risk axis demands
|
|
15
|
+
* refuse-and-exit, never warn-and-continue). `--steal` is the only
|
|
16
|
+
* override.
|
|
17
|
+
* 2. **Checkout-safety preflight.** Refuse to start when the working tree is
|
|
18
|
+
* dirty or HEAD is on a branch other than the expected one, instead of
|
|
19
|
+
* checking `epic/<id>` out over the operator's work.
|
|
20
|
+
*
|
|
21
|
+
* Both guards are pure over injected seams (a `git` shim with
|
|
22
|
+
* `statusPorcelain` / `currentBranch`, and the lease provider) so the unit
|
|
23
|
+
* suite exercises them without standing up a real repo or hitting GitHub.
|
|
24
|
+
* Liveness is threaded in via `heartbeatAt` exactly as `ticket-lease.js`
|
|
25
|
+
* documents — this module does not read the lifecycle ledger itself.
|
|
26
|
+
*
|
|
27
|
+
* Per `.agents/rules/orchestration-error-handling.md`, the composed guard
|
|
28
|
+
* surfaces unrecoverable failures with `throw new Error(...)` (mapped to
|
|
29
|
+
* `process.exit(1)` by the `runAsCli` boundary), never `Logger.fatal`.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { acquireLease, normalizeOperatorHandle } from './ticket-lease.js';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the acquiring operator's identity. Precedence (Tech Spec #3476):
|
|
36
|
+
* 1. An explicit `--as <handle>` flag.
|
|
37
|
+
* 2. `github.operatorHandle` in `.agentrc.json`.
|
|
38
|
+
* 3. The local `git config user.email`.
|
|
39
|
+
*
|
|
40
|
+
* The `@`-prefix some operators carry on `operatorHandle` is stripped so the
|
|
41
|
+
* value matches the bare login written to a ticket's `assignees`.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} args
|
|
44
|
+
* @param {string} [args.asFlag] Explicit `--as` value.
|
|
45
|
+
* @param {object} [args.config] Resolved config (reads github.operatorHandle).
|
|
46
|
+
* @param {string} [args.gitUserEmail] Fallback `git config user.email`.
|
|
47
|
+
* @returns {string|null} The resolved operator handle, or null when none could
|
|
48
|
+
* be determined.
|
|
49
|
+
*/
|
|
50
|
+
export function resolveOperator({ asFlag, config, gitUserEmail } = {}) {
|
|
51
|
+
const candidates = [asFlag, config?.github?.operatorHandle, gitUserEmail];
|
|
52
|
+
for (const raw of candidates) {
|
|
53
|
+
const normalized = normalizeOperatorHandle(raw);
|
|
54
|
+
if (normalized !== null) return normalized;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Normalise the expected-branch argument into a non-empty list. `/epic-deliver`
|
|
61
|
+
* may legitimately start from either the Epic integration branch (`epic/<id>`,
|
|
62
|
+
* on a resume) or the project base branch (`main`, on a fresh run), so the
|
|
63
|
+
* guard accepts a set rather than a single name.
|
|
64
|
+
*
|
|
65
|
+
* @param {string|string[]} expectedBranch
|
|
66
|
+
* @returns {string[]}
|
|
67
|
+
*/
|
|
68
|
+
function normaliseExpectedBranches(expectedBranch) {
|
|
69
|
+
const list = (
|
|
70
|
+
Array.isArray(expectedBranch) ? expectedBranch : [expectedBranch]
|
|
71
|
+
).filter((b) => typeof b === 'string' && b.length > 0);
|
|
72
|
+
if (list.length === 0) {
|
|
73
|
+
throw new Error('checkCheckoutSafety: expectedBranch is required');
|
|
74
|
+
}
|
|
75
|
+
return list;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Pure checkout-safety classifier. The working tree must be clean and HEAD
|
|
80
|
+
* must sit on one of `expectedBranch` before prepare moves anything.
|
|
81
|
+
*
|
|
82
|
+
* @param {object} args
|
|
83
|
+
* @param {object} args.git Injected git shim.
|
|
84
|
+
* @param {() => { dirty: boolean, entries?: string }} args.git.statusPorcelain
|
|
85
|
+
* Returns whether the tree has uncommitted/untracked changes.
|
|
86
|
+
* @param {() => string|null} args.git.currentBranch Returns HEAD's branch (or
|
|
87
|
+
* null in detached-HEAD state).
|
|
88
|
+
* @param {string|string[]} args.expectedBranch The branch (or branches)
|
|
89
|
+
* prepare expects HEAD on (typically `epic/<id>` or the project base branch).
|
|
90
|
+
* @returns {{
|
|
91
|
+
* safe: boolean,
|
|
92
|
+
* reason: 'clean'|'dirty'|'wrong-branch'|'detached-head',
|
|
93
|
+
* currentBranch: string|null,
|
|
94
|
+
* expectedBranches: string[],
|
|
95
|
+
* dirtyEntries?: string,
|
|
96
|
+
* }}
|
|
97
|
+
*/
|
|
98
|
+
export function checkCheckoutSafety({ git, expectedBranch }) {
|
|
99
|
+
if (!git || typeof git.statusPorcelain !== 'function') {
|
|
100
|
+
throw new Error(
|
|
101
|
+
'checkCheckoutSafety: git shim with statusPorcelain/currentBranch is required',
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const expectedBranches = normaliseExpectedBranches(expectedBranch);
|
|
105
|
+
|
|
106
|
+
const status = git.statusPorcelain();
|
|
107
|
+
if (status?.dirty) {
|
|
108
|
+
return {
|
|
109
|
+
safe: false,
|
|
110
|
+
reason: 'dirty',
|
|
111
|
+
currentBranch: git.currentBranch(),
|
|
112
|
+
expectedBranches,
|
|
113
|
+
dirtyEntries: status.entries,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const branch = git.currentBranch();
|
|
118
|
+
if (branch === null || branch === undefined || branch === '') {
|
|
119
|
+
return {
|
|
120
|
+
safe: false,
|
|
121
|
+
reason: 'detached-head',
|
|
122
|
+
currentBranch: null,
|
|
123
|
+
expectedBranches,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (!expectedBranches.includes(branch)) {
|
|
127
|
+
return {
|
|
128
|
+
safe: false,
|
|
129
|
+
reason: 'wrong-branch',
|
|
130
|
+
currentBranch: branch,
|
|
131
|
+
expectedBranches,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
safe: true,
|
|
136
|
+
reason: 'clean',
|
|
137
|
+
currentBranch: branch,
|
|
138
|
+
expectedBranches,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Render the operator-facing message for a failed checkout-safety guard.
|
|
144
|
+
*
|
|
145
|
+
* @param {ReturnType<typeof checkCheckoutSafety>} result
|
|
146
|
+
* @returns {string}
|
|
147
|
+
*/
|
|
148
|
+
export function renderCheckoutRefusal(result) {
|
|
149
|
+
const expected = result.expectedBranches.map((b) => `'${b}'`).join(' or ');
|
|
150
|
+
if (result.reason === 'dirty') {
|
|
151
|
+
return (
|
|
152
|
+
`[epic-deliver] Refusing to start: the working tree is dirty. ` +
|
|
153
|
+
`/epic-deliver will not check out ${expected} over uncommitted ` +
|
|
154
|
+
`or untracked changes — commit, stash, or clean them, then re-run.\n` +
|
|
155
|
+
`--- dirty entries ---\n${result.dirtyEntries ?? '(unavailable)'}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (result.reason === 'detached-head') {
|
|
159
|
+
return (
|
|
160
|
+
`[epic-deliver] Refusing to start: HEAD is detached. /epic-deliver ` +
|
|
161
|
+
`expects HEAD on ${expected}. Check one out before re-running.`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return (
|
|
165
|
+
`[epic-deliver] Refusing to start: HEAD is on '${result.currentBranch}', ` +
|
|
166
|
+
`not the expected ${expected}. /epic-deliver will not yank HEAD ` +
|
|
167
|
+
`away from your branch — switch to ${expected} yourself before re-running.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Render the operator-facing message for a refused (live foreign) lease.
|
|
173
|
+
*
|
|
174
|
+
* @param {{ owner: string|null }} lease
|
|
175
|
+
* @param {number} epicId
|
|
176
|
+
* @returns {string}
|
|
177
|
+
*/
|
|
178
|
+
export function renderLeaseRefusal(lease, epicId) {
|
|
179
|
+
return (
|
|
180
|
+
`[epic-deliver] Refusing to start: Epic #${epicId} is already claimed by ` +
|
|
181
|
+
`'${lease.owner}' with a live lease (recent heartbeat within the TTL). ` +
|
|
182
|
+
`Another /epic-deliver run is driving this Epic. Wait for it to finish, ` +
|
|
183
|
+
`or pass --steal to forcibly transfer the claim.`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Acquire the Epic lease for `operator`, failing closed on a live foreign
|
|
189
|
+
* claim. Returns the `acquireLease` result on success.
|
|
190
|
+
*
|
|
191
|
+
* @param {object} args
|
|
192
|
+
* @param {object} args.provider Ticketing provider.
|
|
193
|
+
* @param {number} args.epicId Epic ticket id.
|
|
194
|
+
* @param {string} args.operator Resolved operator handle.
|
|
195
|
+
* @param {number|null} [args.heartbeatAt] Current owner's last heartbeat (epoch ms).
|
|
196
|
+
* @param {boolean} [args.steal=false] Transfer a live foreign claim.
|
|
197
|
+
* @param {object} [args.config] Resolved config (TTL default).
|
|
198
|
+
* @param {number} [args.now] Injectable clock.
|
|
199
|
+
* @returns {Promise<{ acquired: boolean, owner: string, previousOwner: string|null, reason: string }>}
|
|
200
|
+
* @throws {Error} when the Epic carries a live foreign claim and `steal` is false.
|
|
201
|
+
*/
|
|
202
|
+
export async function acquireEpicLease({
|
|
203
|
+
provider,
|
|
204
|
+
epicId,
|
|
205
|
+
operator,
|
|
206
|
+
heartbeatAt = null,
|
|
207
|
+
steal = false,
|
|
208
|
+
config,
|
|
209
|
+
now,
|
|
210
|
+
}) {
|
|
211
|
+
const result = await acquireLease({
|
|
212
|
+
provider,
|
|
213
|
+
ticketId: epicId,
|
|
214
|
+
operator,
|
|
215
|
+
heartbeatAt,
|
|
216
|
+
steal,
|
|
217
|
+
config,
|
|
218
|
+
now,
|
|
219
|
+
});
|
|
220
|
+
if (!result.acquired) {
|
|
221
|
+
throw new Error(renderLeaseRefusal(result, epicId));
|
|
222
|
+
}
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Compose the two preflight guards in the order prepare needs them: the
|
|
228
|
+
* checkout-safety check first (cheap, local, no network), then the Epic-lease
|
|
229
|
+
* acquisition (a GitHub round-trip). Both fail closed by throwing.
|
|
230
|
+
*
|
|
231
|
+
* The checkout-safety guard runs first (cheap, local) and always executes. The
|
|
232
|
+
* Epic-lease step then **fails closed**: when `operator` cannot be resolved
|
|
233
|
+
* (null — `--as`, `github.operatorHandle`, and `git user.email` all empty, with
|
|
234
|
+
* the shipped `@[USERNAME]` placeholder normalised to null), this throws rather
|
|
235
|
+
* than running an ownerless, unguarded delivery. The lease is the cross-clone
|
|
236
|
+
* coordination layer; without an identity it cannot serialise concurrent runs,
|
|
237
|
+
* so silently skipping it would defeat the guard.
|
|
238
|
+
*
|
|
239
|
+
* @param {object} args
|
|
240
|
+
* @param {number} args.epicId
|
|
241
|
+
* @param {string|string[]} args.expectedBranch Branch(es) prepare expects HEAD on.
|
|
242
|
+
* @param {object} args.git Injected git shim (statusPorcelain/currentBranch).
|
|
243
|
+
* @param {object} args.provider Ticketing provider for the lease.
|
|
244
|
+
* @param {string|null} args.operator Resolved operator handle (null fails closed → throw).
|
|
245
|
+
* @param {number|null} [args.heartbeatAt] Current owner's last heartbeat (epoch ms).
|
|
246
|
+
* @param {boolean} [args.steal=false] Transfer a live foreign claim.
|
|
247
|
+
* @param {object} [args.config] Resolved config.
|
|
248
|
+
* @param {number} [args.now] Injectable clock.
|
|
249
|
+
* @param {object} [args.logger] Logger with info/warn.
|
|
250
|
+
* @returns {Promise<{
|
|
251
|
+
* checkout: ReturnType<typeof checkCheckoutSafety>,
|
|
252
|
+
* lease: { acquired: boolean, owner: string, reason: string },
|
|
253
|
+
* }>}
|
|
254
|
+
* @throws {Error} on a dirty/wrong-branch tree, an unresolvable operator
|
|
255
|
+
* identity, or a refused live foreign lease.
|
|
256
|
+
*/
|
|
257
|
+
export async function runPrepareGuards({
|
|
258
|
+
epicId,
|
|
259
|
+
expectedBranch,
|
|
260
|
+
git,
|
|
261
|
+
provider,
|
|
262
|
+
operator,
|
|
263
|
+
heartbeatAt = null,
|
|
264
|
+
steal = false,
|
|
265
|
+
config,
|
|
266
|
+
now,
|
|
267
|
+
logger,
|
|
268
|
+
}) {
|
|
269
|
+
const log = logger ?? { info: () => {}, warn: () => {} };
|
|
270
|
+
|
|
271
|
+
const checkout = checkCheckoutSafety({ git, expectedBranch });
|
|
272
|
+
if (!checkout.safe) {
|
|
273
|
+
throw new Error(renderCheckoutRefusal(checkout));
|
|
274
|
+
}
|
|
275
|
+
log.info?.(
|
|
276
|
+
`[epic-deliver] ✅ Checkout-safety guard passed (clean tree on '${checkout.currentBranch}').`,
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
if (!operator) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
'[epic-deliver] Refusing to start: no operator identity could be ' +
|
|
282
|
+
'resolved. --as, github.operatorHandle (unset or still the shipped ' +
|
|
283
|
+
'`@[USERNAME]` placeholder), and git user.email are all empty, so the ' +
|
|
284
|
+
'Epic-lease has no owner and concurrent /epic-deliver runs cannot be ' +
|
|
285
|
+
'serialised. Set your own handle in .agentrc.local.json (e.g. ' +
|
|
286
|
+
'{ "github": { "operatorHandle": "@your-login" } }), pass --as <handle>, ' +
|
|
287
|
+
'or configure git user.email, then re-run.',
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const lease = await acquireEpicLease({
|
|
292
|
+
provider,
|
|
293
|
+
epicId,
|
|
294
|
+
operator,
|
|
295
|
+
heartbeatAt,
|
|
296
|
+
steal,
|
|
297
|
+
config,
|
|
298
|
+
now,
|
|
299
|
+
});
|
|
300
|
+
if (lease.reason === 'stolen') {
|
|
301
|
+
log.warn?.(
|
|
302
|
+
`[epic-deliver] ⚠️ Stole the Epic #${epicId} lease from '${lease.previousOwner}' via --steal (live claim forcibly transferred).`,
|
|
303
|
+
);
|
|
304
|
+
} else {
|
|
305
|
+
log.info?.(
|
|
306
|
+
`[epic-deliver] ✅ Acquired Epic #${epicId} lease for '${operator}' (reason=${lease.reason}).`,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
return { checkout, lease };
|
|
310
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cli.js — Phase 6 (CLI entry orchestration) of the epic-plan-decompose
|
|
3
|
+
* pipeline (Story #2466).
|
|
4
|
+
*
|
|
5
|
+
* Owns CLI flag parsing, the `--emit-context` JSON envelope path, and
|
|
6
|
+
* the tickets-file load → `runDecomposePhase` persist path. The
|
|
7
|
+
* partial-failure diagnostics emitter lives in the sibling
|
|
8
|
+
* `diagnostics.js` module.
|
|
9
|
+
*
|
|
10
|
+
* @module lib/orchestration/epic-plan-decompose/phases/cli
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import { parseArgs } from 'node:util';
|
|
15
|
+
|
|
16
|
+
import { drainPendingCleanupAtBoot } from '../../../../epic-plan-spec.js';
|
|
17
|
+
import {
|
|
18
|
+
PROJECT_ROOT,
|
|
19
|
+
resolveConfig,
|
|
20
|
+
validateOrchestrationConfig,
|
|
21
|
+
} from '../../../config-resolver.js';
|
|
22
|
+
import {
|
|
23
|
+
Logger,
|
|
24
|
+
routeAllOutputToStderr,
|
|
25
|
+
STDERR_LOGGER,
|
|
26
|
+
} from '../../../Logger.js';
|
|
27
|
+
import { createProvider } from '../../../provider-factory.js';
|
|
28
|
+
import { buildDecompositionContext } from './context.js';
|
|
29
|
+
import { reportPartialFailure } from './diagnostics.js';
|
|
30
|
+
import { runDecomposePhase } from './persist.js';
|
|
31
|
+
|
|
32
|
+
const CLI_OPTIONS = {
|
|
33
|
+
epic: { type: 'string' },
|
|
34
|
+
tickets: { type: 'string' },
|
|
35
|
+
force: { type: 'boolean', default: false },
|
|
36
|
+
resume: { type: 'boolean', default: false },
|
|
37
|
+
'allow-over-budget': { type: 'boolean', default: false },
|
|
38
|
+
'allow-large-fan-out': { type: 'boolean', default: false },
|
|
39
|
+
'emit-context': { type: 'boolean', default: false },
|
|
40
|
+
pretty: { type: 'boolean', default: false },
|
|
41
|
+
'full-context': { type: 'boolean', default: false },
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const USAGE =
|
|
45
|
+
'Usage: epic-plan-decompose.js --epic <EpicId> (--emit-context [--pretty] [--full-context] | --tickets <file>) [--force | --resume] [--allow-over-budget] [--allow-large-fan-out]';
|
|
46
|
+
|
|
47
|
+
function parseEpicId(rawEpic) {
|
|
48
|
+
if (!rawEpic) throw new Error(USAGE);
|
|
49
|
+
const epicId = Number.parseInt(rawEpic, 10);
|
|
50
|
+
if (Number.isNaN(epicId)) {
|
|
51
|
+
throw new Error(`Invalid epic ID: "${rawEpic}" — must be a number.`);
|
|
52
|
+
}
|
|
53
|
+
return epicId;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function loadResolvedConfig() {
|
|
57
|
+
let config;
|
|
58
|
+
try {
|
|
59
|
+
config = resolveConfig();
|
|
60
|
+
// Epic #2880 / F14B: pass the canonical resolved config directly.
|
|
61
|
+
// The legacy `config.orchestration` pointer is gone; the validator
|
|
62
|
+
// reads `config.github` and `config.delivery.worktreeIsolation`.
|
|
63
|
+
validateOrchestrationConfig(config);
|
|
64
|
+
} catch (err) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Orchestration config schema validation failed:\n${err.message}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
return config;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function driveDrainPendingCleanup({ config, provider, emitContext }) {
|
|
73
|
+
try {
|
|
74
|
+
await drainPendingCleanupAtBoot({
|
|
75
|
+
repoRoot: PROJECT_ROOT,
|
|
76
|
+
// Epic #2880 / F14B: drainPendingCleanupAtBoot now reads opts.config
|
|
77
|
+
// (canonical) and resolves the worktree root from
|
|
78
|
+
// config.delivery.worktreeIsolation.root.
|
|
79
|
+
config,
|
|
80
|
+
provider,
|
|
81
|
+
logger: emitContext ? STDERR_LOGGER : undefined,
|
|
82
|
+
});
|
|
83
|
+
} catch (err) {
|
|
84
|
+
Logger.warn(`[epic-plan-decompose] worktree sweep skipped: ${err.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function runEmitContextPath({ epicId, provider, config, values }) {
|
|
89
|
+
const ctx = await buildDecompositionContext(epicId, provider, config, {
|
|
90
|
+
fullContext: values['full-context'],
|
|
91
|
+
});
|
|
92
|
+
// Surface the resolved budget on stderr so a misconfigured `.agentrc.json`
|
|
93
|
+
// (e.g. flat-key `maxTickets` instead of grouped `planning.maxTickets`) is
|
|
94
|
+
// visible to the operator. The decomposer prompt embeds the same value.
|
|
95
|
+
// Story #2798 — language changed from "prompt cap" to "reviewability
|
|
96
|
+
// budget" to match the new prompt/skill contract.
|
|
97
|
+
Logger.error(
|
|
98
|
+
`[epic-plan-decompose] Resolved planning.maxTickets = ${ctx.maxTickets} (reviewability budget).`,
|
|
99
|
+
);
|
|
100
|
+
const json = values.pretty
|
|
101
|
+
? JSON.stringify(ctx, null, 2)
|
|
102
|
+
: JSON.stringify(ctx);
|
|
103
|
+
process.stdout.write(`${json}\n`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function loadTicketsFile(ticketsPath) {
|
|
107
|
+
if (!ticketsPath) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
'Missing --tickets <file>. (Use --emit-context first to gather authoring context.)',
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
const raw = await readFile(ticketsPath, 'utf8');
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(raw);
|
|
115
|
+
} catch (err) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Failed to parse tickets file "${ticketsPath}" as JSON: ${err.message}`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function runPersistPath({ epicId, provider, config, values }) {
|
|
123
|
+
const tickets = await loadTicketsFile(values.tickets);
|
|
124
|
+
let result;
|
|
125
|
+
try {
|
|
126
|
+
result = await runDecomposePhase(epicId, provider, { tickets }, config, {
|
|
127
|
+
force: values.force,
|
|
128
|
+
resume: values.resume,
|
|
129
|
+
allowOverBudget: values['allow-over-budget'],
|
|
130
|
+
allowLargeFanOut: values['allow-large-fan-out'],
|
|
131
|
+
});
|
|
132
|
+
} catch (err) {
|
|
133
|
+
await reportPartialFailure({ epicId, provider, err });
|
|
134
|
+
throw err;
|
|
135
|
+
}
|
|
136
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* node:coverage ignore next */
|
|
140
|
+
export async function main() {
|
|
141
|
+
const { values } = parseArgs({ options: CLI_OPTIONS });
|
|
142
|
+
const epicId = parseEpicId(values.epic);
|
|
143
|
+
if (values.force && values.resume) {
|
|
144
|
+
throw new Error('--force and --resume are mutually exclusive.');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const config = loadResolvedConfig();
|
|
148
|
+
// Epic #2880 / F14B: createProvider takes the canonical resolved config
|
|
149
|
+
// (it reads config.github). The legacy config.orchestration pointer is
|
|
150
|
+
// gone; passing it yields undefined and crashes the provider factory's
|
|
151
|
+
// hard guard.
|
|
152
|
+
const provider = createProvider(config);
|
|
153
|
+
const emitContext = values['emit-context'];
|
|
154
|
+
|
|
155
|
+
// Story #2278 — in --emit-context mode stdout is reserved for the JSON
|
|
156
|
+
// envelope. Flip every Logger sink that could land on stdout to stderr
|
|
157
|
+
// before any orchestration code runs.
|
|
158
|
+
if (emitContext) routeAllOutputToStderr();
|
|
159
|
+
|
|
160
|
+
await driveDrainPendingCleanup({ config, provider, emitContext });
|
|
161
|
+
|
|
162
|
+
if (emitContext) {
|
|
163
|
+
await runEmitContextPath({ epicId, provider, config, values });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
await runPersistPath({ epicId, provider, config, values });
|
|
167
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* context.js — Phase 3 of the epic-plan-decompose pipeline (Story #2466).
|
|
3
|
+
*
|
|
4
|
+
* Builds the authoring context (PRD + Tech Spec bodies, heuristics, system
|
|
5
|
+
* prompt, ticket cap) the host LLM / `epic-plan-decompose-author` Skill
|
|
6
|
+
* consumes when producing the ticket JSON array.
|
|
7
|
+
*
|
|
8
|
+
* Extracted verbatim from `epic-plan-decompose.js`; both
|
|
9
|
+
* `buildDecomposerSystemPrompt` and `buildDecompositionContext` retain
|
|
10
|
+
* their public-export contract for the existing unit tests.
|
|
11
|
+
*
|
|
12
|
+
* @module lib/orchestration/epic-plan-decompose/phases/context
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
getLimits,
|
|
17
|
+
resolvePreflightCeilings,
|
|
18
|
+
} from '../../../config-resolver.js';
|
|
19
|
+
import { renderDecomposerSystemPrompt } from '../../../templates/decomposer-prompts.js';
|
|
20
|
+
import { read as readPlanState } from '../../epic-plan-state-store.js';
|
|
21
|
+
import { applyBudget } from '../../planning-context-budget.js';
|
|
22
|
+
|
|
23
|
+
export function buildDecomposerSystemPrompt(
|
|
24
|
+
heuristics = [],
|
|
25
|
+
{ maxTickets } = {},
|
|
26
|
+
) {
|
|
27
|
+
const base = renderDecomposerSystemPrompt({ maxTickets });
|
|
28
|
+
const heuristicsStr =
|
|
29
|
+
heuristics.length > 0
|
|
30
|
+
? `### RISK HEURISTICS (planning metadata if any apply):\n- ${heuristics.join('\n- ')}`
|
|
31
|
+
: '';
|
|
32
|
+
return `${base}${heuristicsStr ? `\n\n${heuristicsStr}` : ''}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveHeuristics(config) {
|
|
36
|
+
if (Array.isArray(config.planning?.riskHeuristics)) {
|
|
37
|
+
return config.planning.riskHeuristics;
|
|
38
|
+
}
|
|
39
|
+
return config.agentSettings?.planning?.riskHeuristics || [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function projectBudgetedEntry(item, ticket, mode) {
|
|
43
|
+
if (mode === 'full') return { id: ticket.id, body: ticket.body };
|
|
44
|
+
return { id: ticket.id, body: null, bodySummary: item };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Read the persisted planning decision for the Epic so the decomposition
|
|
49
|
+
* authoring step (Phase 8) can cite the same risk classification the
|
|
50
|
+
* gate routing used in Phase 7. The decision lives in the `epic-plan-state`
|
|
51
|
+
* structured comment written by `epic-plan-spec.js`.
|
|
52
|
+
*
|
|
53
|
+
* Returns `{ planningRisk: null, reviewRouting: null }` when the comment
|
|
54
|
+
* is missing (older plans planned before Story #2801 landed) or when the
|
|
55
|
+
* payload predates the fields. The null sentinels are part of the
|
|
56
|
+
* decomposition context contract — callers MUST be able to JSON.stringify
|
|
57
|
+
* the result without losing the keys.
|
|
58
|
+
*
|
|
59
|
+
* @param {import('../../../ITicketingProvider.js').ITicketingProvider} provider
|
|
60
|
+
* @param {number} epicId
|
|
61
|
+
* @returns {Promise<{ planningRisk: object | null, reviewRouting: object | null }>}
|
|
62
|
+
*/
|
|
63
|
+
async function readPlanningDecision(provider, epicId) {
|
|
64
|
+
let state = null;
|
|
65
|
+
try {
|
|
66
|
+
state = await readPlanState({ provider, epicId });
|
|
67
|
+
} catch (_err) {
|
|
68
|
+
// `read` already swallows JSON parse errors; a thrown error here
|
|
69
|
+
// means the provider couldn't fetch comments. Treat as null state —
|
|
70
|
+
// the decomposer can still author tickets without the risk envelope.
|
|
71
|
+
state = null;
|
|
72
|
+
}
|
|
73
|
+
if (!state || typeof state !== 'object') {
|
|
74
|
+
return { planningRisk: null, reviewRouting: null };
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
planningRisk: state.planningRisk ?? null,
|
|
78
|
+
reviewRouting: state.reviewRouting ?? null,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function fetchPlanningTickets(provider, epicId) {
|
|
83
|
+
const epic = await provider.getEpic(epicId);
|
|
84
|
+
if (!epic?.linkedIssues?.prd || !epic.linkedIssues.techSpec) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`[Decomposer] Epic #${epicId} is missing linked PRD or Tech Spec. Run the Epic Planner first.`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const [prd, techSpec] = await Promise.all([
|
|
90
|
+
provider.getTicket(epic.linkedIssues.prd),
|
|
91
|
+
provider.getTicket(epic.linkedIssues.techSpec),
|
|
92
|
+
]);
|
|
93
|
+
return { epic, prd, techSpec };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Build the authoring context the host LLM (or the
|
|
98
|
+
* `epic-plan-decompose-author` Skill) needs to produce the ticket JSON.
|
|
99
|
+
*
|
|
100
|
+
* PRD and Tech Spec bodies are bounded by the planning-context budget
|
|
101
|
+
* (Epic #817 Story 9). Pass `{ fullContext: true }` (CLI: `--full-context`)
|
|
102
|
+
* to restore the unbounded full bodies.
|
|
103
|
+
*/
|
|
104
|
+
export async function buildDecompositionContext(
|
|
105
|
+
epicId,
|
|
106
|
+
provider,
|
|
107
|
+
config = {},
|
|
108
|
+
opts = {},
|
|
109
|
+
) {
|
|
110
|
+
const { epic, prd, techSpec } = await fetchPlanningTickets(provider, epicId);
|
|
111
|
+
const { planningRisk, reviewRouting } = await readPlanningDecision(
|
|
112
|
+
provider,
|
|
113
|
+
epicId,
|
|
114
|
+
);
|
|
115
|
+
const heuristics = resolveHeuristics(config);
|
|
116
|
+
const limits = getLimits(config);
|
|
117
|
+
const maxTickets = limits.maxTickets;
|
|
118
|
+
const planningLimits = limits.planningContext;
|
|
119
|
+
const { fullContext = false } = opts;
|
|
120
|
+
const systemPrompt = buildDecomposerSystemPrompt(heuristics, { maxTickets });
|
|
121
|
+
|
|
122
|
+
const budgeted = applyBudget(
|
|
123
|
+
[
|
|
124
|
+
{ path: `prd-${prd.id}.md`, content: prd.body ?? '' },
|
|
125
|
+
{ path: `tech-spec-${techSpec.id}.md`, content: techSpec.body ?? '' },
|
|
126
|
+
],
|
|
127
|
+
planningLimits,
|
|
128
|
+
{ fullContext },
|
|
129
|
+
);
|
|
130
|
+
const [prdItem, techSpecItem] = budgeted.items;
|
|
131
|
+
return {
|
|
132
|
+
epic: { id: epic.id, title: epic.title },
|
|
133
|
+
prd: projectBudgetedEntry(prdItem, prd, budgeted.mode),
|
|
134
|
+
techSpec: projectBudgetedEntry(techSpecItem, techSpec, budgeted.mode),
|
|
135
|
+
heuristics,
|
|
136
|
+
systemPrompt,
|
|
137
|
+
maxTickets,
|
|
138
|
+
// Story #3875 — surface the real delivery envelope to the decomposer
|
|
139
|
+
// so Stories are sized against the hydration budget and the
|
|
140
|
+
// configured preflight ceilings rather than guessed.
|
|
141
|
+
maxTokenBudget: limits.maxTokenBudget,
|
|
142
|
+
preflightCeilings: resolvePreflightCeilings(config),
|
|
143
|
+
contextMode: budgeted.mode,
|
|
144
|
+
// Story #2801 — surface the Phase 7 planning decision so the
|
|
145
|
+
// decomposition authoring step can cite the same risk
|
|
146
|
+
// classification used by gate routing. Both fields are `null`
|
|
147
|
+
// when the Epic was planned before the decision contract existed.
|
|
148
|
+
planningRisk,
|
|
149
|
+
reviewRouting,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* creation.js — sub-issue link reconciliation, Epic label transitions, and
|
|
3
|
+
* the advisory ticket-cap warning used by the reconciler-based persist flow
|
|
4
|
+
* (`persist.js`).
|
|
5
|
+
*
|
|
6
|
+
* Exports: `reconcileSubIssueLinks`, `setEpicLabel`,
|
|
7
|
+
* `warnTicketCapNearLimit`.
|
|
8
|
+
*
|
|
9
|
+
* @module lib/orchestration/epic-plan-decompose/phases/creation
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Logger } from '../../../Logger.js';
|
|
13
|
+
import { AGENT_LABELS } from '../../../label-constants.js';
|
|
14
|
+
|
|
15
|
+
export async function reconcileSubIssueLinks(epicId, provider) {
|
|
16
|
+
if (typeof provider.reconcileSubIssueLinks !== 'function') return;
|
|
17
|
+
Logger.info(
|
|
18
|
+
`[Decomposer] Reconciling sub-issue API links for Epic #${epicId}...`,
|
|
19
|
+
);
|
|
20
|
+
const result = await provider.reconcileSubIssueLinks(epicId);
|
|
21
|
+
const { totalExpected, alreadyLinked, reconciled, failed, failures } = result;
|
|
22
|
+
if (failed === 0) {
|
|
23
|
+
const reconciledNote = reconciled > 0 ? ` (${reconciled} reconciled)` : '';
|
|
24
|
+
Logger.info(
|
|
25
|
+
`[Decomposer] linked ${alreadyLinked + reconciled}/${totalExpected} sub-issues${reconciledNote}`,
|
|
26
|
+
);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const failure of failures) {
|
|
30
|
+
Logger.error(
|
|
31
|
+
`[Decomposer] sub-issue link gap: parent #${failure.parentId} ← child #${failure.childId}: ${failure.reason}`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
throw new Error(
|
|
35
|
+
`[Decomposer] Sub-issue reconciliation incomplete: ${failed}/${totalExpected} links could not be established (linked=${alreadyLinked}, reconciled=${reconciled}). See log for per-child reasons.`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function setEpicLabel(provider, epicId, targetLabel) {
|
|
40
|
+
const planningLabels = [AGENT_LABELS.REVIEW_SPEC, AGENT_LABELS.READY];
|
|
41
|
+
await provider.updateTicket(epicId, {
|
|
42
|
+
labels: {
|
|
43
|
+
add: [targetLabel],
|
|
44
|
+
remove: planningLabels.filter((l) => l !== targetLabel),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Advisory-only ticket-count check (Story #2798).
|
|
51
|
+
*
|
|
52
|
+
* `maxTickets` is a **reviewability budget**, not a hard authoring cap.
|
|
53
|
+
* This helper emits a non-destructive warning when a decomposition meets
|
|
54
|
+
* or exceeds the budget so the operator can spot over-budget plans early
|
|
55
|
+
* in the persist flow. It never blocks — the hard gate lives in the
|
|
56
|
+
* `runDecomposePhase` over-budget check, which requires an explicit
|
|
57
|
+
* `allowOverBudget` (CLI: `--allow-over-budget`) override.
|
|
58
|
+
*
|
|
59
|
+
* @param {Array} tickets
|
|
60
|
+
* @param {number} maxTickets — the reviewability budget
|
|
61
|
+
* @param {string} [tag] — log prefix
|
|
62
|
+
* @param {{ logger?: Pick<typeof Logger, 'warn'> }} [opts]
|
|
63
|
+
*/
|
|
64
|
+
export function warnTicketCapNearLimit(
|
|
65
|
+
tickets,
|
|
66
|
+
maxTickets,
|
|
67
|
+
tag = 'epic-plan-decompose',
|
|
68
|
+
{ logger = Logger } = {},
|
|
69
|
+
) {
|
|
70
|
+
if (tickets.length < maxTickets) return;
|
|
71
|
+
logger.warn(
|
|
72
|
+
`[${tag}] ⚠️ Received ${tickets.length} tickets against a reviewability budget of ${maxTickets}. Review the Feature/Story split before persisting; over-budget persistence requires --allow-over-budget.`,
|
|
73
|
+
);
|
|
74
|
+
}
|