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,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* epic-run-state-store — stateless functions for reading and writing the
|
|
3
|
+
* `epic-run-state` structured comment used by `/epic-deliver`.
|
|
4
|
+
*
|
|
5
|
+
* This module is the function-based replacement for the legacy
|
|
6
|
+
* `Checkpointer` class that previously lived at
|
|
7
|
+
* `./epic-runner/checkpointer.js`. Bodies were lifted verbatim from the
|
|
8
|
+
* corresponding `Checkpointer` methods so the structured-comment shape is
|
|
9
|
+
* preserved byte-for-byte. Story #2423 (Epic #2307) deleted the class
|
|
10
|
+
* file; the class API survives as a tests-only fixture at
|
|
11
|
+
* `tests/fixtures/epic-run-state-store.js`.
|
|
12
|
+
*
|
|
13
|
+
* The comment is identified by a stable HTML marker so it can be overwritten
|
|
14
|
+
* idempotently across orchestrator restarts. The body is a fenced JSON block
|
|
15
|
+
* following the schema in tech spec #323.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { assertValidDeliverPhase } from './epic-runner/deliver-phases.js';
|
|
19
|
+
import { parseFencedJsonComment } from './structured-comment-parser.js';
|
|
20
|
+
import { findStructuredComment, upsertStructuredComment } from './ticketing.js';
|
|
21
|
+
|
|
22
|
+
export const EPIC_RUN_STATE_TYPE = 'epic-run-state';
|
|
23
|
+
export const CHECKPOINT_SCHEMA_VERSION = 1;
|
|
24
|
+
|
|
25
|
+
// Re-export the phase enum + index helper so downstream importers continue
|
|
26
|
+
// to use this module as a single import target.
|
|
27
|
+
export {
|
|
28
|
+
DELIVER_PHASES,
|
|
29
|
+
phaseIndex,
|
|
30
|
+
} from './epic-runner/deliver-phases.js';
|
|
31
|
+
|
|
32
|
+
function assertProvider(provider) {
|
|
33
|
+
if (!provider)
|
|
34
|
+
throw new TypeError('epic-run-state-store requires a provider');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function assertEpicId(epicId) {
|
|
38
|
+
if (!Number.isInteger(epicId)) {
|
|
39
|
+
throw new TypeError('epic-run-state-store requires a numeric epicId');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Read and parse the checkpoint. Returns null if the comment is missing or
|
|
45
|
+
* unparseable (callers treat null as "start fresh").
|
|
46
|
+
*
|
|
47
|
+
* @param {{ provider: import('../ITicketingProvider.js').ITicketingProvider, epicId: number }} opts
|
|
48
|
+
* @returns {Promise<object | null>}
|
|
49
|
+
*/
|
|
50
|
+
export async function read({ provider, epicId } = {}) {
|
|
51
|
+
assertProvider(provider);
|
|
52
|
+
assertEpicId(epicId);
|
|
53
|
+
const comment = await findStructuredComment(
|
|
54
|
+
provider,
|
|
55
|
+
epicId,
|
|
56
|
+
EPIC_RUN_STATE_TYPE,
|
|
57
|
+
);
|
|
58
|
+
return parseFencedJsonComment(comment);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Overwrite the checkpoint with `state`. Idempotent — callers may invoke
|
|
63
|
+
* freely per wave; the marker-scoped upsert deletes the prior comment.
|
|
64
|
+
*
|
|
65
|
+
* @param {{ provider: import('../ITicketingProvider.js').ITicketingProvider, epicId: number, state: object }} opts
|
|
66
|
+
*/
|
|
67
|
+
export async function write({ provider, epicId, state } = {}) {
|
|
68
|
+
assertProvider(provider);
|
|
69
|
+
assertEpicId(epicId);
|
|
70
|
+
const payload = {
|
|
71
|
+
version: CHECKPOINT_SCHEMA_VERSION,
|
|
72
|
+
...state,
|
|
73
|
+
lastUpdatedAt: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
const body = `\`\`\`json\n${JSON.stringify(payload, null, 2)}\n\`\`\``;
|
|
76
|
+
await upsertStructuredComment(provider, epicId, EPIC_RUN_STATE_TYPE, body);
|
|
77
|
+
return payload;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Initial checkpoint for a brand-new run. Idempotent against re-dispatch
|
|
82
|
+
* when the wave shape is unchanged. When an existing checkpoint is found
|
|
83
|
+
* but the incoming `totalWaves` or `concurrencyCap` differs from the
|
|
84
|
+
* persisted values, refresh those fields in place — preserving
|
|
85
|
+
* `currentWave`, `waves[]`, `blockerHistory`, `manualInterventions`,
|
|
86
|
+
* `startedAt`, and any other already-persisted fields (e.g., `plan`,
|
|
87
|
+
* `phase`). The `plan` field is owned by the prepare caller, which
|
|
88
|
+
* overwrites it on every prepare run, so it does not need a delta check
|
|
89
|
+
* here.
|
|
90
|
+
*
|
|
91
|
+
* @param {{ provider: import('../ITicketingProvider.js').ITicketingProvider, epicId: number, totalWaves: number, concurrencyCap: number }} opts
|
|
92
|
+
*/
|
|
93
|
+
export async function initialize({
|
|
94
|
+
provider,
|
|
95
|
+
epicId,
|
|
96
|
+
totalWaves,
|
|
97
|
+
concurrencyCap,
|
|
98
|
+
} = {}) {
|
|
99
|
+
assertProvider(provider);
|
|
100
|
+
assertEpicId(epicId);
|
|
101
|
+
const existing = await read({ provider, epicId });
|
|
102
|
+
if (existing) {
|
|
103
|
+
if (
|
|
104
|
+
existing.totalWaves === totalWaves &&
|
|
105
|
+
existing.concurrencyCap === concurrencyCap
|
|
106
|
+
) {
|
|
107
|
+
return existing;
|
|
108
|
+
}
|
|
109
|
+
return write({
|
|
110
|
+
provider,
|
|
111
|
+
epicId,
|
|
112
|
+
state: { ...existing, totalWaves, concurrencyCap },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return write({
|
|
116
|
+
provider,
|
|
117
|
+
epicId,
|
|
118
|
+
state: {
|
|
119
|
+
epicId,
|
|
120
|
+
startedAt: new Date().toISOString(),
|
|
121
|
+
currentWave: 0,
|
|
122
|
+
totalWaves,
|
|
123
|
+
concurrencyCap,
|
|
124
|
+
phase: 'prepare',
|
|
125
|
+
waves: [],
|
|
126
|
+
blockerHistory: [],
|
|
127
|
+
manualInterventions: [],
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Reconcile the resume pointer (`currentWave` + `waves[]` history) against
|
|
134
|
+
* a freshly-recomputed wave plan.
|
|
135
|
+
*
|
|
136
|
+
* Story #3358 — when `/epic-deliver` is resumed on a partially-complete
|
|
137
|
+
* Epic, `epic-deliver-prepare.js` recomputes the wave DAG over only the
|
|
138
|
+
* **not-done** Stories (`build-wave-dag.js#discoverOpenStories` drops the
|
|
139
|
+
* closed/merged Stories). The recomputed plan is therefore *shorter* and
|
|
140
|
+
* **re-indexed from 0** — `plan[0]` is the next ready wave. The preserved
|
|
141
|
+
* checkpoint, however, still carries the prior `currentWave` (e.g. `2`)
|
|
142
|
+
* and a `waves[]` history keyed to the *old* index space. `wave-tick.js`
|
|
143
|
+
* then indexes `plan[currentWave]` into the new plan and dispatches the
|
|
144
|
+
* wrong wave — silently skipping the Stories that are actually ready.
|
|
145
|
+
*
|
|
146
|
+
* Prepare already owns the `plan` field (it overwrites it on every run),
|
|
147
|
+
* so it must equally own the pointer that indexes into that plan. This
|
|
148
|
+
* helper is the single point of reconciliation:
|
|
149
|
+
*
|
|
150
|
+
* - When the recomputed `nextPlan` is **structurally identical** to the
|
|
151
|
+
* persisted `priorPlan` (an idempotent re-prepare with no Story
|
|
152
|
+
* completed since the last run), the pointer is preserved verbatim so
|
|
153
|
+
* in-flight wave progress is not lost.
|
|
154
|
+
* - When the recomputed `nextPlan` **differs** (a Story merged → the
|
|
155
|
+
* plan got shorter / re-indexed), the pointer is reset: `currentWave`
|
|
156
|
+
* to `0` (the new plan's index space starts at the first not-done
|
|
157
|
+
* wave) and `waves[]` to `[]` (the prior history references the old
|
|
158
|
+
* index space and would mis-key `readGateFailures`).
|
|
159
|
+
*
|
|
160
|
+
* Plan equality is compared on the Story-id matrix only — `title` /
|
|
161
|
+
* `worktree` churn on an otherwise-identical plan must not trip a reset.
|
|
162
|
+
*
|
|
163
|
+
* Pure function — no I/O, no provider, no side effects.
|
|
164
|
+
*
|
|
165
|
+
* @param {{
|
|
166
|
+
* currentWave?: number,
|
|
167
|
+
* waves?: Array<unknown>,
|
|
168
|
+
* }} checkpoint The persisted checkpoint fields to reconcile.
|
|
169
|
+
* @param {Array<Array<{ id?: number, storyId?: number, number?: number }>>} priorPlan
|
|
170
|
+
* The plan currently persisted on the checkpoint (may be undefined on a
|
|
171
|
+
* first run).
|
|
172
|
+
* @param {Array<Array<{ id?: number, storyId?: number, number?: number }>>} nextPlan
|
|
173
|
+
* The freshly-recomputed plan prepare is about to persist.
|
|
174
|
+
* @returns {{ currentWave: number, waves: Array<unknown> }} The reconciled
|
|
175
|
+
* pointer fields. Always returns concrete values so the caller can spread
|
|
176
|
+
* them onto the checkpoint payload unconditionally.
|
|
177
|
+
*/
|
|
178
|
+
export function reconcileResumePointer(checkpoint, priorPlan, nextPlan) {
|
|
179
|
+
const safeWaves = Array.isArray(checkpoint?.waves) ? checkpoint.waves : [];
|
|
180
|
+
const currentWave = Number.isInteger(checkpoint?.currentWave)
|
|
181
|
+
? checkpoint.currentWave
|
|
182
|
+
: 0;
|
|
183
|
+
if (planStoryMatrixEqual(priorPlan, nextPlan)) {
|
|
184
|
+
return { currentWave, waves: safeWaves };
|
|
185
|
+
}
|
|
186
|
+
// Plan was recomputed (resume after a completed wave): the new plan is
|
|
187
|
+
// 0-indexed over the remaining not-done waves. Reset the pointer and
|
|
188
|
+
// drop the stale history so `wave-tick.js` reads `plan[0]`.
|
|
189
|
+
return { currentWave: 0, waves: [] };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Compare two wave plans on their Story-id matrix only. Each plan is
|
|
194
|
+
* `Array<Array<{ id|storyId|number }>>`; equality requires the same wave
|
|
195
|
+
* count, the same per-wave Story count, and the same Story ids in the same
|
|
196
|
+
* positions. `title` / `worktree` fields are ignored so cosmetic churn on
|
|
197
|
+
* an otherwise-identical plan does not register as a change.
|
|
198
|
+
*
|
|
199
|
+
* Pure helper for {@link reconcileResumePointer}.
|
|
200
|
+
*
|
|
201
|
+
* @param {Array<Array<object>>|undefined} a
|
|
202
|
+
* @param {Array<Array<object>>|undefined} b
|
|
203
|
+
* @returns {boolean}
|
|
204
|
+
*/
|
|
205
|
+
function planStoryMatrixEqual(a, b) {
|
|
206
|
+
const left = Array.isArray(a) ? a : [];
|
|
207
|
+
const right = Array.isArray(b) ? b : [];
|
|
208
|
+
if (left.length !== right.length) return false;
|
|
209
|
+
for (let i = 0; i < left.length; i += 1) {
|
|
210
|
+
const wl = Array.isArray(left[i]) ? left[i] : [];
|
|
211
|
+
const wr = Array.isArray(right[i]) ? right[i] : [];
|
|
212
|
+
if (wl.length !== wr.length) return false;
|
|
213
|
+
for (let j = 0; j < wl.length; j += 1) {
|
|
214
|
+
if (storyIdOf(wl[j]) !== storyIdOf(wr[j])) return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Extract the Story id from a plan entry. Mirrors the resolution order
|
|
222
|
+
* `wave-runner/tick.js#storyIdOf` uses so the equality check keys on the
|
|
223
|
+
* same identity the tick dispatches against. Returns `null` for shapeless
|
|
224
|
+
* entries so two `null`s never compare equal by accident.
|
|
225
|
+
*
|
|
226
|
+
* @param {object|number|null|undefined} entry
|
|
227
|
+
* @returns {number|null}
|
|
228
|
+
*/
|
|
229
|
+
function storyIdOf(entry) {
|
|
230
|
+
if (typeof entry === 'number') return entry;
|
|
231
|
+
if (!entry || typeof entry !== 'object') return null;
|
|
232
|
+
const id = entry.id ?? entry.storyId ?? entry.number;
|
|
233
|
+
return Number.isInteger(id) ? id : null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Append a manual-intervention record to the checkpoint. Out-of-band
|
|
238
|
+
* recovery steps the host LLM performs during a delivery — `AskUserQuestion`
|
|
239
|
+
* calls, `git restore`/`git reset` against the working tree, manual `--no-ff`
|
|
240
|
+
* recovery merges, story-close `--skipValidation` overrides — disqualify the
|
|
241
|
+
* Epic from auto-merge. The auto-merge predicate reads this array and only
|
|
242
|
+
* fires when it is empty.
|
|
243
|
+
*
|
|
244
|
+
* @param {{ provider: import('../ITicketingProvider.js').ITicketingProvider, epicId: number, entry: { reason: string, source?: string, ts?: string } }} opts
|
|
245
|
+
* @returns {Promise<object>} the persisted state
|
|
246
|
+
*/
|
|
247
|
+
export async function appendIntervention({ provider, epicId, entry } = {}) {
|
|
248
|
+
assertProvider(provider);
|
|
249
|
+
assertEpicId(epicId);
|
|
250
|
+
if (!entry || typeof entry.reason !== 'string' || entry.reason.length === 0) {
|
|
251
|
+
throw new TypeError('appendIntervention: { reason: string } is required.');
|
|
252
|
+
}
|
|
253
|
+
const existing = (await read({ provider, epicId })) ?? {};
|
|
254
|
+
const list = Array.isArray(existing.manualInterventions)
|
|
255
|
+
? existing.manualInterventions
|
|
256
|
+
: [];
|
|
257
|
+
const record = {
|
|
258
|
+
reason: entry.reason,
|
|
259
|
+
source: typeof entry.source === 'string' ? entry.source : 'host-llm',
|
|
260
|
+
ts: typeof entry.ts === 'string' ? entry.ts : new Date().toISOString(),
|
|
261
|
+
};
|
|
262
|
+
return write({
|
|
263
|
+
provider,
|
|
264
|
+
epicId,
|
|
265
|
+
state: {
|
|
266
|
+
...existing,
|
|
267
|
+
manualInterventions: [...list, record],
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Advance the checkpoint's `phase` field to the next `/epic-deliver`
|
|
274
|
+
* phase. Reads the current state first so the caller does not need to
|
|
275
|
+
* keep an in-memory copy. Other state fields are preserved verbatim.
|
|
276
|
+
*
|
|
277
|
+
* Story #1155 / Epic #1142 — phase-granular resume. The runner writes
|
|
278
|
+
* the **next phase to run** here, not the phase that just finished, so
|
|
279
|
+
* a resume can match `phase === 'code-review'` to mean "Phase D is the
|
|
280
|
+
* next thing to do."
|
|
281
|
+
*
|
|
282
|
+
* @param {{ provider: import('../ITicketingProvider.js').ITicketingProvider, epicId: number, nextPhase: string }} opts
|
|
283
|
+
* nextPhase - One of `DELIVER_PHASES` or `'done'`.
|
|
284
|
+
*/
|
|
285
|
+
export async function setPhase({ provider, epicId, nextPhase } = {}) {
|
|
286
|
+
assertProvider(provider);
|
|
287
|
+
assertEpicId(epicId);
|
|
288
|
+
assertValidDeliverPhase(nextPhase);
|
|
289
|
+
const existing = (await read({ provider, epicId })) ?? {};
|
|
290
|
+
return write({
|
|
291
|
+
provider,
|
|
292
|
+
epicId,
|
|
293
|
+
state: { ...existing, phase: nextPhase },
|
|
294
|
+
});
|
|
295
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Story conflict-finding gate for `epic-deliver-prepare.js`.
|
|
3
|
+
*
|
|
4
|
+
* Story #2297 — when the bounded `/epic-plan` flow emitted concurrency
|
|
5
|
+
* findings (Story #2296's validator pass), the operator may have shipped
|
|
6
|
+
* them through to `/epic-deliver` without resolving the underlying
|
|
7
|
+
* `depends_on` gaps. This gate runs at Phase 1 of `/epic-deliver` and
|
|
8
|
+
* refuses to flip the Epic to `agent::executing` when the upcoming
|
|
9
|
+
* waves still contain unresolved conflicts — surfacing the exact
|
|
10
|
+
* remediation commands the operator should run before retrying.
|
|
11
|
+
*
|
|
12
|
+
* The gate is opt-in by default:
|
|
13
|
+
* - Advisory findings (severity 'soft') only log a summary.
|
|
14
|
+
* - Hard findings (severity 'hard') OR `delivery.failOnConcurrencyHazards: true`
|
|
15
|
+
* promote a hard-stop.
|
|
16
|
+
*
|
|
17
|
+
* `--ignore-concurrency-hazards` bypasses the gate; the flag use is
|
|
18
|
+
* recorded on the Epic checkpoint so retro tooling can flag a run that
|
|
19
|
+
* shipped despite an outstanding hazard.
|
|
20
|
+
*
|
|
21
|
+
* The module is pure: it consumes a findings array and a wave plan and
|
|
22
|
+
* returns either a `{ ok: true }` envelope or throws. No I/O.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Build the set of "pending" story identifiers from a wave plan. A Story
|
|
27
|
+
* is pending unless its labels carry `agent::done`. Identifiers are
|
|
28
|
+
* collected in three shapes — `id` (number), `number`, and `slug` — so
|
|
29
|
+
* the caller can match findings keyed by any of them.
|
|
30
|
+
*
|
|
31
|
+
* @param {Array<Array<{ id?: number|string, number?: number|string, slug?: string, labels?: string[] }>>} wavePlan
|
|
32
|
+
* @returns {Set<string>}
|
|
33
|
+
*/
|
|
34
|
+
export function collectPendingStoryKeys(wavePlan) {
|
|
35
|
+
const pending = new Set();
|
|
36
|
+
if (!Array.isArray(wavePlan)) return pending;
|
|
37
|
+
for (const wave of wavePlan) {
|
|
38
|
+
if (!Array.isArray(wave)) continue;
|
|
39
|
+
for (const story of wave) {
|
|
40
|
+
if (!story || typeof story !== 'object') continue;
|
|
41
|
+
const labels = Array.isArray(story.labels) ? story.labels : [];
|
|
42
|
+
if (labels.includes('agent::done')) continue;
|
|
43
|
+
if (story.id != null) pending.add(String(story.id));
|
|
44
|
+
if (story.number != null) pending.add(String(story.number));
|
|
45
|
+
if (story.slug != null) pending.add(String(story.slug));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return pending;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Extract every story identifier a finding references. Both finding
|
|
53
|
+
* kinds in #2296's shape carry slugs; future persisted shapes may carry
|
|
54
|
+
* numeric IDs — accept both transparently.
|
|
55
|
+
*/
|
|
56
|
+
function findingStoryKeys(finding) {
|
|
57
|
+
const keys = [];
|
|
58
|
+
if (Array.isArray(finding?.storySlugs)) {
|
|
59
|
+
for (const s of finding.storySlugs) keys.push(String(s));
|
|
60
|
+
}
|
|
61
|
+
if (finding?.producer?.storySlug != null) {
|
|
62
|
+
keys.push(String(finding.producer.storySlug));
|
|
63
|
+
}
|
|
64
|
+
if (finding?.consumer?.storySlug != null) {
|
|
65
|
+
keys.push(String(finding.consumer.storySlug));
|
|
66
|
+
}
|
|
67
|
+
return keys;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Filter findings to those that touch at least one pending Story. A
|
|
72
|
+
* finding all of whose referenced Stories are already `agent::done` is
|
|
73
|
+
* harmless — the conflict has already played out — and is dropped.
|
|
74
|
+
*
|
|
75
|
+
* When `pendingKeys` is empty (every wave is done) every finding is
|
|
76
|
+
* filtered out. When a finding carries no identifiers (shape drift),
|
|
77
|
+
* conservatively keep it so the operator sees the signal.
|
|
78
|
+
*
|
|
79
|
+
* @param {object[]} findings
|
|
80
|
+
* @param {Set<string>} pendingKeys
|
|
81
|
+
* @returns {object[]}
|
|
82
|
+
*/
|
|
83
|
+
export function filterFindingsToPending(findings, pendingKeys) {
|
|
84
|
+
if (!Array.isArray(findings)) return [];
|
|
85
|
+
if (!(pendingKeys instanceof Set)) return findings;
|
|
86
|
+
return findings.filter((f) => {
|
|
87
|
+
const keys = findingStoryKeys(f);
|
|
88
|
+
if (keys.length === 0) return true;
|
|
89
|
+
return keys.some((k) => pendingKeys.has(k));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function isHardFinding(f) {
|
|
94
|
+
return f && f.severity === 'hard';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Render the operator-facing remediation block for a hard-gate trip.
|
|
99
|
+
* Produces a single multi-line string suitable for `throw new Error(...)`
|
|
100
|
+
* — names every offending path, the affected Stories, and the exact
|
|
101
|
+
* `gh issue edit` commands needed to add the missing `depends_on` links.
|
|
102
|
+
*/
|
|
103
|
+
export function renderGateErrorMessage(findings, ownerRepo) {
|
|
104
|
+
const lines = [
|
|
105
|
+
'Refusing to flip Epic to agent::executing — cross-Story concurrency hazards remain unresolved.',
|
|
106
|
+
'',
|
|
107
|
+
];
|
|
108
|
+
const sharedEditors = findings.filter((f) => f.kind === 'shared-editor');
|
|
109
|
+
const implicit = findings.filter(
|
|
110
|
+
(f) => f.kind === 'implicit-cross-story-dep',
|
|
111
|
+
);
|
|
112
|
+
if (sharedEditors.length > 0) {
|
|
113
|
+
lines.push('Shared-editor conflicts:');
|
|
114
|
+
for (const f of sharedEditors) {
|
|
115
|
+
const stories = Array.isArray(f.storySlugs) ? f.storySlugs : [];
|
|
116
|
+
lines.push(
|
|
117
|
+
` - "${f.path}" written by ${stories.length} concurrent Stories: ${stories.map((s) => `#${s}`).join(', ')}`,
|
|
118
|
+
);
|
|
119
|
+
lines.push(
|
|
120
|
+
' Remediation: add a `depends_on` chain or split the edits into a dedicated late-wave wiring Story.',
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
lines.push('');
|
|
124
|
+
}
|
|
125
|
+
if (implicit.length > 0) {
|
|
126
|
+
lines.push('Implicit cross-Story dependencies:');
|
|
127
|
+
for (const f of implicit) {
|
|
128
|
+
const p = f.producer ?? {};
|
|
129
|
+
const c = f.consumer ?? {};
|
|
130
|
+
lines.push(
|
|
131
|
+
` - "${f.path}" produced by Story #${p.storySlug ?? '?'} consumed by Story #${c.storySlug ?? '?'} (body.${c.sourceField ?? '?'})`,
|
|
132
|
+
);
|
|
133
|
+
const repoFlag = ownerRepo ? ` --repo ${ownerRepo}` : '';
|
|
134
|
+
lines.push(
|
|
135
|
+
` Remediation: gh issue edit ${c.storySlug ?? '?'}${repoFlag} --add-body $'\\n\\nblocked by #${p.storySlug ?? '?'}'`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
lines.push('');
|
|
139
|
+
}
|
|
140
|
+
lines.push(
|
|
141
|
+
'Resolve the listed conflicts and re-run `/epic-deliver`, or pass `--ignore-concurrency-hazards` to bypass this gate.',
|
|
142
|
+
);
|
|
143
|
+
return lines.join('\n');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Apply the gate to a findings array.
|
|
148
|
+
*
|
|
149
|
+
* @param {object} input
|
|
150
|
+
* @param {object[]} input.findings - Findings filtered to pending waves.
|
|
151
|
+
* @param {object} [input.policy] - Resolved `delivery.failOnConcurrencyHazards` (boolean).
|
|
152
|
+
* @param {boolean} [input.ignore] - `--ignore-concurrency-hazards` flag value.
|
|
153
|
+
* @param {string} [input.ownerRepo] - "owner/repo" string for `gh issue edit` hints.
|
|
154
|
+
* @returns {{ tripped: boolean, reason: 'hard-severity'|'config-fail-on'|null, findings: object[], bypassed: boolean }}
|
|
155
|
+
* When the gate trips and `ignore` is false the caller should
|
|
156
|
+
* throw `renderGateErrorMessage(findings, ownerRepo)`. The
|
|
157
|
+
* returned `bypassed` is true when `ignore` short-circuits a
|
|
158
|
+
* trip; record it on the checkpoint.
|
|
159
|
+
*/
|
|
160
|
+
export function evaluateConcurrencyGate({
|
|
161
|
+
findings = [],
|
|
162
|
+
policy = {},
|
|
163
|
+
ignore = false,
|
|
164
|
+
ownerRepo,
|
|
165
|
+
} = {}) {
|
|
166
|
+
void ownerRepo;
|
|
167
|
+
const hardFindings = findings.filter(isHardFinding);
|
|
168
|
+
const failOnConcurrencyHazards = policy.failOnConcurrencyHazards === true;
|
|
169
|
+
if (hardFindings.length > 0) {
|
|
170
|
+
return {
|
|
171
|
+
tripped: true,
|
|
172
|
+
reason: 'hard-severity',
|
|
173
|
+
findings: hardFindings,
|
|
174
|
+
bypassed: ignore === true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (failOnConcurrencyHazards && findings.length > 0) {
|
|
178
|
+
return {
|
|
179
|
+
tripped: true,
|
|
180
|
+
reason: 'config-fail-on',
|
|
181
|
+
findings,
|
|
182
|
+
bypassed: ignore === true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return { tripped: false, reason: null, findings: [], bypassed: false };
|
|
186
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* deliver-phases.js — phase enum and ordering utility for `/epic-deliver`.
|
|
3
|
+
*
|
|
4
|
+
* Story #1155 (Epic #1142, 5.40.0). Originally extracted from the
|
|
5
|
+
* legacy class-based checkpoint module so the phase enum and close-tail
|
|
6
|
+
* semantics live in a dedicated module that downstream tooling (the
|
|
7
|
+
* contract test) can import without dragging the provider-coupled
|
|
8
|
+
* checkpoint surface along. Story #2409 routes the runtime checkpoint
|
|
9
|
+
* read/write surface through `../epic-run-state-store.js`; this file
|
|
10
|
+
* remains the canonical home for the phase enum + validator.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ordered list of `/epic-deliver` phases. The checkpoint's `phase` field
|
|
15
|
+
* stores the **next phase to run**, so a mid-flight crash during
|
|
16
|
+
* `code-review` resumes by reading `phase === 'code-review'` and re-
|
|
17
|
+
* entering Phase D from the start.
|
|
18
|
+
*/
|
|
19
|
+
export const DELIVER_PHASES = Object.freeze([
|
|
20
|
+
'prepare',
|
|
21
|
+
'wave-loop',
|
|
22
|
+
'close-validation',
|
|
23
|
+
'code-review',
|
|
24
|
+
'retro',
|
|
25
|
+
'finalize',
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Pure: index of `phase` in `DELIVER_PHASES`. Returns `-1` for unknown
|
|
30
|
+
* values (callers treat that as "start fresh"); `+Infinity` for the
|
|
31
|
+
* terminal `'done'` sentinel.
|
|
32
|
+
*/
|
|
33
|
+
export function phaseIndex(phase) {
|
|
34
|
+
if (phase === 'done') return Number.POSITIVE_INFINITY;
|
|
35
|
+
return DELIVER_PHASES.indexOf(phase);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Pure: validate that `nextPhase` is a known phase tag (or the terminal
|
|
40
|
+
* `'done'` sentinel). Throws on invalid input — exported so the
|
|
41
|
+
* `setPhase` store function and downstream callers share one failure mode.
|
|
42
|
+
*/
|
|
43
|
+
export function assertValidDeliverPhase(nextPhase) {
|
|
44
|
+
if (nextPhase === 'done') return;
|
|
45
|
+
if (phaseIndex(nextPhase) >= 0) return;
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Invalid /epic-deliver phase ${JSON.stringify(nextPhase)}. ` +
|
|
48
|
+
`Expected one of ${DELIVER_PHASES.join(', ')} or 'done'.`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the wave DAG from the Epic's open child Stories.
|
|
3
|
+
*
|
|
4
|
+
* `getSubTickets` returns the **direct** children of a parent ticket via
|
|
5
|
+
* native sub-issues + checklist links + body reverse-lookup (despite an
|
|
6
|
+
* older docstring claiming "every descendant"). The v5 canonical Epic
|
|
7
|
+
* hierarchy is Epic → Feature → Story → Task, so Stories live as
|
|
8
|
+
* **grandchildren** of the Epic. We therefore walk one level deeper from
|
|
9
|
+
* each `type::feature` direct child to collect the real Story set, and
|
|
10
|
+
* union with any direct-child Stories (some Epics still carry Stories
|
|
11
|
+
* directly while migrating).
|
|
12
|
+
*
|
|
13
|
+
* We additionally filter out closed Stories — `getSubTickets`'s reverse-
|
|
14
|
+
* reference search can surface closed-as-obsolete tickets whose body
|
|
15
|
+
* still names the Epic (e.g. a Story replaced during a planning
|
|
16
|
+
* iteration). Dispatching against those would silently fan a sub-agent
|
|
17
|
+
* out at pre-replan work.
|
|
18
|
+
*
|
|
19
|
+
* Throws if no open Stories are found.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { parseBlockedBy } from '../../../dependency-parser.js';
|
|
23
|
+
import { computeWaves } from '../../../Graph.js';
|
|
24
|
+
import { TYPE_LABELS } from '../../../label-constants.js';
|
|
25
|
+
import { WaveScheduler } from '../wave-scheduler.js';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Walk Epic → Feature → Story (one descent past the Epic's direct
|
|
29
|
+
* children) and return the open `type::story` tickets, deduped by id.
|
|
30
|
+
*
|
|
31
|
+
* Exported so `snapshot.js#discoverStoryIds` and `epic-deliver-preflight`
|
|
32
|
+
* can share the same enumeration contract — the snapshot.end payload,
|
|
33
|
+
* preflight Story count, and wave DAG input set must never disagree.
|
|
34
|
+
*/
|
|
35
|
+
export async function discoverOpenStories({ epicId, provider }) {
|
|
36
|
+
const descendants = (await provider.getSubTickets(epicId)) ?? [];
|
|
37
|
+
const features = descendants.filter((t) =>
|
|
38
|
+
(t.labels ?? []).includes(TYPE_LABELS.FEATURE),
|
|
39
|
+
);
|
|
40
|
+
const grandchildren = (
|
|
41
|
+
await Promise.all(
|
|
42
|
+
features.map(async (f) => {
|
|
43
|
+
const id = f.id ?? f.number;
|
|
44
|
+
return id == null ? [] : ((await provider.getSubTickets(id)) ?? []);
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
47
|
+
).flat();
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
const stories = [];
|
|
50
|
+
for (const t of [...descendants, ...grandchildren]) {
|
|
51
|
+
const labels = t.labels ?? [];
|
|
52
|
+
if (!labels.includes(TYPE_LABELS.STORY)) continue;
|
|
53
|
+
const rawState = t.state ?? 'open';
|
|
54
|
+
const norm = typeof rawState === 'string' ? rawState.toLowerCase() : 'open';
|
|
55
|
+
if (norm !== 'open') continue;
|
|
56
|
+
const id = t.id ?? t.number;
|
|
57
|
+
if (id == null || seen.has(id)) continue;
|
|
58
|
+
seen.add(id);
|
|
59
|
+
stories.push(t);
|
|
60
|
+
}
|
|
61
|
+
return stories;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function runBuildWaveDagPhase(ctx, collaborators, state) {
|
|
65
|
+
const { epicId, provider } = ctx;
|
|
66
|
+
const bus = collaborators?.bus ?? null;
|
|
67
|
+
if (bus) {
|
|
68
|
+
await bus.emit('epic.plan.start', { epicId });
|
|
69
|
+
}
|
|
70
|
+
const stories = await discoverOpenStories({ epicId, provider });
|
|
71
|
+
if (!stories.length) {
|
|
72
|
+
throw new Error(`Epic #${epicId} has no child stories to dispatch.`);
|
|
73
|
+
}
|
|
74
|
+
const { adjacency, taskMap } = buildStoryDag(stories);
|
|
75
|
+
const waves = computeWaves(adjacency, taskMap);
|
|
76
|
+
const scheduler = new WaveScheduler(waves);
|
|
77
|
+
if (bus) {
|
|
78
|
+
// epic.plan.end carries the computed waves as the array-of-arrays
|
|
79
|
+
// shape declared by the schema. Each inner array is the storyIds
|
|
80
|
+
// dispatched together in that wave. `computeWaves` may return
|
|
81
|
+
// entries that are objects (when fed `taskMap`); we normalize to a
|
|
82
|
+
// simple numeric matrix here so the payload validates and replays
|
|
83
|
+
// off the ledger without coupling readers to internal types.
|
|
84
|
+
await bus.emit('epic.plan.end', {
|
|
85
|
+
waves: normalizeWavesForEmit(waves),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return { ...state, stories, waves, scheduler };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Normalize the runner's wave representation into the
|
|
93
|
+
* `Array<Array<integer>>` shape declared by
|
|
94
|
+
* `.agents/schemas/lifecycle/epic.plan.end.schema.json`. `computeWaves`
|
|
95
|
+
* returns waves of `taskMap` entries (objects with `id`); the ledger
|
|
96
|
+
* needs only the IDs. Defensive number coercion mirrors the same id
|
|
97
|
+
* extraction used in `buildStoryDag` above so emit and DAG stay
|
|
98
|
+
* structurally aligned.
|
|
99
|
+
*/
|
|
100
|
+
function normalizeWavesForEmit(waves) {
|
|
101
|
+
if (!Array.isArray(waves)) return [];
|
|
102
|
+
return waves.map((wave) => {
|
|
103
|
+
if (!Array.isArray(wave)) return [];
|
|
104
|
+
return wave
|
|
105
|
+
.map((entry) => {
|
|
106
|
+
if (entry == null) return null;
|
|
107
|
+
if (typeof entry === 'number') return entry;
|
|
108
|
+
const id = entry.id ?? entry.number ?? entry.storyId;
|
|
109
|
+
return id == null ? null : Number(id);
|
|
110
|
+
})
|
|
111
|
+
.filter((n) => Number.isInteger(n) && n > 0);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Convert an ordered list of story tickets into the adjacency/taskMap shape
|
|
117
|
+
* that `Graph.computeWaves()` expects.
|
|
118
|
+
*
|
|
119
|
+
* Dependency source order (must match manifest-builder.js so dispatch manifest
|
|
120
|
+
* and runtime wave scheduling never disagree):
|
|
121
|
+
* 1. Canonical: `blocked by #NNN` / `depends on #NNN` parsed from the story
|
|
122
|
+
* ticket body via `parseBlockedBy` (same parser the dispatcher uses).
|
|
123
|
+
* 2. Fallback: explicit `dependencies` array on the provider-returned story
|
|
124
|
+
* object (present in fixture / test payloads; optional in live GitHub
|
|
125
|
+
* payloads).
|
|
126
|
+
* Only edges to other stories in this Epic are retained — foreign IDs are
|
|
127
|
+
* dropped so the DAG stays closed over the scheduled set.
|
|
128
|
+
*/
|
|
129
|
+
function buildStoryDag(stories) {
|
|
130
|
+
const adjacency = new Map();
|
|
131
|
+
const taskMap = new Map();
|
|
132
|
+
const storyIds = new Set(stories.map((s) => Number(s.id ?? s.number)));
|
|
133
|
+
for (const s of stories) {
|
|
134
|
+
const id = Number(s.id ?? s.number);
|
|
135
|
+
const fromBody = parseBlockedBy(s.body ?? '');
|
|
136
|
+
const fromField = Array.isArray(s.dependencies)
|
|
137
|
+
? s.dependencies.map(Number)
|
|
138
|
+
: [];
|
|
139
|
+
const merged = [...new Set([...fromBody, ...fromField])]
|
|
140
|
+
.map(Number)
|
|
141
|
+
.filter((dep) => dep !== id && storyIds.has(dep));
|
|
142
|
+
adjacency.set(id, merged);
|
|
143
|
+
taskMap.set(id, { ...s, id });
|
|
144
|
+
}
|
|
145
|
+
return { adjacency, taskMap };
|
|
146
|
+
}
|