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,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* console-allowlist.js — deterministic console-message → finding filter.
|
|
3
|
+
*
|
|
4
|
+
* Story #3295 (Feature #3289 "Instrumentation, inspection & findings",
|
|
5
|
+
* Epic #3214). The QA harness captures per-surface console messages via
|
|
6
|
+
* `list_console_messages` and must turn genuine console errors into
|
|
7
|
+
* structured findings while suppressing benign, expected noise. The
|
|
8
|
+
* suppression contract is the `qa.consoleAllowlist` array bound in
|
|
9
|
+
* `.agentrc.json` (landed by Story #3293): a list of inline patterns that
|
|
10
|
+
* mark a console message as expected.
|
|
11
|
+
*
|
|
12
|
+
* This module is the pure, side-effect-free decision layer. Given a list of
|
|
13
|
+
* captured console messages and the consumer's `consoleAllowlist`, it returns
|
|
14
|
+
* one structured finding per non-allowlisted console error and drops every
|
|
15
|
+
* message matched by an allowlist pattern. Determinism is load-bearing:
|
|
16
|
+
* re-running the filter over the same captured console with the same allowlist
|
|
17
|
+
* always yields the same findings in the same order, so the surrounding
|
|
18
|
+
* harness produces stable, diffable evidence.
|
|
19
|
+
*
|
|
20
|
+
* The emitted finding aligns with the `F#` finding shape from Tech Spec #3285
|
|
21
|
+
* (`{ id, classification, surface, symptom, likelyRootCause, disposition,
|
|
22
|
+
* acceptance, evidence: { console[], network[] } }`). Finding-shape *schema*
|
|
23
|
+
* validation (`qa-finding.schema.json`) is a sibling Story; this module only
|
|
24
|
+
* produces the console-derived subset and leaves richer enrichment
|
|
25
|
+
* (likely-root-cause heuristics, drafting) to later layers.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Console message levels that the harness treats as error-grade. Only
|
|
30
|
+
* messages at one of these levels can become a finding; `log`, `info`,
|
|
31
|
+
* `debug`, and `warning` are never escalated by this module.
|
|
32
|
+
*
|
|
33
|
+
* @type {ReadonlySet<string>}
|
|
34
|
+
*/
|
|
35
|
+
const ERROR_LEVELS = new Set(['error', 'severe']);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Normalise a captured console message into `{ level, text }`. Capture
|
|
39
|
+
* surfaces (`list_console_messages`, raw CDP, etc.) disagree on field names,
|
|
40
|
+
* so accept the common spellings and coerce defensively. A message with no
|
|
41
|
+
* recoverable text normalises to an empty string (which never matches an
|
|
42
|
+
* allowlist pattern and never reads as an error symptom).
|
|
43
|
+
*
|
|
44
|
+
* @param {unknown} message
|
|
45
|
+
* @returns {{ level: string, text: string }}
|
|
46
|
+
*/
|
|
47
|
+
function normaliseMessage(message) {
|
|
48
|
+
if (message == null || typeof message !== 'object') {
|
|
49
|
+
return { level: '', text: typeof message === 'string' ? message : '' };
|
|
50
|
+
}
|
|
51
|
+
const record = /** @type {Record<string, unknown>} */ (message);
|
|
52
|
+
const rawLevel = record.level ?? record.type ?? record.severity ?? '';
|
|
53
|
+
const rawText = record.text ?? record.message ?? record.value ?? '';
|
|
54
|
+
return {
|
|
55
|
+
level: String(rawLevel).toLowerCase(),
|
|
56
|
+
text: String(rawText),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Decide whether a console message text is matched by any allowlist pattern.
|
|
62
|
+
*
|
|
63
|
+
* Each allowlist entry is matched as a case-sensitive substring against the
|
|
64
|
+
* message text. Substring (not regex) matching is the deliberate contract:
|
|
65
|
+
* patterns stay readable in `.agentrc.json`, an operator never has to escape
|
|
66
|
+
* regex metacharacters, and the decision is trivially deterministic. An empty
|
|
67
|
+
* or blank pattern is ignored (it would otherwise match everything and
|
|
68
|
+
* silently swallow every error).
|
|
69
|
+
*
|
|
70
|
+
* @param {string} text Normalised console message text.
|
|
71
|
+
* @param {string[]} allowlist Inline benign-console patterns.
|
|
72
|
+
* @returns {boolean} `true` when the message is allowlisted (suppress it).
|
|
73
|
+
*/
|
|
74
|
+
export function isAllowlisted(text, allowlist) {
|
|
75
|
+
if (!Array.isArray(allowlist) || allowlist.length === 0) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return allowlist.some((pattern) => {
|
|
79
|
+
if (typeof pattern !== 'string' || pattern.trim() === '') {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
return text.includes(pattern);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Build a structured finding for a single non-allowlisted console error.
|
|
88
|
+
* The `id` is assigned by the caller (1-based finding index across a surface)
|
|
89
|
+
* so the surrounding harness controls finding numbering across console and
|
|
90
|
+
* network evidence.
|
|
91
|
+
*
|
|
92
|
+
* @param {{ level: string, text: string }} message Normalised console error.
|
|
93
|
+
* @param {{ surface?: string, index: number }} ctx
|
|
94
|
+
* @returns {object} Structured `F#` finding (console-derived subset).
|
|
95
|
+
*/
|
|
96
|
+
function buildFinding(message, ctx) {
|
|
97
|
+
return {
|
|
98
|
+
id: `F${ctx.index}`,
|
|
99
|
+
classification: 'console-error',
|
|
100
|
+
surface: ctx.surface ?? 'unknown',
|
|
101
|
+
symptom: message.text,
|
|
102
|
+
likelyRootCause: null,
|
|
103
|
+
disposition: 'follow-up',
|
|
104
|
+
acceptance: null,
|
|
105
|
+
evidence: {
|
|
106
|
+
console: [{ level: message.level, text: message.text }],
|
|
107
|
+
network: [],
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Filter captured console messages through the `consoleAllowlist` and emit a
|
|
114
|
+
* structured finding for each non-allowlisted console error.
|
|
115
|
+
*
|
|
116
|
+
* Behaviour contract:
|
|
117
|
+
* - A console **error** (level `error`/`severe`) whose text matches no
|
|
118
|
+
* allowlist pattern becomes exactly one finding.
|
|
119
|
+
* - A console message matched by any allowlist pattern is suppressed — no
|
|
120
|
+
* finding — even when it is an error.
|
|
121
|
+
* - Non-error levels (`log`, `info`, `warning`, …) are never escalated.
|
|
122
|
+
* - Findings are returned in capture order; ids are assigned `F1`, `F2`, …
|
|
123
|
+
* in that order.
|
|
124
|
+
*
|
|
125
|
+
* @param {Array<unknown>} messages Captured console messages.
|
|
126
|
+
* @param {string[]} [allowlist] `qa.consoleAllowlist` patterns.
|
|
127
|
+
* @param {{ surface?: string }} [opts] Surface label for the finding.
|
|
128
|
+
* @returns {object[]} Structured findings (possibly empty).
|
|
129
|
+
*/
|
|
130
|
+
export function filterConsoleMessages(messages, allowlist = [], opts = {}) {
|
|
131
|
+
if (!Array.isArray(messages)) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
const findings = [];
|
|
135
|
+
for (const raw of messages) {
|
|
136
|
+
const message = normaliseMessage(raw);
|
|
137
|
+
if (!ERROR_LEVELS.has(message.level)) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (isAllowlisted(message.text, allowlist)) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
findings.push(
|
|
144
|
+
buildFinding(message, {
|
|
145
|
+
surface: opts.surface,
|
|
146
|
+
index: findings.length + 1,
|
|
147
|
+
}),
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return findings;
|
|
151
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// .agents/scripts/lib/qa/coverage-report.js
|
|
2
|
+
//
|
|
3
|
+
// Render an AC × test-tier coverage matrix to a human-readable markdown
|
|
4
|
+
// report and persist it under `<tempRoot>/qa/`.
|
|
5
|
+
//
|
|
6
|
+
// The matrix shape is produced by `lib/qa/coverage-verdict.js#acceptanceMatrix`
|
|
7
|
+
// — one row per acceptance criterion, each row carrying the per-tier
|
|
8
|
+
// `coverageVerdict` (`{unit, contract, acceptance}` with `present`/`absent`
|
|
9
|
+
// statuses + notes). This module is the presentation + persistence seam:
|
|
10
|
+
// - {@link renderCoverageReport} — pure: matrix → markdown string.
|
|
11
|
+
// - {@link reportPathFor} — the report path under `<tempRoot>/qa/`.
|
|
12
|
+
// - {@link writeCoverageReport} — render + write the markdown to disk.
|
|
13
|
+
//
|
|
14
|
+
// `renderCoverageReport` does no I/O so it stays trivially unit-testable;
|
|
15
|
+
// `writeCoverageReport` accepts an injectable `fsImpl` (default `node:fs`)
|
|
16
|
+
// for the same reason, mirroring `lib/qa/qa-session.js`.
|
|
17
|
+
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import path from 'node:path';
|
|
20
|
+
|
|
21
|
+
import { tempRootFrom } from '../config/temp-paths.js';
|
|
22
|
+
import { acceptanceMatrix, TIERS } from './coverage-verdict.js';
|
|
23
|
+
|
|
24
|
+
/** Directory segment (under `tempRoot`) that holds QA coverage reports. */
|
|
25
|
+
export const QA_REPORT_DIRNAME = 'qa';
|
|
26
|
+
|
|
27
|
+
/** Cell glyph for each verdict status, used in the markdown matrix table. */
|
|
28
|
+
const STATUS_GLYPH = Object.freeze({
|
|
29
|
+
present: '✅ present',
|
|
30
|
+
absent: '❌ absent',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/** Title-case a tier name for the table header (`unit` → `Unit`). */
|
|
34
|
+
function tierHeader(tier) {
|
|
35
|
+
return tier.charAt(0).toUpperCase() + tier.slice(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Escape the pipe character so a label never breaks the markdown table, and
|
|
40
|
+
* collapse newlines to spaces so a multi-line criterion stays on one row.
|
|
41
|
+
*/
|
|
42
|
+
function cell(value) {
|
|
43
|
+
return String(value ?? '')
|
|
44
|
+
.replace(/\r?\n/g, ' ')
|
|
45
|
+
.replace(/\|/g, '\\|')
|
|
46
|
+
.trim();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the matrix input. Accepts either a pre-built matrix
|
|
51
|
+
* (`{tiers, rows}` from {@link acceptanceMatrix}) or raw criteria (array or
|
|
52
|
+
* keyed object), in which case it is run through {@link acceptanceMatrix}.
|
|
53
|
+
*
|
|
54
|
+
* @param {object|Array} input
|
|
55
|
+
* @returns {{tiers: ReadonlyArray<string>, rows: Array}}
|
|
56
|
+
*/
|
|
57
|
+
function resolveMatrix(input) {
|
|
58
|
+
if (
|
|
59
|
+
input &&
|
|
60
|
+
typeof input === 'object' &&
|
|
61
|
+
!Array.isArray(input) &&
|
|
62
|
+
Array.isArray(input.rows)
|
|
63
|
+
) {
|
|
64
|
+
return { tiers: input.tiers ?? TIERS, rows: input.rows };
|
|
65
|
+
}
|
|
66
|
+
return acceptanceMatrix(input);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Render an AC × test-tier coverage matrix to a markdown report string.
|
|
71
|
+
*
|
|
72
|
+
* The report has a title, a one-line summary of how many criteria are fully
|
|
73
|
+
* covered, the matrix table (one row per AC, one column per tier), and a
|
|
74
|
+
* per-criterion notes section explaining each absent tier.
|
|
75
|
+
*
|
|
76
|
+
* @param {{tiers?:ReadonlyArray<string>,rows:Array}|Array|object} input
|
|
77
|
+
* Either a built matrix (`{tiers, rows}`) or raw criteria to build one from.
|
|
78
|
+
* @param {{ title?: string, generatedAt?: string }} [opts]
|
|
79
|
+
* @returns {string} The markdown report.
|
|
80
|
+
*/
|
|
81
|
+
export function renderCoverageReport(input, opts = {}) {
|
|
82
|
+
const { tiers, rows } = resolveMatrix(input);
|
|
83
|
+
const title =
|
|
84
|
+
typeof opts.title === 'string' && opts.title.trim() !== ''
|
|
85
|
+
? opts.title.trim()
|
|
86
|
+
: 'QA Coverage — AC × Test-Tier Matrix';
|
|
87
|
+
|
|
88
|
+
const fullyCovered = rows.filter((row) =>
|
|
89
|
+
tiers.every((tier) => row.verdict[tier]?.status === 'present'),
|
|
90
|
+
).length;
|
|
91
|
+
|
|
92
|
+
const lines = [];
|
|
93
|
+
lines.push(`# ${title}`);
|
|
94
|
+
lines.push('');
|
|
95
|
+
if (typeof opts.generatedAt === 'string' && opts.generatedAt.trim() !== '') {
|
|
96
|
+
lines.push(`_Generated: ${opts.generatedAt.trim()}_`);
|
|
97
|
+
lines.push('');
|
|
98
|
+
}
|
|
99
|
+
lines.push(
|
|
100
|
+
`${rows.length} acceptance criteri${rows.length === 1 ? 'on' : 'a'}, ` +
|
|
101
|
+
`${fullyCovered} fully covered across all ${tiers.length} tiers.`,
|
|
102
|
+
);
|
|
103
|
+
lines.push('');
|
|
104
|
+
|
|
105
|
+
// Matrix table.
|
|
106
|
+
const headerCells = ['Acceptance Criterion', ...tiers.map(tierHeader)];
|
|
107
|
+
lines.push(`| ${headerCells.join(' | ')} |`);
|
|
108
|
+
lines.push(`| ${headerCells.map(() => '---').join(' | ')} |`);
|
|
109
|
+
for (const row of rows) {
|
|
110
|
+
const acCell = cell(row.label ? `${row.id}: ${row.label}` : row.id);
|
|
111
|
+
const tierCells = tiers.map((tier) => {
|
|
112
|
+
const status = row.verdict[tier]?.status ?? 'absent';
|
|
113
|
+
return STATUS_GLYPH[status] ?? cell(status);
|
|
114
|
+
});
|
|
115
|
+
lines.push(`| ${[acCell, ...tierCells].join(' | ')} |`);
|
|
116
|
+
}
|
|
117
|
+
lines.push('');
|
|
118
|
+
|
|
119
|
+
// Per-criterion notes.
|
|
120
|
+
lines.push('## Notes');
|
|
121
|
+
lines.push('');
|
|
122
|
+
for (const row of rows) {
|
|
123
|
+
lines.push(
|
|
124
|
+
`### ${cell(row.id)}${row.label ? ` — ${cell(row.label)}` : ''}`,
|
|
125
|
+
);
|
|
126
|
+
for (const tier of tiers) {
|
|
127
|
+
const v = row.verdict[tier];
|
|
128
|
+
const status = v?.status ?? 'absent';
|
|
129
|
+
const note = v?.note ?? '';
|
|
130
|
+
lines.push(`- **${tierHeader(tier)}** (${status}): ${cell(note)}`);
|
|
131
|
+
}
|
|
132
|
+
lines.push('');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return `${lines.join('\n').trimEnd()}\n`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The report path under `<tempRoot>/qa/`.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} [fileName] Report file name (default `coverage-report.md`).
|
|
142
|
+
* Path separators are rejected so a caller cannot escape the `qa/` dir.
|
|
143
|
+
* @param {object} [config] Resolved config bag (for `project.paths.tempRoot`).
|
|
144
|
+
* @returns {string}
|
|
145
|
+
*/
|
|
146
|
+
export function reportPathFor(fileName = 'coverage-report.md', config) {
|
|
147
|
+
const name = String(fileName);
|
|
148
|
+
if (name.includes('/') || name.includes('\\') || name === '..') {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`[coverage-report] file name must not contain path separators; got ${JSON.stringify(name)}`,
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
return path.join(tempRootFrom(config), QA_REPORT_DIRNAME, name);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Render the matrix to markdown and write it under `<tempRoot>/qa/`, creating
|
|
158
|
+
* the directory if needed. Returns the resolved path and the rendered body.
|
|
159
|
+
*
|
|
160
|
+
* @param {{tiers?:ReadonlyArray<string>,rows:Array}|Array|object} input
|
|
161
|
+
* Either a built matrix or raw criteria.
|
|
162
|
+
* @param {{
|
|
163
|
+
* fileName?: string,
|
|
164
|
+
* config?: object,
|
|
165
|
+
* title?: string,
|
|
166
|
+
* generatedAt?: string,
|
|
167
|
+
* fsImpl?: typeof fs,
|
|
168
|
+
* }} [opts]
|
|
169
|
+
* @returns {{ path: string, markdown: string }}
|
|
170
|
+
*/
|
|
171
|
+
export function writeCoverageReport(input, opts = {}) {
|
|
172
|
+
const fsImpl = opts.fsImpl ?? fs;
|
|
173
|
+
const markdown = renderCoverageReport(input, {
|
|
174
|
+
title: opts.title,
|
|
175
|
+
generatedAt: opts.generatedAt,
|
|
176
|
+
});
|
|
177
|
+
const reportPath = reportPathFor(opts.fileName, opts.config);
|
|
178
|
+
fsImpl.mkdirSync(path.dirname(reportPath), { recursive: true });
|
|
179
|
+
fsImpl.writeFileSync(reportPath, markdown, 'utf8');
|
|
180
|
+
return { path: reportPath, markdown };
|
|
181
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
// .agents/scripts/lib/qa/coverage-verdict.js
|
|
2
|
+
//
|
|
3
|
+
// Deterministic per-tier coverage verdict for a single finding surface.
|
|
4
|
+
//
|
|
5
|
+
// A "finding surface" is the unit of code a quality finding points at — a
|
|
6
|
+
// symbol (function / class / module export) together with the set of tests
|
|
7
|
+
// that exercise it. This helper answers one question, purely and without I/O:
|
|
8
|
+
// for that surface, which of the three test tiers from
|
|
9
|
+
// `.agents/rules/testing-standards.md` (unit / contract / acceptance) are
|
|
10
|
+
// PRESENT, and which are ABSENT — and why.
|
|
11
|
+
//
|
|
12
|
+
// A scenario that is skipped does not exercise anything — a `@skip` /
|
|
13
|
+
// `@pending` Gherkin tag (or a runner equivalent such as `it.skip` / `xit` /
|
|
14
|
+
// `describe.skip`, or a `skipped: true` descriptor field) means the test is
|
|
15
|
+
// inert at run time. This module therefore treats a skipped test as ABSENT
|
|
16
|
+
// for its tier: it never bumps a tier into `present`, because a tier whose
|
|
17
|
+
// only "coverage" is a skipped scenario is, operationally, uncovered.
|
|
18
|
+
//
|
|
19
|
+
// The companion process skill is `core/qa-coverage-mapping`, which shows how
|
|
20
|
+
// to gather the surface input and act on the verdict. This module is the
|
|
21
|
+
// deterministic seam that skill delegates to; it makes no network calls, runs
|
|
22
|
+
// no child processes, and reads no environment or files.
|
|
23
|
+
//
|
|
24
|
+
// Public API:
|
|
25
|
+
//
|
|
26
|
+
// coverageVerdict(surface) -> {
|
|
27
|
+
// unit: { status, note },
|
|
28
|
+
// contract: { status, note },
|
|
29
|
+
// acceptance: { status, note },
|
|
30
|
+
// }
|
|
31
|
+
//
|
|
32
|
+
// status is 'present' when the tier has at least one classified,
|
|
33
|
+
// non-skipped test, or 'absent' otherwise. `note` is a short
|
|
34
|
+
// operator-facing string explaining the verdict (always populated,
|
|
35
|
+
// including for present tiers).
|
|
36
|
+
//
|
|
37
|
+
// acceptanceMatrix(criteria) -> {
|
|
38
|
+
// tiers: TIERS,
|
|
39
|
+
// rows: [{ id, label, verdict }, ...],
|
|
40
|
+
// }
|
|
41
|
+
//
|
|
42
|
+
// Maps each acceptance criterion to its per-tier `coverageVerdict`, giving
|
|
43
|
+
// the AC × test-tier matrix the markdown report (lib/qa/coverage-report.js)
|
|
44
|
+
// renders.
|
|
45
|
+
|
|
46
|
+
/** The three test tiers, in pyramid order (base → top). */
|
|
47
|
+
export const TIERS = Object.freeze(['unit', 'contract', 'acceptance']);
|
|
48
|
+
|
|
49
|
+
const PRESENT = 'present';
|
|
50
|
+
const ABSENT = 'absent';
|
|
51
|
+
|
|
52
|
+
/** True when `value` contains a `@skip` or `@pending` Gherkin-style tag. */
|
|
53
|
+
function hasSkipTag(value) {
|
|
54
|
+
if (typeof value !== 'string') return false;
|
|
55
|
+
return /(^|[\s,])@(skip|pending)\b/i.test(value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** True when `value` contains a runner-level skip/pending marker. */
|
|
59
|
+
function hasRunnerSkipMarker(value) {
|
|
60
|
+
if (typeof value !== 'string') return false;
|
|
61
|
+
if (/\b(?:it|test|describe|context)\.(?:skip|todo)\b/i.test(value)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
return /\bx(?:it|test|describe|context)\b/i.test(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* True when a test descriptor is marked skipped/pending and therefore must
|
|
69
|
+
* NOT count toward its tier. Recognizes:
|
|
70
|
+
* - a `@skip` / `@pending` tag in a `tags` array or whitespace/comma string,
|
|
71
|
+
* - the same tags embedded in a path or descriptor `name`,
|
|
72
|
+
* - explicit boolean flags (`skipped`, `pending`),
|
|
73
|
+
* - runner skip markers in a path/name (`it.skip`, `xit`, `xdescribe`,
|
|
74
|
+
* `describe.skip`, `test.skip`, `.todo`).
|
|
75
|
+
*
|
|
76
|
+
* @param {string|object} test
|
|
77
|
+
* @returns {boolean}
|
|
78
|
+
*/
|
|
79
|
+
export function isSkipped(test) {
|
|
80
|
+
if (test == null) return false;
|
|
81
|
+
|
|
82
|
+
if (typeof test === 'object') {
|
|
83
|
+
// 1. Explicit boolean flags win.
|
|
84
|
+
if (test.skipped === true || test.pending === true) return true;
|
|
85
|
+
|
|
86
|
+
// 2. A `tags` field — array of tag strings or a single string.
|
|
87
|
+
const tags = test.tags;
|
|
88
|
+
if (Array.isArray(tags)) {
|
|
89
|
+
if (tags.some((t) => hasSkipTag(t))) return true;
|
|
90
|
+
} else if (typeof tags === 'string' && hasSkipTag(tags)) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 3. Scan a path/name string for an inline skip/pending tag or a runner
|
|
96
|
+
// skip marker (covers both string inputs and descriptor `path`/`name`).
|
|
97
|
+
const scannable =
|
|
98
|
+
typeof test === 'string'
|
|
99
|
+
? test
|
|
100
|
+
: typeof test === 'object'
|
|
101
|
+
? [test.path, test.name].filter((s) => typeof s === 'string').join(' ')
|
|
102
|
+
: '';
|
|
103
|
+
return hasSkipTag(scannable) || hasRunnerSkipMarker(scannable);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Classify a single test descriptor into one of the three tiers, or `null`
|
|
108
|
+
* when it cannot be placed OR when it is skipped/pending. Tier placement
|
|
109
|
+
* mirrors `.agents/rules/testing-standards.md`:
|
|
110
|
+
* - unit — colocated `*.test.*` next to source, or under `__tests__/`.
|
|
111
|
+
* - contract — lives under a `tests/contract/**` (or `**\/contract\/**`)
|
|
112
|
+
* path.
|
|
113
|
+
* - acceptance — a Gherkin `.feature` file (e2e / acceptance tier).
|
|
114
|
+
*
|
|
115
|
+
* An explicit `tier` field on the descriptor always wins over path inference,
|
|
116
|
+
* so callers that already know the tier can state it directly.
|
|
117
|
+
*
|
|
118
|
+
* A skipped/pending test (see {@link isSkipped}) is treated as inert and
|
|
119
|
+
* returns `null` so it never counts toward its tier — a tier covered only by
|
|
120
|
+
* a skipped scenario is, operationally, uncovered.
|
|
121
|
+
*/
|
|
122
|
+
export function classifyTest(test) {
|
|
123
|
+
if (test == null) return null;
|
|
124
|
+
|
|
125
|
+
// A skipped/pending test exercises nothing — it cannot place into any tier.
|
|
126
|
+
if (isSkipped(test)) return null;
|
|
127
|
+
|
|
128
|
+
// 1. Explicit tier wins.
|
|
129
|
+
const explicit =
|
|
130
|
+
typeof test === 'object' && typeof test.tier === 'string'
|
|
131
|
+
? test.tier.trim().toLowerCase()
|
|
132
|
+
: null;
|
|
133
|
+
if (explicit && TIERS.includes(explicit)) {
|
|
134
|
+
return explicit;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// 2. Infer from a path string.
|
|
138
|
+
const rawPath =
|
|
139
|
+
typeof test === 'string'
|
|
140
|
+
? test
|
|
141
|
+
: typeof test === 'object' && typeof test.path === 'string'
|
|
142
|
+
? test.path
|
|
143
|
+
: null;
|
|
144
|
+
if (!rawPath) return null;
|
|
145
|
+
|
|
146
|
+
const p = rawPath.replace(/\\/g, '/').toLowerCase();
|
|
147
|
+
|
|
148
|
+
if (p.endsWith('.feature')) return 'acceptance';
|
|
149
|
+
if (/(^|\/)contract\//.test(p) || /\.contract\.test\.[cm]?[jt]sx?$/.test(p)) {
|
|
150
|
+
return 'contract';
|
|
151
|
+
}
|
|
152
|
+
if (/\.test\.[cm]?[jt]sx?$/.test(p) || /(^|\/)__tests__\//.test(p)) {
|
|
153
|
+
return 'unit';
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const ABSENT_NOTES = Object.freeze({
|
|
159
|
+
unit: 'no colocated unit test exercises this surface',
|
|
160
|
+
contract: 'no contract test asserts this surface’s wire shape or boundary',
|
|
161
|
+
acceptance: 'no acceptance scenario covers a user-visible journey here',
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const PRESENT_NOTES = Object.freeze({
|
|
165
|
+
unit: (n) => `${n} unit test${n === 1 ? '' : 's'} present`,
|
|
166
|
+
contract: (n) => `${n} contract test${n === 1 ? '' : 's'} present`,
|
|
167
|
+
acceptance: (n) => `${n} acceptance scenario${n === 1 ? '' : 's'} present`,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Compute the per-tier coverage verdict for one finding surface.
|
|
172
|
+
*
|
|
173
|
+
* @param {object} surface
|
|
174
|
+
* @param {string} [surface.symbol] - The symbol the finding points at; echoed
|
|
175
|
+
* into notes for operator context. Optional.
|
|
176
|
+
* @param {Array<string|{path?:string,tier?:string,tags?:string|string[],skipped?:boolean,pending?:boolean}>} [surface.tests] -
|
|
177
|
+
* The tests that exercise the surface. Each entry is either a path string or
|
|
178
|
+
* a descriptor with `path`, `tier`, and/or skip markers (`tags`, `skipped`,
|
|
179
|
+
* `pending`). Unclassifiable and skipped/pending entries are ignored.
|
|
180
|
+
* @returns {{unit:{status:string,note:string},
|
|
181
|
+
* contract:{status:string,note:string},
|
|
182
|
+
* acceptance:{status:string,note:string}}}
|
|
183
|
+
*/
|
|
184
|
+
export function coverageVerdict(surface = {}) {
|
|
185
|
+
if (surface === null || typeof surface !== 'object') {
|
|
186
|
+
throw new TypeError('coverageVerdict: surface must be an object');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const tests = Array.isArray(surface.tests) ? surface.tests : [];
|
|
190
|
+
const symbol =
|
|
191
|
+
typeof surface.symbol === 'string' && surface.symbol.trim() !== ''
|
|
192
|
+
? surface.symbol.trim()
|
|
193
|
+
: null;
|
|
194
|
+
|
|
195
|
+
const counts = { unit: 0, contract: 0, acceptance: 0 };
|
|
196
|
+
for (const test of tests) {
|
|
197
|
+
const tier = classifyTest(test);
|
|
198
|
+
if (tier) counts[tier] += 1;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const verdict = {};
|
|
202
|
+
for (const tier of TIERS) {
|
|
203
|
+
const n = counts[tier];
|
|
204
|
+
if (n > 0) {
|
|
205
|
+
verdict[tier] = {
|
|
206
|
+
status: PRESENT,
|
|
207
|
+
note: PRESENT_NOTES[tier](n),
|
|
208
|
+
};
|
|
209
|
+
} else {
|
|
210
|
+
const base = ABSENT_NOTES[tier];
|
|
211
|
+
verdict[tier] = {
|
|
212
|
+
status: ABSENT,
|
|
213
|
+
note: symbol ? `${base} (${symbol})` : base,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return verdict;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Normalize a single criterion descriptor into `{id, label, surface}`. A
|
|
223
|
+
* descriptor may carry `id`, `label` (falls back to id), and either a nested
|
|
224
|
+
* `surface` or a flat `{symbol, tests}` shape.
|
|
225
|
+
*/
|
|
226
|
+
function normalizeOne(entry, index) {
|
|
227
|
+
const e = entry && typeof entry === 'object' ? entry : {};
|
|
228
|
+
const id =
|
|
229
|
+
typeof e.id === 'string' && e.id.trim() !== ''
|
|
230
|
+
? e.id.trim()
|
|
231
|
+
: `AC-${index + 1}`;
|
|
232
|
+
const label =
|
|
233
|
+
typeof e.label === 'string' && e.label.trim() !== '' ? e.label.trim() : id;
|
|
234
|
+
|
|
235
|
+
let surface;
|
|
236
|
+
if (e.surface && typeof e.surface === 'object') {
|
|
237
|
+
surface = e.surface;
|
|
238
|
+
} else if (Array.isArray(e.tests) || typeof e.symbol === 'string') {
|
|
239
|
+
surface = { symbol: e.symbol, tests: e.tests };
|
|
240
|
+
} else {
|
|
241
|
+
surface = {};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return { id, label, surface };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Normalize the criteria input for {@link acceptanceMatrix}. Accepts either an
|
|
249
|
+
* array of criterion descriptors or a plain object keyed by criterion id whose
|
|
250
|
+
* values are surfaces (or `{surface}` wrappers). Returns a normalized array of
|
|
251
|
+
* `{id, label, surface}`.
|
|
252
|
+
*
|
|
253
|
+
* @param {Array<object>|object} criteria
|
|
254
|
+
* @returns {Array<{id:string,label:string,surface:object}>}
|
|
255
|
+
*/
|
|
256
|
+
function normalizeCriteria(criteria) {
|
|
257
|
+
if (Array.isArray(criteria)) {
|
|
258
|
+
return criteria.map((entry, index) => normalizeOne(entry, index));
|
|
259
|
+
}
|
|
260
|
+
if (criteria && typeof criteria === 'object') {
|
|
261
|
+
return Object.entries(criteria).map(([id, value], index) =>
|
|
262
|
+
normalizeOne(
|
|
263
|
+
value && typeof value === 'object' && !Array.isArray(value)
|
|
264
|
+
? { id, ...value }
|
|
265
|
+
: { id, surface: { tests: value } },
|
|
266
|
+
index,
|
|
267
|
+
),
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
throw new TypeError(
|
|
271
|
+
'acceptanceMatrix: criteria must be an array or an object',
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Build the AC × test-tier matrix: for each acceptance criterion, the per-tier
|
|
277
|
+
* {@link coverageVerdict}. This is the structured shape the markdown report
|
|
278
|
+
* (`lib/qa/coverage-report.js`) renders into a table.
|
|
279
|
+
*
|
|
280
|
+
* @param {Array<{id?:string,label?:string,surface?:object,symbol?:string,tests?:Array}>|Record<string,object>} criteria
|
|
281
|
+
* Acceptance criteria, either as an array of descriptors or an object keyed
|
|
282
|
+
* by criterion id. Each descriptor names a surface (nested `surface`, or a
|
|
283
|
+
* flat `{symbol, tests}`).
|
|
284
|
+
* @returns {{tiers: ReadonlyArray<string>,
|
|
285
|
+
* rows: Array<{id:string,label:string,
|
|
286
|
+
* verdict:ReturnType<typeof coverageVerdict>}>}}
|
|
287
|
+
*/
|
|
288
|
+
export function acceptanceMatrix(criteria) {
|
|
289
|
+
const normalized = normalizeCriteria(criteria);
|
|
290
|
+
const rows = normalized.map(({ id, label, surface }) => ({
|
|
291
|
+
id,
|
|
292
|
+
label,
|
|
293
|
+
verdict: coverageVerdict(surface),
|
|
294
|
+
}));
|
|
295
|
+
return { tiers: TIERS, rows };
|
|
296
|
+
}
|