mandrel 2.60.0 → 2.62.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 +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +32 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,60 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* This module is the scheduling kernel the v2 `/mandrel-deliver` multi-Story path
|
|
6
|
-
* dispatches through (`stories-wave-tick.js`). It replaces wave-*batch* selection
|
|
7
|
-
* (group N must fully drain before group N+1 opens) with *continuous*,
|
|
8
|
-
* dependency-driven selection: a Story becomes dispatchable the instant
|
|
9
|
-
* **its own** dependencies are satisfied, regardless of whether unrelated
|
|
10
|
-
* Stories in some nominal wave are still running. There is no false
|
|
11
|
-
* barrier — a Story C that depends only on a done Story A is selected even
|
|
12
|
-
* while an unrelated Story B is still pending.
|
|
13
|
-
*
|
|
14
|
-
* It is deliberately **path-agnostic and side-effect-free**: it neither
|
|
15
|
-
* reads GitHub, the lifecycle ledger, nor a checkpoint, and it dispatches
|
|
16
|
-
* nothing. Callers supply the live Story records (already fetched), the
|
|
17
|
-
* resolved `inFlight` count, and the `globalCap`, and receive back the set
|
|
18
|
-
* of Stories that are safe to dispatch on this beat. The
|
|
19
|
-
* `stories-wave-tick.js` adapter wires this core; this module does not
|
|
20
|
-
* modify that CLI surface.
|
|
21
|
-
*
|
|
22
|
-
* The scheduling surface:
|
|
23
|
-
* - `classifyStory(story)` — live-label classifier mapping a Story
|
|
24
|
-
* record's labels + issue state to one of `done | blocked | executing |
|
|
25
|
-
* ready`. Mirrors the done-predicate this module uses
|
|
26
|
-
* (`agent::done` OR closed issue) so a Story closed manually through
|
|
27
|
-
* the GitHub UI is recognised as done.
|
|
28
|
-
* - `storiesOverlap(a, b)` — the **beat-local** file-overlap co-dispatch
|
|
29
|
-
* guard: true when two Stories' file footprints intersect. Two Stories
|
|
30
|
-
* that would touch the same file MUST NOT be admitted onto parallel
|
|
31
|
-
* `story-<id>` branches on the same beat (they would race the same path
|
|
32
|
-
* and produce a merge conflict at close). The comparison runs over
|
|
33
|
-
* the **widened** footprint (`storyWidenedFootprint`) — a declared
|
|
34
|
-
* `changes[]` is treated as a lower bound and widened from the paths the
|
|
35
|
-
* Story's own text names, because a guard that trusts a prediction cannot
|
|
36
|
-
* prevent the collision nobody predicted (Story #4875).
|
|
37
|
-
* - `planReadySet({ stories, doneIds, inFlight, globalCap,
|
|
38
|
-
* inFlightRecords })` — the scheduler. Returns the deterministic,
|
|
39
|
-
* overlap-free dispatch set (capped at `globalCap − inFlight`) **and**
|
|
40
|
-
* the Stories it withheld because a **concrete** path in their footprint
|
|
41
|
-
* is reserved by a Story still in flight from an earlier beat.
|
|
42
|
-
*
|
|
43
|
-
* The two guards deliberately draw the glob/UNKNOWN class differently
|
|
44
|
-
* (Story #4960). Within a beat an unknown-width footprint overlaps
|
|
45
|
-
* everything, because admitting two Stories whose real widths are unknown is
|
|
46
|
-
* the collision the guard exists to prevent. Across beats it reserves
|
|
47
|
-
* nothing: an in-flight Story's window spans its whole implementation, so a
|
|
48
|
-
* glob that reserved cross-beat would withhold every other Story for
|
|
49
|
-
* minutes-to-hours — and `resolve-stories.js` substitutes the UNKNOWN
|
|
50
|
-
* sentinel for any body it cannot parse, so a single malformed Story body
|
|
51
|
-
* would collapse an N-Story run to fully serial.
|
|
52
|
-
*
|
|
53
|
-
* Adjacency is re-derived from the supplied records via the shared
|
|
54
|
-
* `buildStoryAdjacency` builder (`lib/story-adjacency.js`) — the same
|
|
55
|
-
* `blocked by #NNN` / `dependencies[]` source order the dispatch manifest
|
|
56
|
-
* and the existing wave wrappers use — so this core never disagrees with
|
|
57
|
-
* the manifest about what depends on what.
|
|
2
|
+
* Side-effect-free ready-set scheduler: a Story is dispatchable the instant
|
|
3
|
+
* its own dependencies are done (no wave barrier), capped by `globalCap` and
|
|
4
|
+
* filtered by the file-footprint overlap guards.
|
|
58
5
|
*
|
|
59
6
|
* @module lib/wave-runner/ready-set
|
|
60
7
|
*/
|
|
@@ -64,28 +11,16 @@ import { buildStoryAdjacency } from '../story-adjacency.js';
|
|
|
64
11
|
import { detectCollision } from './footprint.js';
|
|
65
12
|
|
|
66
13
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `enforce` is the default and encodes delivery-time-only knowledge the
|
|
71
|
-
* planner cannot have: which implementation windows are open right now, which
|
|
72
|
-
* Stories a foreign lease holds, how far the ground has moved since the plan
|
|
73
|
-
* was authored. It is never demoted automatically.
|
|
74
|
-
*
|
|
75
|
-
* `advisory` is an explicit operator trade for throughput on a run whose
|
|
76
|
-
* `depends_on` edges are known to be complete. Detection still runs; only the
|
|
77
|
-
* withholding stops.
|
|
14
|
+
* `delivery.deliverRunner.footprintGuard`: `enforce` (default, never demoted
|
|
15
|
+
* automatically) withholds on collision; `advisory` still detects but only
|
|
16
|
+
* reports, for runs whose `depends_on` edges are known complete.
|
|
78
17
|
*/
|
|
79
18
|
export const GUARD_MODES = Object.freeze({
|
|
80
19
|
ENFORCE: 'enforce',
|
|
81
20
|
ADVISORY: 'advisory',
|
|
82
21
|
});
|
|
83
22
|
|
|
84
|
-
/**
|
|
85
|
-
* Which guard produced a withhold: a peer admitted **this beat**, or a Story
|
|
86
|
-
* still in flight from an **earlier** one. The two clear on different events,
|
|
87
|
-
* so an operator reading the report needs them apart.
|
|
88
|
-
*/
|
|
23
|
+
/** Which guard withheld: a same-beat peer or an earlier in-flight Story. */
|
|
89
24
|
export const WITHHOLD_SCOPES = Object.freeze({
|
|
90
25
|
BEAT: 'beat',
|
|
91
26
|
IN_FLIGHT: 'in-flight',
|
|
@@ -93,27 +28,23 @@ export const WITHHOLD_SCOPES = Object.freeze({
|
|
|
93
28
|
|
|
94
29
|
/**
|
|
95
30
|
* @typedef {object} StoryRecord
|
|
96
|
-
* @property {number|string} [id]
|
|
97
|
-
* @property {number} [number]
|
|
31
|
+
* @property {number|string} [id]
|
|
32
|
+
* @property {number} [number]
|
|
98
33
|
* @property {string} [title]
|
|
99
|
-
* @property {string} [body]
|
|
100
|
-
*
|
|
101
|
-
* @property {string
|
|
102
|
-
* @property {string} [
|
|
103
|
-
* @property {Array<number|string>} [
|
|
104
|
-
* @property {
|
|
105
|
-
* @property {string[]} [
|
|
106
|
-
*
|
|
107
|
-
* @property {string[]} [changes] Alternate footprint shape.
|
|
108
|
-
* @property {Array<{path?: string}>} [changeset] Alternate footprint shape.
|
|
34
|
+
* @property {string} [body]
|
|
35
|
+
* @property {string[]} [labels]
|
|
36
|
+
* @property {string} [state]
|
|
37
|
+
* @property {Array<number|string>} [dependencies]
|
|
38
|
+
* @property {Array<number|string>} [dependsOn]
|
|
39
|
+
* @property {string[]} [files] Footprint (any `storyFootprint` shape).
|
|
40
|
+
* @property {string[]} [changes]
|
|
41
|
+
* @property {Array<{path?: string}>} [changeset]
|
|
109
42
|
*/
|
|
110
43
|
|
|
111
44
|
/** @typedef {'done'|'blocked'|'executing'|'ready'} StoryClass */
|
|
112
45
|
|
|
113
46
|
/**
|
|
114
|
-
*
|
|
115
|
-
* absent / non-integer. Accepts both the ticket shape (`id`) and the raw
|
|
116
|
-
* GitHub issue shape (`number`), matching `buildStoryAdjacency`.
|
|
47
|
+
* Positive-integer Story id from `id` or `number`, else `null`.
|
|
117
48
|
*
|
|
118
49
|
* @param {StoryRecord|number|string} story
|
|
119
50
|
* @returns {number|null}
|
|
@@ -128,23 +59,9 @@ export function storyIdOf(story) {
|
|
|
128
59
|
}
|
|
129
60
|
|
|
130
61
|
/**
|
|
131
|
-
* Classify a Story from
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* 1. `done` — carries `agent::done` OR the issue is `state === 'closed'`.
|
|
135
|
-
* The closed-state arm aligns with `tick.js#isStoryDone`
|
|
136
|
-
* so a Story closed manually in the GitHub UI (issue
|
|
137
|
-
* closed, label not flipped) still reads as done and is
|
|
138
|
-
* never re-dispatched.
|
|
139
|
-
* 2. `blocked` — carries `agent::blocked`.
|
|
140
|
-
* 3. `executing` — carries `agent::executing` OR `agent::closing` (both
|
|
141
|
-
* are in-flight: an executing or closing Story occupies a
|
|
142
|
-
* slot and must not be re-dispatched).
|
|
143
|
-
* 4. `ready` — none of the above; the Story is eligible for dispatch
|
|
144
|
-
* once its dependencies are satisfied.
|
|
145
|
-
*
|
|
146
|
-
* `done` wins over every in-progress label so a stale `agent::executing`
|
|
147
|
-
* left behind on an issue that has since closed never masks completion.
|
|
62
|
+
* Classify a Story from live labels and state. `done` (label or closed issue,
|
|
63
|
+
* so a manual UI close counts) wins over any stale in-progress label;
|
|
64
|
+
* `closing` counts as executing because it still occupies a slot.
|
|
148
65
|
*
|
|
149
66
|
* @param {StoryRecord} story
|
|
150
67
|
* @returns {StoryClass}
|
|
@@ -165,25 +82,10 @@ export function classifyStory(story) {
|
|
|
165
82
|
}
|
|
166
83
|
|
|
167
84
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
* Comparison runs over the **widened** footprint
|
|
173
|
-
* ({@link storyWidenedFootprint}), not the declaration: a declared `changes[]`
|
|
174
|
-
* is a lower bound on what a Story will touch, and two Stories whose real edits
|
|
175
|
-
* collide were being co-dispatched whenever the collision was not predicted
|
|
176
|
-
* (Story #4875).
|
|
177
|
-
*
|
|
178
|
-
* **A glob footprint overlaps EVERYTHING** → `true` (Story #4539/#4540).
|
|
179
|
-
* Comparison is exact-string, so a Story declaring `.agents/scripts/lib/**`
|
|
180
|
-
* would not match another declaring `.agents/scripts/lib/story-adjacency.js` —
|
|
181
|
-
* the guard would silently pass two Stories that genuinely race. Unknown width
|
|
182
|
-
* is not the same as no width: fail safe by serializing the rest of the beat.
|
|
183
|
-
*
|
|
184
|
-
* That fail-safe is **beat-local and stays that way**. The cross-beat
|
|
185
|
-
* reservation uses {@link reservesConcretePath} instead, because a beat is a
|
|
186
|
-
* moment and an in-flight window is an implementation (Story #4960).
|
|
85
|
+
* Beat-local overlap guard: `true` when two footprints intersect. A glob
|
|
86
|
+
* (unknown width) overlaps everything, since exact-string comparison would
|
|
87
|
+
* otherwise pass two Stories that really race; this fail-safe is beat-local
|
|
88
|
+
* only.
|
|
187
89
|
*
|
|
188
90
|
* @param {StoryRecord} a
|
|
189
91
|
* @param {StoryRecord} b
|
|
@@ -194,30 +96,14 @@ export function storiesOverlap(a, b, options = {}) {
|
|
|
194
96
|
}
|
|
195
97
|
|
|
196
98
|
/**
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* implementation window, not for a moment, so the two guards cannot share a
|
|
202
|
-
* predicate (Story #4960):
|
|
203
|
-
*
|
|
204
|
-
* - A **concrete** shared path is a real, named collision — two branches
|
|
205
|
-
* editing `lib/foo.js` conflict at close whether the peer was admitted
|
|
206
|
-
* alongside or hours ago. It reserves, exactly as Story #4950 shipped.
|
|
207
|
-
* - A **glob** — or the UNKNOWN sentinel `resolve-stories.js` substitutes
|
|
208
|
-
* for an unparseable body — names no file. Reserving on it withheld every
|
|
209
|
-
* eligible Story against a single unknown-width blocker for that blocker's
|
|
210
|
-
* whole window, which is strictly worse than the serial run the
|
|
211
|
-
* reservation was meant to speed up. Glob paths are therefore skipped on
|
|
212
|
-
* both sides here; the beat-local {@link storiesOverlap} fail-safe is
|
|
213
|
-
* unchanged and still serializes them within a beat.
|
|
99
|
+
* Cross-beat reservation guard: collides only on a shared concrete path. An
|
|
100
|
+
* in-flight Story holds its footprint for its whole implementation window, so
|
|
101
|
+
* a glob or the UNKNOWN sentinel (substituted for any unparseable body) must
|
|
102
|
+
* reserve nothing or one bad body would serialize the entire run.
|
|
214
103
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* @param {StoryRecord} held The in-flight Story holding the reservation.
|
|
219
|
-
* @param {StoryRecord} candidate The Story being considered for admission.
|
|
220
|
-
* @param {object} [options] Evidence-scrape options (see {@link storyEvidencePaths}).
|
|
104
|
+
* @param {StoryRecord} held
|
|
105
|
+
* @param {StoryRecord} candidate
|
|
106
|
+
* @param {object} [options]
|
|
221
107
|
* @returns {{ paths: string[], source: string }|null}
|
|
222
108
|
*/
|
|
223
109
|
function reservesConcretePath(held, candidate, options = {}) {
|
|
@@ -225,93 +111,33 @@ function reservesConcretePath(held, candidate, options = {}) {
|
|
|
225
111
|
}
|
|
226
112
|
|
|
227
113
|
/**
|
|
228
|
-
* Select the
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* 1. **Adjacency.** Re-derive `Map<id, depIds[]>` from the supplied
|
|
233
|
-
* records via `buildStoryAdjacency`. The `dropForeign` flag controls
|
|
234
|
-
* how a dependency on an id **outside** the supplied set is treated:
|
|
235
|
-
* - `dropForeign: false` (default, standalone-path semantics) — the
|
|
236
|
-
* foreign dependency still gates the dependent: an absent dependency
|
|
237
|
-
* is treated as not-yet-done and withholds the dependent until it
|
|
238
|
-
* completes (preserves the operator-DAG contract).
|
|
239
|
-
* - `dropForeign: true` (Epic-path semantics) — a foreign edge is
|
|
240
|
-
* pruned so the DAG stays closed over the scheduled Story set. An
|
|
241
|
-
* Epic's Stories depend only on siblings, so a `blocked by #N` whose
|
|
242
|
-
* target is out-of-scope (a foreign id, or a typo) must be dropped,
|
|
243
|
-
* not treated as a permanent unsatisfiable gate — otherwise the
|
|
244
|
-
* dependent Story is never schedulable and the run silently strands
|
|
245
|
-
* it. This matches `build-wave-dag.js`, which builds the Epic
|
|
246
|
-
* wave DAG with the same default-`dropForeign` builder.
|
|
247
|
-
* 2. **Done set.** Union the caller-supplied `doneIds` with every record
|
|
248
|
-
* that classifies as `done` (live label / closed issue). A Story's
|
|
249
|
-
* dependency counts as satisfied iff it is in this union.
|
|
250
|
-
* 3. **Eligibility.** A Story is *eligible* when it classifies as `ready`
|
|
251
|
-
* (not done / blocked / executing) **and** every one of its
|
|
252
|
-
* dependencies is in the done set. This is the no-false-barrier
|
|
253
|
-
* property: C depending only on A is eligible the instant A is done,
|
|
254
|
-
* even while an unrelated B is still pending.
|
|
255
|
-
* 4. **Capacity.** The dispatch set never exceeds `slots = max(0,
|
|
256
|
-
* globalCap − inFlight)`. `inFlight` is the caller's count of Stories
|
|
257
|
-
* already occupying a slot (executing / closing / dispatched-not-yet-
|
|
258
|
-
* labelled). When `slots <= 0`, the result is empty.
|
|
259
|
-
* 5. **Overlap guard.** Greedily admit eligible Stories in ascending-id
|
|
260
|
-
* order, skipping any whose file footprint overlaps a Story **already
|
|
261
|
-
* admitted this beat** ({@link storiesOverlap}) or shares a **concrete**
|
|
262
|
-
* path with a Story **still in flight from an earlier beat**
|
|
263
|
-
* (`inFlightRecords`, {@link reservesConcretePath}). A withheld Story
|
|
264
|
-
* stays eligible and is naturally re-considered on the next beat once
|
|
265
|
-
* the Story reserving its files has cleared.
|
|
266
|
-
*
|
|
267
|
-
* The result is deterministic: eligible Stories are considered in
|
|
268
|
-
* ascending-id order, so the same inputs always yield the same set.
|
|
114
|
+
* Select the Stories safe to dispatch this beat: `ready` Stories whose deps
|
|
115
|
+
* are all done, admitted greedily in ascending-id order (deterministic) up to
|
|
116
|
+
* `globalCap − inFlight`, skipping footprint collisions.
|
|
269
117
|
*
|
|
270
118
|
* @param {object} args
|
|
271
|
-
* @param {StoryRecord[]} args.stories
|
|
272
|
-
* @param {Array<number|string>|Set<number|string>} [args.doneIds]
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* @param {number}
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
* @param {
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* **reserve** rather than merely count. `inFlight` is a number and can only
|
|
286
|
-
* shrink capacity; without the records a Story admitted now can share files
|
|
287
|
-
* with one dispatched on an earlier beat and still implementing — a
|
|
288
|
-
* guaranteed merge conflict at close (Story #4950). A glob / UNKNOWN
|
|
289
|
-
* footprint reserves nothing (Story #4960). Callers that hold only ids (the
|
|
290
|
-
* `--dag`/`--in-flight` flag mode) pass nothing and get the pre-#4950
|
|
291
|
-
* same-beat-only behaviour.
|
|
292
|
-
* @param {'enforce'|'advisory'} [args.footprintGuard='enforce'] Whether a
|
|
293
|
-
* footprint collision **withholds** a Story (`enforce`, the default and
|
|
294
|
-
* today's behaviour) or merely **reports** one while dispatch follows the
|
|
295
|
-
* declared `depends_on` edges alone (`advisory`). Advisory never changes what
|
|
296
|
-
* the guard *detects* — every would-be withhold is still computed and
|
|
297
|
-
* returned in `footprintWithholds` with `enforced: false` — so turning it on
|
|
298
|
-
* trades serialization for throughput without going blind (Story #5044).
|
|
299
|
-
* @param {string} [args.tempRoot] Resolved `project.paths.tempRoot`. Accepted
|
|
300
|
-
* for call-site compatibility; the evidence scrape that read it was retired
|
|
301
|
-
* in Story #5313 and the footprint is the declared `changes[]` alone.
|
|
119
|
+
* @param {StoryRecord[]} args.stories
|
|
120
|
+
* @param {Array<number|string>|Set<number|string>} [args.doneIds] Merged with
|
|
121
|
+
* records that classify as done.
|
|
122
|
+
* @param {number} [args.inFlight=0]
|
|
123
|
+
* @param {number} args.globalCap
|
|
124
|
+
* @param {boolean} [args.dropForeign=false] `false` keeps a dependency on an
|
|
125
|
+
* out-of-set id as a gate (operator DAG); `true` prunes it so an Epic's
|
|
126
|
+
* Story is never stranded by a foreign or mistyped `blocked by`.
|
|
127
|
+
* @param {StoryRecord[]} [args.inFlightRecords=[]] In-flight Stories whose
|
|
128
|
+
* concrete paths are reserved; a bare `inFlight` count only shrinks capacity
|
|
129
|
+
* and cannot prevent a close-time merge conflict.
|
|
130
|
+
* @param {'enforce'|'advisory'} [args.footprintGuard='enforce'] Advisory
|
|
131
|
+
* still records every would-be withhold with `enforced: false`.
|
|
132
|
+
* @param {string} [args.tempRoot] Accepted for call-site compatibility only.
|
|
302
133
|
* @returns {{
|
|
303
134
|
* selected: StoryRecord[],
|
|
304
135
|
* withheldByInFlight: Array<{id: number, blockedBy: number}>,
|
|
305
136
|
* footprintWithholds: Array<{id: number, blockedBy: number, scope: string, source: string, paths: string[], enforced: boolean}>,
|
|
306
137
|
* guardMode: 'enforce'|'advisory'
|
|
307
138
|
* }}
|
|
308
|
-
* `
|
|
309
|
-
*
|
|
310
|
-
* names each eligible Story a reservation held back and the in-flight
|
|
311
|
-
* Story that holds it. `footprintWithholds` is the **complete** ledger —
|
|
312
|
-
* beat-local skips as well as cross-beat reservations, each with the
|
|
313
|
-
* colliding paths and its `declared-overlap` source — so no withheld
|
|
314
|
-
* dispatch is unexplained (Story #5044).
|
|
139
|
+
* `footprintWithholds` is the complete ledger, so no withheld dispatch is
|
|
140
|
+
* unexplained.
|
|
315
141
|
*/
|
|
316
142
|
export function planReadySet({
|
|
317
143
|
stories,
|
|
@@ -341,22 +167,14 @@ export function planReadySet({
|
|
|
341
167
|
};
|
|
342
168
|
}
|
|
343
169
|
|
|
344
|
-
// Step 1 — adjacency keyed by id. The `dropForeign` policy decides whether
|
|
345
|
-
// a dependency on an id outside the supplied set gates the dependent
|
|
346
|
-
// (false) or is pruned (true). See the JSDoc above for the per-path
|
|
347
|
-
// rationale.
|
|
348
170
|
const adjacency = buildStoryAdjacency(records, { dropForeign });
|
|
349
171
|
|
|
350
|
-
// Steps 2 + 3 — who is eligible at all, before any footprint reasoning.
|
|
351
172
|
const { eligibleIds, byId } = resolveEligibility({
|
|
352
173
|
records,
|
|
353
174
|
doneIds,
|
|
354
175
|
adjacency,
|
|
355
176
|
});
|
|
356
177
|
|
|
357
|
-
// Steps 4 + 5 — greedily admit up to `slots`, skipping file-overlap
|
|
358
|
-
// collisions against the already-admitted set AND against the footprints
|
|
359
|
-
// reserved by Stories still in flight from an earlier beat.
|
|
360
178
|
return admitStories({
|
|
361
179
|
eligibleIds,
|
|
362
180
|
byId,
|
|
@@ -368,18 +186,9 @@ export function planReadySet({
|
|
|
368
186
|
}
|
|
369
187
|
|
|
370
188
|
/**
|
|
371
|
-
*
|
|
372
|
-
* `
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
* Separated from {@link planReadySet} because it answers a different question:
|
|
376
|
-
* this is the *declared graph* half of the decision (edges and lifecycle
|
|
377
|
-
* state), while everything after it reasons about footprints. Keeping the two
|
|
378
|
-
* apart is also what holds `planReadySet` under the cyclomatic ceiling ratchet.
|
|
379
|
-
*
|
|
380
|
-
* The done set is the union of two sources: ids the caller resolved from live
|
|
381
|
-
* state, and records in this batch that classify done — a Story can be both,
|
|
382
|
-
* and neither alone is complete.
|
|
189
|
+
* Stories eligible on dependency grounds alone, plus the id→record index. The
|
|
190
|
+
* done set is caller `doneIds` ∪ records classifying done; neither alone is
|
|
191
|
+
* complete.
|
|
383
192
|
*
|
|
384
193
|
* @param {object} args
|
|
385
194
|
* @param {StoryRecord[]} args.records
|
|
@@ -401,7 +210,6 @@ function resolveEligibility({ records, doneIds, adjacency }) {
|
|
|
401
210
|
if (classifyStory(rec) === 'done') done.add(id);
|
|
402
211
|
}
|
|
403
212
|
|
|
404
|
-
// Ascending id for deterministic admission order.
|
|
405
213
|
const eligibleIds = [];
|
|
406
214
|
for (const id of [...byId.keys()].sort((a, b) => a - b)) {
|
|
407
215
|
if (classifyStory(byId.get(id)) !== 'ready') continue;
|
|
@@ -412,30 +220,16 @@ function resolveEligibility({ records, doneIds, adjacency }) {
|
|
|
412
220
|
}
|
|
413
221
|
|
|
414
222
|
/**
|
|
415
|
-
* Greedily admit eligible Stories
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* The two rules are distinct predicates, not one applied twice: the
|
|
419
|
-
* cross-beat reservation matches only a shared **concrete** path
|
|
420
|
-
* ({@link reservesConcretePath}), while the same-beat guard also serializes
|
|
421
|
-
* unknown-width footprints ({@link storiesOverlap}). See both for why.
|
|
422
|
-
*
|
|
423
|
-
* Which of the two a candidate is reported against is {@link blockingCollision}'s
|
|
424
|
-
* decision, not this loop's.
|
|
425
|
-
*
|
|
426
|
-
* Under `footprintGuard: 'advisory'` neither rule withholds: dispatch follows
|
|
427
|
-
* the declared `depends_on` edges alone. Detection is unchanged — every hit is
|
|
428
|
-
* still computed and recorded with `enforced: false` — so advisory mode is a
|
|
429
|
-
* deliberate throughput trade an operator can read the cost of, not a blind
|
|
430
|
-
* spot (Story #5044).
|
|
223
|
+
* Greedily admit eligible Stories; under `advisory` collisions are recorded
|
|
224
|
+
* but never withhold.
|
|
431
225
|
*
|
|
432
226
|
* @param {object} args
|
|
433
|
-
* @param {number[]} args.eligibleIds
|
|
227
|
+
* @param {number[]} args.eligibleIds
|
|
434
228
|
* @param {Map<number, StoryRecord>} args.byId
|
|
435
|
-
* @param {number} args.slots
|
|
436
|
-
* @param {StoryRecord[]} args.reserved
|
|
229
|
+
* @param {number} args.slots
|
|
230
|
+
* @param {StoryRecord[]} args.reserved
|
|
437
231
|
* @param {'enforce'|'advisory'} args.guardMode
|
|
438
|
-
* @param {object} args.evidence
|
|
232
|
+
* @param {object} args.evidence
|
|
439
233
|
* @returns {{ selected: StoryRecord[], withheldByInFlight: Array<{id: number, blockedBy: number}>, footprintWithholds: object[], guardMode: string }}
|
|
440
234
|
*/
|
|
441
235
|
function admitStories({
|
|
@@ -459,9 +253,7 @@ function admitStories({
|
|
|
459
253
|
}
|
|
460
254
|
return {
|
|
461
255
|
selected,
|
|
462
|
-
//
|
|
463
|
-
// shape: it is `stories-wave-tick.js`'s long-standing reservation input and
|
|
464
|
-
// narrowing the scrape must not reshape it.
|
|
256
|
+
// Shape `{ id, blockedBy }` is `stories-wave-tick.js`'s reservation input.
|
|
465
257
|
withheldByInFlight: footprintWithholds
|
|
466
258
|
.filter((w) => w.enforced && w.scope === WITHHOLD_SCOPES.IN_FLIGHT)
|
|
467
259
|
.map(({ id, blockedBy }) => ({ id, blockedBy })),
|
|
@@ -471,20 +263,15 @@ function admitStories({
|
|
|
471
263
|
}
|
|
472
264
|
|
|
473
265
|
/**
|
|
474
|
-
* The
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
* in-flight Story and a same-beat peer is reported against the in-flight one:
|
|
478
|
-
* that is the longer-lived and more informative blocker (a Story that has been
|
|
479
|
-
* implementing for beats, not one merely admitted a moment ago), and checking it
|
|
480
|
-
* first is what makes the reservation report complete. Order cannot change
|
|
481
|
-
* `selected` — a candidate either rule rejects is skipped whichever runs first.
|
|
266
|
+
* The collision withholding this candidate, or `null`. In-flight is checked
|
|
267
|
+
* first so it is reported as the longer-lived blocker; order cannot change
|
|
268
|
+
* `selected`.
|
|
482
269
|
*
|
|
483
270
|
* @param {object} args
|
|
484
271
|
* @param {StoryRecord} args.rec
|
|
485
272
|
* @param {number} args.id
|
|
486
|
-
* @param {StoryRecord[]} args.selected
|
|
487
|
-
* @param {StoryRecord[]} args.reserved
|
|
273
|
+
* @param {StoryRecord[]} args.selected
|
|
274
|
+
* @param {StoryRecord[]} args.reserved
|
|
488
275
|
* @param {object} args.evidence
|
|
489
276
|
* @returns {{ blockedBy: number, scope: string, paths: string[], source: string }|null}
|
|
490
277
|
*/
|
|
@@ -496,17 +283,11 @@ function blockingCollision({ rec, id, selected, reserved, evidence }) {
|
|
|
496
283
|
}
|
|
497
284
|
|
|
498
285
|
/**
|
|
499
|
-
* The
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
* Until Story #5044 this was an anonymous `continue`: the candidate was
|
|
503
|
-
* silently dropped from the beat and nothing in any envelope said why. An
|
|
504
|
-
* unfilled slot with no explanation is indistinguishable from a cap that was
|
|
505
|
-
* simply not reached, which is what let a footprint-widening artifact
|
|
506
|
-
* serialize a whole audit-derived plan without leaving a trace to notice.
|
|
286
|
+
* The same-beat peer this candidate would race, with the colliding paths, so
|
|
287
|
+
* an unfilled slot is never unexplained.
|
|
507
288
|
*
|
|
508
289
|
* @param {StoryRecord} candidate
|
|
509
|
-
* @param {StoryRecord[]} selected
|
|
290
|
+
* @param {StoryRecord[]} selected
|
|
510
291
|
* @param {object} [options]
|
|
511
292
|
* @returns {{ blockedBy: number, paths: string[], source: string }|null}
|
|
512
293
|
*/
|
|
@@ -519,19 +300,9 @@ function findBeatBlocker(candidate, selected, options = {}) {
|
|
|
519
300
|
}
|
|
520
301
|
|
|
521
302
|
/**
|
|
522
|
-
* The
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* Two records are skipped rather than treated as blockers:
|
|
526
|
-
*
|
|
527
|
-
* - **The candidate itself.** Probe mode hands the whole record set to both
|
|
528
|
-
* arguments, and an in-flight Story classifies `executing` rather than
|
|
529
|
-
* `ready`, so a candidate can never legitimately appear here — but a
|
|
530
|
-
* caller that double-lists one Story must not have it withhold itself.
|
|
531
|
-
* - **An unidentifiable record.** A withholding this function cannot name
|
|
532
|
-
* is one the envelope cannot explain, and an unexplained unfilled slot is
|
|
533
|
-
* the exact operator-facing failure this reservation exists to remove.
|
|
534
|
-
* Probe-mode records always carry an integer id, so this is defensive.
|
|
303
|
+
* The in-flight Story reserving a concrete path the candidate would race.
|
|
304
|
+
* Skips the candidate itself (a double-listed Story must not withhold itself)
|
|
305
|
+
* and id-less records (a withhold that cannot be named cannot be explained).
|
|
535
306
|
*
|
|
536
307
|
* @param {StoryRecord} candidate
|
|
537
308
|
* @param {number} candidateId
|
|
@@ -1,32 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `workerData`: `{}` — coverage is no longer cloned into workers at spawn.
|
|
8
|
-
* Instead, the host resolves each file's coverage entry via `findCoverageEntry`
|
|
9
|
-
* before dispatch and attaches it as `item.coverageEntry`. Workers receive
|
|
10
|
-
* only their file's entry, removing the O(workers × coverageMapSize) clone.
|
|
11
|
-
*
|
|
12
|
-
* Message contract — see lib/cpu-pool.js:
|
|
13
|
-
* IN : { item: { abs: string, relPath: string, requireCoverage: boolean,
|
|
14
|
-
* coverageAvailable?: boolean, coverageEntry: object | null } }
|
|
15
|
-
* { exit: true }
|
|
16
|
-
* OUT : { ok: true, result: {
|
|
17
|
-
* relPath,
|
|
18
|
-
* skippedFileNoCoverage: boolean,
|
|
19
|
-
* rows: Array<{ method, startLine, cyclomatic, coverage, crap }>,
|
|
20
|
-
* skippedMethodsNoCoverage: number,
|
|
21
|
-
* hasCoverageEntry: boolean,
|
|
22
|
-
* resolvedMethods: number,
|
|
23
|
-
* totalMethods: number,
|
|
24
|
-
* } }
|
|
25
|
-
*
|
|
26
|
-
* A truly unrecoverable per-file failure (read error, transpile null, or a
|
|
27
|
-
* source the kernel cannot parse) surfaces as
|
|
28
|
-
* `{ ok: true, result: { relPath, rows: null, ... } }` so the host loop drops
|
|
29
|
-
* the file and increments its own counter — never aborts the whole scan.
|
|
2
|
+
* CPU-pool worker for `scanAndScore`: one file in, its per-method CRAP rows
|
|
3
|
+
* out. The host pre-resolves each file's coverage entry (`item.coverageEntry`)
|
|
4
|
+
* so the coverage map is never cloned per worker. An unrecoverable per-file
|
|
5
|
+
* failure replies `rows: null`, which the host drops and counts.
|
|
30
6
|
*/
|
|
31
7
|
|
|
32
8
|
import { parentPort } from 'node:worker_threads';
|
|
@@ -39,24 +15,7 @@ import { prepareSourceForScoring } from '../transpile.js';
|
|
|
39
15
|
import { serveWorkerMessages } from './serve-worker-messages.js';
|
|
40
16
|
|
|
41
17
|
/**
|
|
42
|
-
* Pure handler for
|
|
43
|
-
* tests can exercise every branch (bad-shape rejection, missing
|
|
44
|
-
* coverage, fs/transpile/escomplex failures, success rows, skipped
|
|
45
|
-
* methods) without spawning a real `Worker` thread.
|
|
46
|
-
*
|
|
47
|
-
* Returns one of:
|
|
48
|
-
* - `{ kind: 'exit' }` — caller should close the port.
|
|
49
|
-
* - `{ kind: 'reply', message }` — caller should `postMessage(message)`.
|
|
50
|
-
*
|
|
51
|
-
* Side effects (fs, transpile, escomplex) are wired through `deps` so
|
|
52
|
-
* tests pass deterministic stubs. `readFile` / `transpile` are forwarded to
|
|
53
|
-
* `prepareSourceForScoring`, which also derives the transpiled →
|
|
54
|
-
* original-source line map the coverage join needs (Story #4775); a
|
|
55
|
-
* `transpile` stub that still returns a bare string is tolerated.
|
|
56
|
-
*
|
|
57
|
-
* Coverage is supplied via `item.coverageEntry` (pre-resolved on the host),
|
|
58
|
-
* not via a whole-map `coverage` argument. The second parameter is kept as
|
|
59
|
-
* `_coverage` for backward-compatibility but is intentionally unused.
|
|
18
|
+
* Pure handler for one worker message (testable without a `Worker`).
|
|
60
19
|
*
|
|
61
20
|
* @param {unknown} msg
|
|
62
21
|
* @param {object|null} _coverage - Unused. Coverage is in `item.coverageEntry`.
|
|
@@ -87,15 +46,10 @@ export function handleCrapWorkerMessage(msg, _coverage, deps = {}) {
|
|
|
87
46
|
}
|
|
88
47
|
const { abs, relPath, requireCoverage, coverageAvailable = true } = item;
|
|
89
48
|
|
|
90
|
-
// Coverage entry is pre-resolved on the host and attached to the item.
|
|
91
|
-
// `item.coverageEntry` may be explicitly `null` when the file has no
|
|
92
|
-
// coverage, or `undefined` when the caller did not supply it (treat as null).
|
|
93
49
|
const entry = item.coverageEntry ?? null;
|
|
94
50
|
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
// result fields out per branch is what let the drop shape and the success
|
|
98
|
-
// shape drift apart in the first place.
|
|
51
|
+
// One envelope for every non-error outcome, so drop and success shapes
|
|
52
|
+
// cannot drift.
|
|
99
53
|
const reply = (result) => ({
|
|
100
54
|
kind: 'reply',
|
|
101
55
|
message: {
|
|
@@ -119,11 +73,8 @@ export function handleCrapWorkerMessage(msg, _coverage, deps = {}) {
|
|
|
119
73
|
|
|
120
74
|
const dropped = (error) => reply(error ? { error } : {});
|
|
121
75
|
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
// keys on the .ts file, not transpiled output) and the per-method join
|
|
125
|
-
// below uses ORIGINAL source *lines*, remapped from escomplex's transpiled
|
|
126
|
-
// coordinates via `prepared.mapLine` (Story #4775).
|
|
76
|
+
// Coverage keys on original source lines; `prepared.mapLine` remaps
|
|
77
|
+
// escomplex's transpiled coordinates to them.
|
|
127
78
|
const prepare = deps.prepare ?? prepareSourceForScoring;
|
|
128
79
|
const prepared = prepare(abs, deps);
|
|
129
80
|
if (prepared.error) return dropped(null);
|
|
@@ -140,12 +91,8 @@ export function handleCrapWorkerMessage(msg, _coverage, deps = {}) {
|
|
|
140
91
|
err && typeof err.message === 'string' ? err.message : String(err),
|
|
141
92
|
);
|
|
142
93
|
}
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
// unreachable for the whole parse-failure class: the file reached the host
|
|
146
|
-
// as a successfully-scored file with no methods, and its baseline rows
|
|
147
|
-
// vanished without a counter moving. `rows: null` is the serial path's
|
|
148
|
-
// `parseError` verdict in the shape the host loop already drops on.
|
|
94
|
+
// Unparseable must drop (`rows: null`), not read as a file with no methods,
|
|
95
|
+
// or its baseline rows vanish uncounted.
|
|
149
96
|
if (methodRows === UNSCORABLE) return dropped(null);
|
|
150
97
|
|
|
151
98
|
return reply(
|