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,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* model-attribution.js — per-ticket model attribution comments + rollup
|
|
3
|
+
* (Story #2813).
|
|
4
|
+
*
|
|
5
|
+
* Records which Claude model executed a given ticket as a structured comment
|
|
6
|
+
* on that ticket. Epic-level mixes are computed at query time by walking the
|
|
7
|
+
* child tickets' comments — no Epic-scope emission is written.
|
|
8
|
+
*
|
|
9
|
+
* Surface:
|
|
10
|
+
*
|
|
11
|
+
* - {@link resolveModelIdentity} — pure resolver that picks an identity
|
|
12
|
+
* from the fallback chain (SDK metadata → env var → 'unknown'
|
|
13
|
+
* sentinel) and tags the source. Pure: no IO, no Date.now().
|
|
14
|
+
* - {@link buildModelAttributionPayload} — shape the canonical payload
|
|
15
|
+
* from a resolved identity + ticketId + timestamp.
|
|
16
|
+
* - {@link validateModelAttributionPayload} — hand-rolled validator
|
|
17
|
+
* matching `.agents/schemas/model-attribution.schema.json`. Returns
|
|
18
|
+
* `{ ok: true }` or `{ ok: false, errors: string[] }`.
|
|
19
|
+
* - {@link renderModelAttributionBody} — markdown body + fenced JSON
|
|
20
|
+
* block (same fence convention as the other structured comments in
|
|
21
|
+
* this repo so the shared `parseFencedJsonComment` can read it back).
|
|
22
|
+
* - {@link emitModelAttribution} — idempotent upsert against a Task
|
|
23
|
+
* ticket. Throws on validator failure (no comment written).
|
|
24
|
+
* - {@link parseModelAttributionComment} — readback helper for the
|
|
25
|
+
* rollup walker; returns `null` on missing/malformed payloads.
|
|
26
|
+
* - {@link rollupModelAttribution} — given a Story or Epic ticket id,
|
|
27
|
+
* walks `getSubTickets`, collects attribution comments, returns
|
|
28
|
+
* `{ totalChildren, byModel: {...}, missing: N }`.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { parseFencedJsonComment } from './structured-comment-parser.js';
|
|
32
|
+
import { findStructuredComment, upsertStructuredComment } from './ticketing.js';
|
|
33
|
+
|
|
34
|
+
export const MODEL_ATTRIBUTION_TYPE = 'model-attribution';
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Sentinel returned by {@link resolveModelIdentity} when neither the SDK
|
|
38
|
+
* metadata nor the runtime env var supplied a model id. Exported so tests
|
|
39
|
+
* and downstream consumers can compare without re-spelling the literal.
|
|
40
|
+
*/
|
|
41
|
+
export const UNKNOWN_MODEL_ID = 'unknown';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Env vars consulted as the second-priority resolver source. Listed in
|
|
45
|
+
* priority order — the first one set wins.
|
|
46
|
+
*/
|
|
47
|
+
const ENV_VAR_CANDIDATES = Object.freeze(['CLAUDE_MODEL', 'ANTHROPIC_MODEL']);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Derive the coarse family label from a canonical model id. Used for the
|
|
51
|
+
* rollup-friendly `family` field. Returns `null` when the id does not
|
|
52
|
+
* match a recognised family pattern (the rollup helper falls back to the
|
|
53
|
+
* full id in that case so unknown models still aggregate distinctly).
|
|
54
|
+
*
|
|
55
|
+
* Recognises Anthropic Claude families: Opus, Sonnet, Haiku.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} id
|
|
58
|
+
* @returns {string | null}
|
|
59
|
+
*/
|
|
60
|
+
export function deriveFamily(id) {
|
|
61
|
+
if (typeof id !== 'string') return null;
|
|
62
|
+
const lower = id.toLowerCase();
|
|
63
|
+
if (lower.includes('opus')) return 'Opus';
|
|
64
|
+
if (lower.includes('sonnet')) return 'Sonnet';
|
|
65
|
+
if (lower.includes('haiku')) return 'Haiku';
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Resolve the active model identity using the documented fallback chain:
|
|
71
|
+
*
|
|
72
|
+
* 1. `sdkMetadata.modelId` (or `.model`) when present and non-empty.
|
|
73
|
+
* 2. `CLAUDE_MODEL` / `ANTHROPIC_MODEL` env vars (first non-empty wins).
|
|
74
|
+
* 3. The `UNKNOWN_MODEL_ID` sentinel.
|
|
75
|
+
*
|
|
76
|
+
* Pure: accepts the env bag as an injectable argument so tests can pin
|
|
77
|
+
* the resolver without mutating `process.env`. Production callers default
|
|
78
|
+
* to `process.env`.
|
|
79
|
+
*
|
|
80
|
+
* @param {object} [opts]
|
|
81
|
+
* @param {object|null} [opts.sdkMetadata] — SDK response metadata.
|
|
82
|
+
* @param {Record<string, string|undefined>} [opts.env=process.env]
|
|
83
|
+
* @returns {{ id: string, family: string|null, source: 'sdk-metadata'|'env'|'unknown', sdkMetadata?: object }}
|
|
84
|
+
*/
|
|
85
|
+
export function resolveModelIdentity(opts = {}) {
|
|
86
|
+
const { sdkMetadata = null, env = process.env } = opts;
|
|
87
|
+
|
|
88
|
+
const sdkId =
|
|
89
|
+
sdkMetadata && typeof sdkMetadata === 'object'
|
|
90
|
+
? (typeof sdkMetadata.modelId === 'string' && sdkMetadata.modelId) ||
|
|
91
|
+
(typeof sdkMetadata.model === 'string' && sdkMetadata.model) ||
|
|
92
|
+
null
|
|
93
|
+
: null;
|
|
94
|
+
if (sdkId) {
|
|
95
|
+
return {
|
|
96
|
+
id: sdkId,
|
|
97
|
+
family: deriveFamily(sdkId),
|
|
98
|
+
source: 'sdk-metadata',
|
|
99
|
+
sdkMetadata,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
for (const name of ENV_VAR_CANDIDATES) {
|
|
104
|
+
const value = env?.[name];
|
|
105
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
106
|
+
return {
|
|
107
|
+
id: value,
|
|
108
|
+
family: deriveFamily(value),
|
|
109
|
+
source: 'env',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
id: UNKNOWN_MODEL_ID,
|
|
116
|
+
family: null,
|
|
117
|
+
source: 'unknown',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Build the canonical payload object from a resolved identity. Separated
|
|
123
|
+
* from {@link emitModelAttribution} so callers (and tests) can shape the
|
|
124
|
+
* payload without triggering the upsert side-effect.
|
|
125
|
+
*
|
|
126
|
+
* @param {{
|
|
127
|
+
* ticketId: number,
|
|
128
|
+
* identity: ReturnType<typeof resolveModelIdentity>,
|
|
129
|
+
* recordedAt?: string,
|
|
130
|
+
* }} args
|
|
131
|
+
* @returns {object}
|
|
132
|
+
*/
|
|
133
|
+
export function buildModelAttributionPayload(args) {
|
|
134
|
+
const { ticketId, identity, recordedAt } = args ?? {};
|
|
135
|
+
const payload = {
|
|
136
|
+
kind: MODEL_ATTRIBUTION_TYPE,
|
|
137
|
+
ticketId,
|
|
138
|
+
model: identity?.family
|
|
139
|
+
? { id: identity.id, family: identity.family }
|
|
140
|
+
: { id: identity?.id },
|
|
141
|
+
source: identity?.source,
|
|
142
|
+
recordedAt: recordedAt ?? new Date().toISOString(),
|
|
143
|
+
};
|
|
144
|
+
if (identity?.sdkMetadata && typeof identity.sdkMetadata === 'object') {
|
|
145
|
+
payload.sdkMetadata = identity.sdkMetadata;
|
|
146
|
+
}
|
|
147
|
+
return payload;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const VALID_SOURCES = new Set(['sdk-metadata', 'env', 'unknown']);
|
|
151
|
+
const ISO_8601_RE =
|
|
152
|
+
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Hand-rolled validator matching
|
|
156
|
+
* `.agents/schemas/model-attribution.schema.json`. Returns
|
|
157
|
+
* `{ ok: true }` on success, `{ ok: false, errors: string[] }` on
|
|
158
|
+
* failure. The error strings are stable enough to assert against in
|
|
159
|
+
* tests.
|
|
160
|
+
*
|
|
161
|
+
* The codebase does not pull in `ajv` for runtime schema validation
|
|
162
|
+
* (signals + structured comments use hand-rolled shape guards — see
|
|
163
|
+
* `lib/signals/schema.js`). We follow the same pattern here so the
|
|
164
|
+
* schema file stays the documented SSOT and the validator is the
|
|
165
|
+
* runtime gate.
|
|
166
|
+
*
|
|
167
|
+
* @param {unknown} payload
|
|
168
|
+
* @returns {{ ok: true } | { ok: false, errors: string[] }}
|
|
169
|
+
*/
|
|
170
|
+
export function validateModelAttributionPayload(payload) {
|
|
171
|
+
const errors = [];
|
|
172
|
+
if (
|
|
173
|
+
payload === null ||
|
|
174
|
+
typeof payload !== 'object' ||
|
|
175
|
+
Array.isArray(payload)
|
|
176
|
+
) {
|
|
177
|
+
return { ok: false, errors: ['payload must be a plain object'] };
|
|
178
|
+
}
|
|
179
|
+
if (payload.kind !== MODEL_ATTRIBUTION_TYPE) {
|
|
180
|
+
errors.push(`kind must be "${MODEL_ATTRIBUTION_TYPE}"`);
|
|
181
|
+
}
|
|
182
|
+
if (!Number.isInteger(payload.ticketId) || payload.ticketId <= 0) {
|
|
183
|
+
errors.push('ticketId must be a positive integer');
|
|
184
|
+
}
|
|
185
|
+
if (
|
|
186
|
+
!payload.model ||
|
|
187
|
+
typeof payload.model !== 'object' ||
|
|
188
|
+
Array.isArray(payload.model)
|
|
189
|
+
) {
|
|
190
|
+
errors.push('model must be an object');
|
|
191
|
+
} else {
|
|
192
|
+
if (typeof payload.model.id !== 'string' || payload.model.id.length === 0) {
|
|
193
|
+
errors.push('model.id must be a non-empty string');
|
|
194
|
+
}
|
|
195
|
+
if (
|
|
196
|
+
payload.model.family !== undefined &&
|
|
197
|
+
(typeof payload.model.family !== 'string' ||
|
|
198
|
+
payload.model.family.length === 0)
|
|
199
|
+
) {
|
|
200
|
+
errors.push('model.family, when present, must be a non-empty string');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (
|
|
204
|
+
typeof payload.source !== 'string' ||
|
|
205
|
+
!VALID_SOURCES.has(payload.source)
|
|
206
|
+
) {
|
|
207
|
+
errors.push(`source must be one of: ${[...VALID_SOURCES].join(', ')}`);
|
|
208
|
+
}
|
|
209
|
+
if (
|
|
210
|
+
typeof payload.recordedAt !== 'string' ||
|
|
211
|
+
!ISO_8601_RE.test(payload.recordedAt)
|
|
212
|
+
) {
|
|
213
|
+
errors.push('recordedAt must be an ISO-8601 timestamp string');
|
|
214
|
+
}
|
|
215
|
+
if (
|
|
216
|
+
payload.sdkMetadata !== undefined &&
|
|
217
|
+
(payload.sdkMetadata === null ||
|
|
218
|
+
typeof payload.sdkMetadata !== 'object' ||
|
|
219
|
+
Array.isArray(payload.sdkMetadata))
|
|
220
|
+
) {
|
|
221
|
+
errors.push('sdkMetadata, when present, must be an object');
|
|
222
|
+
}
|
|
223
|
+
return errors.length ? { ok: false, errors } : { ok: true };
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Render the markdown body that gets upserted as the structured comment.
|
|
228
|
+
* Body is a one-line summary followed by the canonical payload inside a
|
|
229
|
+
* fenced ```json``` block so downstream readers can use the shared
|
|
230
|
+
* `parseFencedJsonComment` helper without bespoke parsing.
|
|
231
|
+
*
|
|
232
|
+
* @param {object} payload — already validated.
|
|
233
|
+
* @returns {string}
|
|
234
|
+
*/
|
|
235
|
+
export function renderModelAttributionBody(payload) {
|
|
236
|
+
const id = payload.model?.id ?? UNKNOWN_MODEL_ID;
|
|
237
|
+
const family = payload.model?.family ? ` (${payload.model.family})` : '';
|
|
238
|
+
const sourceLabel =
|
|
239
|
+
payload.source === 'sdk-metadata'
|
|
240
|
+
? 'SDK metadata'
|
|
241
|
+
: payload.source === 'env'
|
|
242
|
+
? 'env var'
|
|
243
|
+
: 'unknown source';
|
|
244
|
+
const header = `🤖 Model attribution: \`${id}\`${family} · via ${sourceLabel}`;
|
|
245
|
+
return [header, '', '```json', JSON.stringify(payload, null, 2), '```'].join(
|
|
246
|
+
'\n',
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Emit (idempotently) the model-attribution comment onto a Task ticket.
|
|
252
|
+
* Validates the payload before any IO — a malformed payload throws and
|
|
253
|
+
* writes nothing to the provider.
|
|
254
|
+
*
|
|
255
|
+
* @param {{
|
|
256
|
+
* provider: import('../ITicketingProvider.js').ITicketingProvider,
|
|
257
|
+
* ticketId: number,
|
|
258
|
+
* sdkMetadata?: object|null,
|
|
259
|
+
* env?: Record<string, string|undefined>,
|
|
260
|
+
* recordedAt?: string,
|
|
261
|
+
* }} args
|
|
262
|
+
* @returns {Promise<{ payload: object, body: string }>}
|
|
263
|
+
*/
|
|
264
|
+
export async function emitModelAttribution(args) {
|
|
265
|
+
const { provider, ticketId, sdkMetadata, env, recordedAt } = args ?? {};
|
|
266
|
+
if (!provider || typeof provider.postComment !== 'function') {
|
|
267
|
+
throw new TypeError(
|
|
268
|
+
'emitModelAttribution requires a provider with postComment',
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
if (!Number.isInteger(ticketId) || ticketId <= 0) {
|
|
272
|
+
throw new TypeError(
|
|
273
|
+
'emitModelAttribution requires a positive integer ticketId',
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
const identity = resolveModelIdentity({ sdkMetadata, env });
|
|
277
|
+
const payload = buildModelAttributionPayload({
|
|
278
|
+
ticketId,
|
|
279
|
+
identity,
|
|
280
|
+
recordedAt,
|
|
281
|
+
});
|
|
282
|
+
const result = validateModelAttributionPayload(payload);
|
|
283
|
+
if (!result.ok) {
|
|
284
|
+
throw new Error(
|
|
285
|
+
`model-attribution payload failed validation: ${result.errors.join('; ')}`,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
const body = renderModelAttributionBody(payload);
|
|
289
|
+
await upsertStructuredComment(
|
|
290
|
+
provider,
|
|
291
|
+
ticketId,
|
|
292
|
+
MODEL_ATTRIBUTION_TYPE,
|
|
293
|
+
body,
|
|
294
|
+
);
|
|
295
|
+
return { payload, body };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Read back a model-attribution comment from a ticket. Returns the
|
|
300
|
+
* parsed payload, or `null` when the comment is missing or its payload
|
|
301
|
+
* fails validation (malformed payloads are treated as "no attribution"
|
|
302
|
+
* so a single corrupt comment does not poison the whole rollup).
|
|
303
|
+
*
|
|
304
|
+
* @param {{
|
|
305
|
+
* provider: import('../ITicketingProvider.js').ITicketingProvider,
|
|
306
|
+
* ticketId: number,
|
|
307
|
+
* }} args
|
|
308
|
+
* @returns {Promise<object|null>}
|
|
309
|
+
*/
|
|
310
|
+
export async function parseModelAttributionComment(args) {
|
|
311
|
+
const { provider, ticketId } = args ?? {};
|
|
312
|
+
const comment = await findStructuredComment(
|
|
313
|
+
provider,
|
|
314
|
+
ticketId,
|
|
315
|
+
MODEL_ATTRIBUTION_TYPE,
|
|
316
|
+
);
|
|
317
|
+
if (!comment) return null;
|
|
318
|
+
const parsed = parseFencedJsonComment(comment);
|
|
319
|
+
if (!parsed) return null;
|
|
320
|
+
const result = validateModelAttributionPayload(parsed);
|
|
321
|
+
return result.ok ? parsed : null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Walk the immediate child tickets of a parent (e.g. an Epic's Stories),
|
|
326
|
+
* read each child's model-attribution comment (when present), and
|
|
327
|
+
* aggregate per-model counts. Children with no attribution comment are
|
|
328
|
+
* counted under `missing`.
|
|
329
|
+
*
|
|
330
|
+
* Rollup is keyed by `model.family` when present, otherwise by
|
|
331
|
+
* `model.id` so unknown families still aggregate distinctly. The
|
|
332
|
+
* envelope also exposes the per-id breakdown for callers that want a
|
|
333
|
+
* finer-grained view.
|
|
334
|
+
*
|
|
335
|
+
* @param {{
|
|
336
|
+
* provider: import('../ITicketingProvider.js').ITicketingProvider,
|
|
337
|
+
* parentId: number,
|
|
338
|
+
* }} args
|
|
339
|
+
* @returns {Promise<{
|
|
340
|
+
* parentId: number,
|
|
341
|
+
* totalChildren: number,
|
|
342
|
+
* missing: number,
|
|
343
|
+
* byModel: Record<string, number>,
|
|
344
|
+
* byId: Record<string, number>,
|
|
345
|
+
* }>}
|
|
346
|
+
*/
|
|
347
|
+
export async function rollupModelAttribution(args) {
|
|
348
|
+
const { provider, parentId } = args ?? {};
|
|
349
|
+
if (!provider || typeof provider.getSubTickets !== 'function') {
|
|
350
|
+
throw new TypeError(
|
|
351
|
+
'rollupModelAttribution requires a provider with getSubTickets',
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
if (!Number.isInteger(parentId) || parentId <= 0) {
|
|
355
|
+
throw new TypeError(
|
|
356
|
+
'rollupModelAttribution requires a positive integer parentId',
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
const children = (await provider.getSubTickets(parentId)) ?? [];
|
|
360
|
+
const byModel = {};
|
|
361
|
+
const byId = {};
|
|
362
|
+
let missing = 0;
|
|
363
|
+
for (const child of children) {
|
|
364
|
+
const childId = Number(child?.id);
|
|
365
|
+
if (!Number.isInteger(childId) || childId <= 0) {
|
|
366
|
+
missing += 1;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
const payload = await parseModelAttributionComment({
|
|
370
|
+
provider,
|
|
371
|
+
ticketId: childId,
|
|
372
|
+
});
|
|
373
|
+
if (!payload) {
|
|
374
|
+
missing += 1;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
const familyKey =
|
|
378
|
+
payload.model?.family ?? payload.model?.id ?? UNKNOWN_MODEL_ID;
|
|
379
|
+
const idKey = payload.model?.id ?? UNKNOWN_MODEL_ID;
|
|
380
|
+
byModel[familyKey] = (byModel[familyKey] ?? 0) + 1;
|
|
381
|
+
byId[idKey] = (byId[idKey] ?? 0) + 1;
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
parentId,
|
|
385
|
+
totalChildren: children.length,
|
|
386
|
+
missing,
|
|
387
|
+
byModel,
|
|
388
|
+
byId,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify Stories that exist under an Epic but are absent from the frozen
|
|
3
|
+
* dispatch manifest. Two cases:
|
|
4
|
+
*
|
|
5
|
+
* - "recut" — the Story carries a `<!-- recut-of: #N -->` marker whose
|
|
6
|
+
* parent ID matches a manifest entry. These are attributable
|
|
7
|
+
* to a manifest Story and must be satisfied alongside it.
|
|
8
|
+
*
|
|
9
|
+
* - "parked" — the Story is genuinely outside the manifest (carved off
|
|
10
|
+
* mid-sprint, no recut lineage). The operator should explicitly
|
|
11
|
+
* adopt it into the current Epic or defer it. Surfaced as a
|
|
12
|
+
* structured comment so `/epic-deliver` has a single checkpoint.
|
|
13
|
+
*
|
|
14
|
+
* Both categories are informational at the wave-completeness gate — they do
|
|
15
|
+
* not fail closure by themselves. The gate continues to enforce that every
|
|
16
|
+
* manifest Story is closed; recuts and parked follow-ons are additional
|
|
17
|
+
* transparency.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { parseRecutMarker } from './recut.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Partition Stories under an Epic into manifest, recut, and parked buckets.
|
|
24
|
+
*
|
|
25
|
+
* @param {number[]} manifestStoryIds IDs present in the dispatch manifest.
|
|
26
|
+
* @param {Array<{ id: number, title?: string, body?: string, state?: string, labels?: string[] }>} storiesUnderEpic
|
|
27
|
+
* All `type::story` tickets under the Epic.
|
|
28
|
+
* @returns {{
|
|
29
|
+
* manifest: Array<object>,
|
|
30
|
+
* recuts: Array<{ storyId: number, parentId: number, title: string, state: string }>,
|
|
31
|
+
* parked: Array<{ storyId: number, title: string, state: string }>,
|
|
32
|
+
* }}
|
|
33
|
+
*/
|
|
34
|
+
export function classifyStoriesAgainstManifest(
|
|
35
|
+
manifestStoryIds,
|
|
36
|
+
storiesUnderEpic,
|
|
37
|
+
) {
|
|
38
|
+
const manifestSet = new Set(manifestStoryIds.map(Number));
|
|
39
|
+
const manifest = [];
|
|
40
|
+
const recuts = [];
|
|
41
|
+
const parked = [];
|
|
42
|
+
|
|
43
|
+
for (const story of storiesUnderEpic) {
|
|
44
|
+
if (manifestSet.has(story.id)) {
|
|
45
|
+
manifest.push(story);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const marker = parseRecutMarker(story.body);
|
|
49
|
+
if (marker && manifestSet.has(marker.parentStoryId)) {
|
|
50
|
+
recuts.push({
|
|
51
|
+
storyId: story.id,
|
|
52
|
+
parentId: marker.parentStoryId,
|
|
53
|
+
title: story.title ?? '',
|
|
54
|
+
state: story.state ?? 'open',
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
parked.push({
|
|
58
|
+
storyId: story.id,
|
|
59
|
+
title: story.title ?? '',
|
|
60
|
+
state: story.state ?? 'open',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { manifest, recuts, parked };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Render the structured `parked-follow-ons` comment body for an Epic.
|
|
70
|
+
* Idempotent: the same input produces identical output, so repeated upserts
|
|
71
|
+
* don't churn comment revisions.
|
|
72
|
+
*
|
|
73
|
+
* @param {number} epicId
|
|
74
|
+
* @param {ReturnType<typeof classifyStoriesAgainstManifest>} classification
|
|
75
|
+
* @returns {string}
|
|
76
|
+
*/
|
|
77
|
+
export function renderParkedFollowOnsComment(epicId, classification) {
|
|
78
|
+
const { recuts, parked } = classification;
|
|
79
|
+
|
|
80
|
+
const lines = [
|
|
81
|
+
`## 🪝 Parked Follow-Ons & Recuts — Epic #${epicId}`,
|
|
82
|
+
'',
|
|
83
|
+
'Stories created under this Epic that are **not** in the frozen dispatch',
|
|
84
|
+
'manifest. Surfaced here so `/epic-deliver` can gate on them at the',
|
|
85
|
+
'completeness check.',
|
|
86
|
+
'',
|
|
87
|
+
`- **Recuts** (attributable to a manifest Story): ${recuts.length}`,
|
|
88
|
+
`- **Parked follow-ons** (no manifest lineage): ${parked.length}`,
|
|
89
|
+
'',
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
if (recuts.length > 0) {
|
|
93
|
+
lines.push('### Recuts');
|
|
94
|
+
lines.push('');
|
|
95
|
+
lines.push('| Story | Recut-of | State | Title |');
|
|
96
|
+
lines.push('| :--- | :--- | :--- | :--- |');
|
|
97
|
+
for (const r of recuts) {
|
|
98
|
+
lines.push(
|
|
99
|
+
`| #${r.storyId} | #${r.parentId} | ${r.state} | ${r.title} |`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
lines.push('');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (parked.length > 0) {
|
|
106
|
+
lines.push('### Parked Follow-Ons');
|
|
107
|
+
lines.push('');
|
|
108
|
+
lines.push('| Story | State | Title |');
|
|
109
|
+
lines.push('| :--- | :--- | :--- |');
|
|
110
|
+
for (const p of parked) {
|
|
111
|
+
lines.push(`| #${p.storyId} | ${p.state} | ${p.title} |`);
|
|
112
|
+
}
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push(
|
|
115
|
+
'> **Action required**: adopt each Story into the current Epic (by',
|
|
116
|
+
'> re-running the dispatcher so the manifest is refreshed), or explicitly',
|
|
117
|
+
'> defer by closing the Story with `state_reason=not_planned`.',
|
|
118
|
+
);
|
|
119
|
+
lines.push('');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (recuts.length === 0 && parked.length === 0) {
|
|
123
|
+
lines.push(
|
|
124
|
+
'✅ No out-of-manifest Stories detected — every Story under this Epic is in the dispatch manifest.',
|
|
125
|
+
);
|
|
126
|
+
lines.push('');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
lines.push('```json');
|
|
130
|
+
lines.push(
|
|
131
|
+
JSON.stringify(
|
|
132
|
+
{
|
|
133
|
+
recuts: recuts.map((r) => ({
|
|
134
|
+
storyId: r.storyId,
|
|
135
|
+
parentId: r.parentId,
|
|
136
|
+
state: r.state,
|
|
137
|
+
})),
|
|
138
|
+
parked: parked.map((p) => ({ storyId: p.storyId, state: p.state })),
|
|
139
|
+
},
|
|
140
|
+
null,
|
|
141
|
+
2,
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
lines.push('```');
|
|
145
|
+
|
|
146
|
+
return lines.join('\n');
|
|
147
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* phase-runner.js — Lightweight wrappers for "named phase" error handling.
|
|
3
|
+
*
|
|
4
|
+
* Many orchestration entry points (story-init, story-close,
|
|
5
|
+
* the epic-runner submodules) repeat the same `try { ... } catch (err) {
|
|
6
|
+
* logger.error('[phase=foo] ' + err.message); ... }` block. These two
|
|
7
|
+
* helpers consolidate that pattern.
|
|
8
|
+
*
|
|
9
|
+
* - `runPhase(name, fn, opts)`: Run `fn()`. On error, log with a
|
|
10
|
+
* `[phase=<name>]` prefix. If `fatal: true`, rethrow; otherwise
|
|
11
|
+
* return `opts.fallback` (default `undefined`) so the caller can
|
|
12
|
+
* continue.
|
|
13
|
+
*
|
|
14
|
+
* - `runSafely(fn, opts)`: Run `fn()` and swallow any error after
|
|
15
|
+
* logging it. Convenience for unnamed best-effort cleanup steps.
|
|
16
|
+
*
|
|
17
|
+
* Both helpers handle sync and async `fn`s — the return value is always
|
|
18
|
+
* a Promise that resolves to the function's value (or `fallback`).
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { NOOP_LOGGER } from '../Logger.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {object} PhaseLogger
|
|
25
|
+
* @property {(msg: string) => void} [error]
|
|
26
|
+
* @property {(msg: string) => void} [warn]
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
function pickLogger(logger) {
|
|
30
|
+
if (!logger) return NOOP_LOGGER;
|
|
31
|
+
return {
|
|
32
|
+
error:
|
|
33
|
+
typeof logger.error === 'function'
|
|
34
|
+
? logger.error.bind(logger)
|
|
35
|
+
: NOOP_LOGGER.error,
|
|
36
|
+
warn:
|
|
37
|
+
typeof logger.warn === 'function'
|
|
38
|
+
? logger.warn.bind(logger)
|
|
39
|
+
: NOOP_LOGGER.warn,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Run `fn` under a named phase. On error:
|
|
45
|
+
* - logs `[phase=<name>] <message>` via `logger.error`
|
|
46
|
+
* - if `fatal` is true, rethrows the original error
|
|
47
|
+
* - otherwise returns `fallback`
|
|
48
|
+
*
|
|
49
|
+
* @template T
|
|
50
|
+
* @param {string} name - Phase name (used in the log prefix).
|
|
51
|
+
* @param {() => (T | Promise<T>)} fn
|
|
52
|
+
* @param {{ logger?: PhaseLogger, fallback?: T, fatal?: boolean }} [opts]
|
|
53
|
+
* @returns {Promise<T | undefined>}
|
|
54
|
+
*/
|
|
55
|
+
export async function runPhase(name, fn, opts = {}) {
|
|
56
|
+
const logger = pickLogger(opts.logger);
|
|
57
|
+
const fatal = opts.fatal === true;
|
|
58
|
+
try {
|
|
59
|
+
return await fn();
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
62
|
+
logger.error(`[phase=${name}] ${message}`);
|
|
63
|
+
if (fatal) throw err;
|
|
64
|
+
return opts.fallback;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Run `fn` and swallow errors after logging. Equivalent to
|
|
70
|
+
* `runPhase('safe', fn, { logger, fatal: false })` but without requiring
|
|
71
|
+
* the caller to invent a phase name.
|
|
72
|
+
*
|
|
73
|
+
* @template T
|
|
74
|
+
* @param {() => (T | Promise<T>)} fn
|
|
75
|
+
* @param {{ logger?: PhaseLogger }} [opts]
|
|
76
|
+
* @returns {Promise<T | undefined>}
|
|
77
|
+
*/
|
|
78
|
+
export async function runSafely(fn, opts = {}) {
|
|
79
|
+
const logger = pickLogger(opts.logger);
|
|
80
|
+
try {
|
|
81
|
+
return await fn();
|
|
82
|
+
} catch (err) {
|
|
83
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
84
|
+
logger.warn(`[phase=safe] ${message}`);
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plan-review-routing.js — resolve Phase 7 review-stop vs auto-proceed.
|
|
3
|
+
*
|
|
4
|
+
* Pure ESM, no I/O. Consumes the shared planningRisk envelope (derived
|
|
5
|
+
* from the planner-authored risk verdict via `deriveRiskEnvelope`) and
|
|
6
|
+
* optional operator overrides to decide whether the plan wrapper should
|
|
7
|
+
* STOP for human review before Phase 8.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import('./planning-risk.js').PlanningRiskEnvelope} PlanningRiskEnvelope
|
|
12
|
+
* @typedef {'review-required' | 'auto-proceed' | 'operator-override-review'} ReviewRoutingDecision
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} ReviewRoutingEnvelope
|
|
17
|
+
* @property {ReviewRoutingDecision} decision
|
|
18
|
+
* @property {boolean} requiresStop
|
|
19
|
+
* @property {boolean} forceReviewApplied
|
|
20
|
+
* @property {string} operatorMessage
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const AUTO_PROCEED_MESSAGE =
|
|
24
|
+
'Planning risk is low — auto-proceeding to Phase 8 decomposition after spec validation. Context tickets remain open until Epic delivery finalizes.';
|
|
25
|
+
|
|
26
|
+
const REVIEW_REQUIRED_MESSAGE =
|
|
27
|
+
'Planning risk requires operator review — STOP before Phase 8. Review the PRD, Tech Spec, and Acceptance Spec on GitHub and confirm in this session before decomposition.';
|
|
28
|
+
|
|
29
|
+
const FORCE_REVIEW_MESSAGE =
|
|
30
|
+
'Operator override — forcing review stop before Phase 8 despite low planning risk.';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Resolve whether Phase 7 should STOP for operator review before Phase 8.
|
|
34
|
+
*
|
|
35
|
+
* @param {{ planningRisk: PlanningRiskEnvelope, forceReview?: boolean }} input
|
|
36
|
+
* @returns {ReviewRoutingEnvelope}
|
|
37
|
+
*/
|
|
38
|
+
export function resolveReviewRouting({ planningRisk, forceReview = false }) {
|
|
39
|
+
if (forceReview) {
|
|
40
|
+
return {
|
|
41
|
+
decision: 'operator-override-review',
|
|
42
|
+
requiresStop: true,
|
|
43
|
+
forceReviewApplied: true,
|
|
44
|
+
operatorMessage: FORCE_REVIEW_MESSAGE,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (planningRisk.requiresReview) {
|
|
49
|
+
return {
|
|
50
|
+
decision: 'review-required',
|
|
51
|
+
requiresStop: true,
|
|
52
|
+
forceReviewApplied: false,
|
|
53
|
+
operatorMessage: REVIEW_REQUIRED_MESSAGE,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
decision: 'auto-proceed',
|
|
59
|
+
requiresStop: false,
|
|
60
|
+
forceReviewApplied: false,
|
|
61
|
+
operatorMessage: AUTO_PROCEED_MESSAGE,
|
|
62
|
+
};
|
|
63
|
+
}
|