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,22 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/findings/provenance-field.js — the per-Story `provenance`
|
|
3
|
-
*
|
|
4
|
-
* An audit-seeded plan carries dedup identities forward so the next sweep
|
|
5
|
-
* recognises what it already planned. The optional top-level `provenance`
|
|
6
|
-
* field on a `stories.json` entry says **which of them that Story owns**:
|
|
7
|
-
*
|
|
8
|
-
* ```jsonc
|
|
9
|
-
* { "fingerprints": ["<40-char sha1>"], "semanticKeys": ["architecture␟lib/a.js"] }
|
|
10
|
-
* ```
|
|
11
|
-
*
|
|
12
|
-
* Two callers, deliberately split from
|
|
13
|
-
* [`route-finding.js`](route-finding.js): the ticket validator shape-checks
|
|
14
|
-
* the authored field, and plan-persist's assembly renders the owned identities
|
|
15
|
-
* into the footer source it stamps. Neither is dedup *routing*, which is what
|
|
16
|
-
* `route-finding.js` is for — this module reads its identity vocabulary
|
|
17
|
-
* (`SHA1_RE`, `SEMANTIC_KEY_RE`, and the two footer renderers) from there so
|
|
18
|
-
* there is exactly one definition of what a fingerprint or a semantic key
|
|
19
|
-
* looks like.
|
|
2
|
+
* lib/findings/provenance-field.js — the optional per-Story `provenance`
|
|
3
|
+
* field naming the audit identities that Story owns.
|
|
20
4
|
*
|
|
21
5
|
* @module lib/findings/provenance-field
|
|
22
6
|
*/
|
|
@@ -28,10 +12,8 @@ import {
|
|
|
28
12
|
semanticKeyFooter,
|
|
29
13
|
} from './route-finding.js';
|
|
30
14
|
|
|
31
|
-
/** Human-readable rendering of the `provenance` field's two lists. */
|
|
32
15
|
const PROVENANCE_SHAPE = 'fingerprints[] / semanticKeys[]';
|
|
33
16
|
|
|
34
|
-
/** What each `provenance` list accepts, and how to say so when it does not. */
|
|
35
17
|
const PROVENANCE_FIELDS = Object.freeze({
|
|
36
18
|
fingerprints: { pattern: SHA1_RE, expected: 'a 40-char sha1 hex string' },
|
|
37
19
|
semanticKeys: {
|
|
@@ -41,8 +23,6 @@ const PROVENANCE_FIELDS = Object.freeze({
|
|
|
41
23
|
});
|
|
42
24
|
|
|
43
25
|
/**
|
|
44
|
-
* Validate one authored `provenance` list into its normalized form.
|
|
45
|
-
*
|
|
46
26
|
* @param {unknown} list
|
|
47
27
|
* @param {{ where: string, field: string, pattern: RegExp, expected: string }} spec
|
|
48
28
|
* @returns {string[]} Trimmed, de-duplicated, first-seen order.
|
|
@@ -66,25 +46,13 @@ function normalizeList(list, { where, field, pattern, expected }) {
|
|
|
66
46
|
}
|
|
67
47
|
|
|
68
48
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* `null`, which is the caller's signal to fall back to the whole-seed union
|
|
74
|
-
* carry. That fallback is not vestigial — leaving the authoring agent to
|
|
75
|
-
* hand-carry provenance out of the seed's HTML comments was measured to fail,
|
|
76
|
-
* and the mechanical union is what closed it. Attribution is **additive**: a
|
|
77
|
-
* plan that attributes gets exact stamping, a plan that does not keeps recall.
|
|
78
|
-
*
|
|
79
|
-
* An empty object is therefore *not* the same as an absent field: it means
|
|
80
|
-
* "this Story owns nothing", and stamps nothing.
|
|
81
|
-
*
|
|
82
|
-
* Present-but-malformed is a hard error rather than a silent drop, because a
|
|
83
|
-
* dropped identity is invisible until the next sweep re-files work that was
|
|
84
|
-
* already planned.
|
|
49
|
+
* Absent → `null`: the caller falls back to carrying the whole seed's union
|
|
50
|
+
* (hand-carrying was measured to fail). An empty object means "owns nothing"
|
|
51
|
+
* and stamps nothing. Malformed throws — a dropped identity is invisible until
|
|
52
|
+
* the next sweep re-files planned work.
|
|
85
53
|
*
|
|
86
54
|
* @param {unknown} raw
|
|
87
|
-
* @param {string} [label]
|
|
55
|
+
* @param {string} [label]
|
|
88
56
|
* @returns {{ fingerprints: string[], semanticKeys: string[] }|null}
|
|
89
57
|
* @throws {Error} On any shape the stamper cannot honour exactly.
|
|
90
58
|
*/
|
|
@@ -108,19 +76,10 @@ export function normalizeOwnedProvenance(raw, label = 'story') {
|
|
|
108
76
|
}
|
|
109
77
|
|
|
110
78
|
/**
|
|
111
|
-
* Render
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* union-preserving and idempotent for an attributed plan exactly as it is for
|
|
116
|
-
* an un-attributed one.
|
|
117
|
-
*
|
|
118
|
-
* An empty (or absent) set renders the empty string, which the carry treats as
|
|
119
|
-
* nothing-to-do — so a Story that owns no findings is stamped with none rather
|
|
120
|
-
* than inheriting its siblings'.
|
|
121
|
-
*
|
|
122
|
-
* Expects the normalized shape {@link normalizeOwnedProvenance} returns; the
|
|
123
|
-
* validator runs first on every production path.
|
|
79
|
+
* Render owned identities in the same footer vocabulary
|
|
80
|
+
* `carryProvenanceFooters` harvests, so attribution changes which identities
|
|
81
|
+
* are stamped, never how. An empty set renders `''` (nothing inherited from
|
|
82
|
+
* siblings). Expects {@link normalizeOwnedProvenance}'s shape.
|
|
124
83
|
*
|
|
125
84
|
* @param {{ fingerprints?: string[], semanticKeys?: string[] }|null} [provenance]
|
|
126
85
|
* @returns {string}
|
|
@@ -1,32 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/findings/route-finding.js —
|
|
3
|
-
*
|
|
4
|
-
* This module is the single dedup/route implementation that both
|
|
5
|
-
* `audit-to-stories` and `qa-explore` consume. It does three things:
|
|
6
|
-
*
|
|
7
|
-
* 1. `fingerprintFinding(finding)` — a stable sha1 over the finding's
|
|
8
|
-
* identity fields (`title`, `area`, `primaryFile`, `severity`,
|
|
9
|
-
* `labels`). Two runs over the same finding MUST produce the same
|
|
10
|
-
* sha, and unrelated prose drift MUST NOT change it.
|
|
11
|
-
* 2. `fingerprintFooter(sha)` / `parseFingerprintFooter(body)` — round-trip
|
|
12
|
-
* the machine-readable `<!-- audit-fingerprints: sha,sha,... -->` marker
|
|
13
|
-
* stamped into Issue bodies.
|
|
14
|
-
* 3. `routeFinding(finding, { searchIssues, searchCandidates })` — classify a
|
|
15
|
-
* finding against existing Issues into one of `new | update-existing |
|
|
16
|
-
* duplicate | regression-of-closed`. Routing gathers a candidate pool,
|
|
17
|
-
* then confirms identity against it. **Every wired port runs, and their
|
|
18
|
-
* results union** (Story #5079): the exact `searchIssues(sha)` lookup is
|
|
19
|
-
* what reliably retrieves an Issue by its footer sha, while the
|
|
20
|
-
* meaning-first `searchCandidates` pass (wired to
|
|
21
|
-
* `semantic-issue-search.js`) widens that pool to catch a reworded
|
|
22
|
-
* finding whose sha has drifted. The semantic pass **adds** to the
|
|
23
|
-
* fingerprint lookup; it never replaces it. Whichever ports are wired
|
|
24
|
-
* query BOTH open and closed issues; a closed fingerprint match yields
|
|
25
|
-
* `regression-of-closed`.
|
|
26
|
-
*
|
|
27
|
-
* Pure orchestration: no network I/O lives here. The `searchIssues` /
|
|
28
|
-
* `searchCandidates` ports are injected by the caller (production wires them
|
|
29
|
-
* to the GitHub provider; tests pass an in-memory stub).
|
|
2
|
+
* lib/findings/route-finding.js — the one dedup/route implementation: finding
|
|
3
|
+
* fingerprints, Issue-body footers, and `routeFinding`. Ports are injected.
|
|
30
4
|
*/
|
|
31
5
|
|
|
32
6
|
import crypto from 'node:crypto';
|
|
@@ -38,13 +12,10 @@ const MARKER = 'audit-fingerprints:';
|
|
|
38
12
|
const SEMANTIC_MARKER = 'audit-semantic-keys:';
|
|
39
13
|
const LABEL_MARKER = 'audit-labels:';
|
|
40
14
|
export const SHA1_RE = /^[0-9a-f]{40}$/;
|
|
41
|
-
//
|
|
42
|
-
// carry a comma or a `>` (which would truncate the HTML comment). Both are
|
|
43
|
-
// stripped when the key is built, so this guard is defence-in-depth.
|
|
15
|
+
// No `,` or `>`: keys round-trip through a comma-joined HTML-comment footer.
|
|
44
16
|
export const SEMANTIC_KEY_RE = /^[^,>]+$/;
|
|
45
17
|
|
|
46
18
|
/**
|
|
47
|
-
* Normalise a single scalar identity field to a stable string.
|
|
48
19
|
* @param {unknown} value
|
|
49
20
|
* @returns {string}
|
|
50
21
|
*/
|
|
@@ -54,7 +25,6 @@ function normaliseField(value) {
|
|
|
54
25
|
}
|
|
55
26
|
|
|
56
27
|
/**
|
|
57
|
-
* Normalise the `labels` array into a stable, order-independent string.
|
|
58
28
|
* @param {unknown} labels
|
|
59
29
|
* @returns {string}
|
|
60
30
|
*/
|
|
@@ -68,20 +38,8 @@ function normaliseLabels(labels) {
|
|
|
68
38
|
}
|
|
69
39
|
|
|
70
40
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* **Severity is projected, not raw (Story #4877).** The severity vocabulary was
|
|
74
|
-
* normalised onto the canonical five-level scale in the same change that wrote
|
|
75
|
-
* this comment, and severity is an identity field — so a naive
|
|
76
|
-
* `normaliseField(finding.severity)` here would have re-minted the fingerprint
|
|
77
|
-
* of every finding whose spelling the normalisation touched, silently breaking
|
|
78
|
-
* dedup against every Issue already filed. {@link fingerprintSeverity} is the
|
|
79
|
-
* projection that makes the hash **invariant** under that normalisation: it
|
|
80
|
-
* resolves aliases onto their canonical level, keeps an absent severity as the
|
|
81
|
-
* empty string (what the raw call produced), and passes an unrecognised value
|
|
82
|
-
* through verbatim. Labels are deliberately left on the raw
|
|
83
|
-
* lower-case/trim/sort path for the same reason — order- and case-insensitive
|
|
84
|
-
* already, and any further folding would move existing shas.
|
|
41
|
+
* Any change to this folding moves existing shas and breaks dedup against
|
|
42
|
+
* filed Issues.
|
|
85
43
|
*
|
|
86
44
|
* @param {object} finding
|
|
87
45
|
* @returns {{ title: string, area: string, primaryFile: string, severity: string, labels: string }}
|
|
@@ -97,8 +55,6 @@ function fingerprintComponents(finding) {
|
|
|
97
55
|
}
|
|
98
56
|
|
|
99
57
|
/**
|
|
100
|
-
* Stable per-finding fingerprint over {title, area, primaryFile, severity, labels}.
|
|
101
|
-
*
|
|
102
58
|
* @param {object} finding
|
|
103
59
|
* @returns {{ short: string, full: string, components: object }}
|
|
104
60
|
*/
|
|
@@ -116,20 +72,10 @@ export function fingerprintFinding(finding) {
|
|
|
116
72
|
}
|
|
117
73
|
|
|
118
74
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* sha), the semantic key is stable across a reworded title and a re-severitied
|
|
122
|
-
* finding: it is derived solely from the finding's identity *location* —
|
|
123
|
-
* `area` (the audit dimension) plus `primaryFile`. Two scans that describe the
|
|
124
|
-
* same problem at the same location produce the same semantic key even when
|
|
125
|
-
* their titles diverge, so a reworded finding still confirms against the Issue
|
|
126
|
-
* that already tracks that location.
|
|
75
|
+
* Location key (`area` + `primaryFile`), stable across rewording. Empty when
|
|
76
|
+
* the location is unknown; an empty key never confirms a match.
|
|
127
77
|
*
|
|
128
|
-
*
|
|
129
|
-
* `primaryFile`) — an empty key never confirms a match, exactly as an absent
|
|
130
|
-
* fingerprint footer never does.
|
|
131
|
-
*
|
|
132
|
-
* @param {object} finding — canonical finding ({ area, primaryFile, ... }).
|
|
78
|
+
* @param {object} finding
|
|
133
79
|
* @returns {string}
|
|
134
80
|
*/
|
|
135
81
|
export function semanticKeyFor(finding) {
|
|
@@ -141,13 +87,7 @@ export function semanticKeyFor(finding) {
|
|
|
141
87
|
}
|
|
142
88
|
|
|
143
89
|
/**
|
|
144
|
-
*
|
|
145
|
-
* (`<!-- audit-semantic-keys: key,key,... -->`). Stamped alongside the
|
|
146
|
-
* fingerprint footer by the audit filers so a later reworded finding can
|
|
147
|
-
* confirm identity by location when its fingerprint has drifted. Round-trips
|
|
148
|
-
* through {@link parseSemanticKeyFooter}. Empty keys are dropped.
|
|
149
|
-
*
|
|
150
|
-
* @param {string | string[]} keys — one semantic key or an array of them.
|
|
90
|
+
* @param {string | string[]} keys
|
|
151
91
|
* @returns {string}
|
|
152
92
|
*/
|
|
153
93
|
export function semanticKeyFooter(keys) {
|
|
@@ -159,12 +99,6 @@ export function semanticKeyFooter(keys) {
|
|
|
159
99
|
}
|
|
160
100
|
|
|
161
101
|
/**
|
|
162
|
-
* Extract semantic keys from an Issue body carrying the semantic-key footer.
|
|
163
|
-
* The audit filers stamp the footer via {@link semanticKeyFooter}; the
|
|
164
|
-
* confirmation path here, {@link carryProvenanceFooters} and the audit dedup's
|
|
165
|
-
* local issue index read it back. Exported alongside its writer so an indexer
|
|
166
|
-
* cannot drift into a second parse of the same footer.
|
|
167
|
-
*
|
|
168
102
|
* @param {string} body
|
|
169
103
|
* @returns {string[]}
|
|
170
104
|
*/
|
|
@@ -177,15 +111,8 @@ export function parseSemanticKeyFooter(body) {
|
|
|
177
111
|
}
|
|
178
112
|
|
|
179
113
|
/**
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* The dedup corpus is listed by `audit::*` label, so a Story carrying none is
|
|
184
|
-
* absent from the pool an indexed run matches against — and with an index in
|
|
185
|
-
* play the exact lookup is answered locally and never reaches the provider, so
|
|
186
|
-
* a fingerprint footer alone cannot rescue it. Carrying the labels through the
|
|
187
|
-
* seed is what lets the planning path stamp them without the authoring agent
|
|
188
|
-
* being asked to notice them (Story #5307).
|
|
114
|
+
* The dedup corpus is listed by `audit::*` label; this footer lets planning
|
|
115
|
+
* stamp them so the Story stays visible to indexed dedup.
|
|
189
116
|
*
|
|
190
117
|
* @param {string | string[]} labels
|
|
191
118
|
* @returns {string}
|
|
@@ -200,8 +127,6 @@ export function auditLabelFooter(labels) {
|
|
|
200
127
|
}
|
|
201
128
|
|
|
202
129
|
/**
|
|
203
|
-
* Read every `audit-labels` footer out of a body, de-duplicated.
|
|
204
|
-
*
|
|
205
130
|
* @param {string} body
|
|
206
131
|
* @returns {string[]}
|
|
207
132
|
*/
|
|
@@ -214,16 +139,7 @@ export function parseAuditLabelFooter(body) {
|
|
|
214
139
|
}
|
|
215
140
|
|
|
216
141
|
/**
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
* Accepts either a single 40-char sha1 or an array of them, so a footer
|
|
220
|
-
* can carry every finding sha that a grouped Issue tracks
|
|
221
|
-
* (`<!-- audit-fingerprints: sha,sha,... -->`). The comma-joined form
|
|
222
|
-
* round-trips through {@link parseFingerprintFooter}. This is the single
|
|
223
|
-
* footer renderer shared by `audit-to-stories` and `qa-explore`; neither
|
|
224
|
-
* consumer defines its own marker.
|
|
225
|
-
*
|
|
226
|
-
* @param {string | string[]} shas — full 40-char sha1, or an array of them.
|
|
142
|
+
* @param {string | string[]} shas
|
|
227
143
|
* @returns {string}
|
|
228
144
|
*/
|
|
229
145
|
export function fingerprintFooter(shas) {
|
|
@@ -239,8 +155,6 @@ export function fingerprintFooter(shas) {
|
|
|
239
155
|
}
|
|
240
156
|
|
|
241
157
|
/**
|
|
242
|
-
* Extract fingerprint sha1s from an Issue body carrying the footer marker.
|
|
243
|
-
*
|
|
244
158
|
* @param {string} body
|
|
245
159
|
* @returns {string[]}
|
|
246
160
|
*/
|
|
@@ -253,20 +167,11 @@ export function parseFingerprintFooter(body) {
|
|
|
253
167
|
}
|
|
254
168
|
|
|
255
169
|
/**
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* Scanning every occurrence rather than only the first matters for the
|
|
260
|
-
* provenance carry (Story #4877): the audit Single-plan seed stamps one footer
|
|
261
|
-
* pair per MVP Scope bullet, so a multi-group seed carries several. A
|
|
262
|
-
* first-match-only parse silently dropped every group but the first, which
|
|
263
|
-
* would have made the carry look wired while leaking most of the provenance.
|
|
264
|
-
* Reading all footers is also strictly more correct for issue-body confirmation
|
|
265
|
-
* — a body that accumulated two footer lines confirms against either.
|
|
170
|
+
* Values from every occurrence of a footer (a multi-group seed carries
|
|
171
|
+
* several), de-duplicated.
|
|
266
172
|
*
|
|
267
173
|
* @param {unknown} text
|
|
268
|
-
* @param {RegExp} pattern —
|
|
269
|
-
* comma-separated value list.
|
|
174
|
+
* @param {RegExp} pattern — global; capture group 1 is the value list.
|
|
270
175
|
* @param {(value: string) => boolean} isValid
|
|
271
176
|
* @returns {string[]}
|
|
272
177
|
*/
|
|
@@ -286,34 +191,12 @@ function parseAllFooterValues(text, pattern, isValid) {
|
|
|
286
191
|
}
|
|
287
192
|
|
|
288
193
|
/**
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* The audit sweep's Single-plan path emits a `/mandrel-plan` seed whose MVP Scope
|
|
293
|
-
* bullets already carry the `audit-fingerprints` / `audit-semantic-keys`
|
|
294
|
-
* footers (Story #4626). Nothing then copied them into the Story `/mandrel-plan`
|
|
295
|
-
* actually persisted, so the recommended path filed Stories that the next
|
|
296
|
-
* sweep could not recognise and re-filed as new. It was left to the authoring
|
|
297
|
-
* agent to notice HTML comments in a one-pager and hand-carry them — a
|
|
298
|
-
* remembered step, which is to say no step at all.
|
|
299
|
-
*
|
|
300
|
-
* This is that carry, as a function: harvest both footers out of `from`, and
|
|
301
|
-
* append whichever provenance `into` is missing. It is deliberately:
|
|
194
|
+
* Append the seed's provenance footers missing from `into`, so the next
|
|
195
|
+
* sweep recognises the Story. Additive and idempotent.
|
|
302
196
|
*
|
|
303
|
-
*
|
|
304
|
-
* and a footer `into` already carries is left exactly as authored.
|
|
305
|
-
* - **Union-preserving.** When both sides carry footers the result carries the
|
|
306
|
-
* union, so a hand-authored fingerprint is not dropped in favour of the seed's.
|
|
307
|
-
* - **Idempotent.** Re-running over its own output is a no-op, so a resumed
|
|
308
|
-
* persist cannot stack footers.
|
|
309
|
-
* - **Silent on nothing-to-do.** No provenance in `from` returns `into`
|
|
310
|
-
* unchanged with `carried: false`, so a non-audit plan run is untouched.
|
|
311
|
-
*
|
|
312
|
-
* @param {{ from?: string, into?: string }} args — `from` is the provenance
|
|
313
|
-
* source (the seed markdown); `into` is the body being persisted.
|
|
197
|
+
* @param {{ from?: string, into?: string }} args
|
|
314
198
|
* @returns {{ body: string, carried: boolean, fingerprints: string[], semanticKeys: string[] }}
|
|
315
|
-
*
|
|
316
|
-
* newly carried (empty when there was nothing to carry).
|
|
199
|
+
* The arrays hold only newly carried values.
|
|
317
200
|
*/
|
|
318
201
|
export function carryProvenanceFooters({ from = '', into = '' } = {}) {
|
|
319
202
|
const body = typeof into === 'string' ? into : '';
|
|
@@ -346,9 +229,8 @@ export function carryProvenanceFooters({ from = '', into = '' } = {}) {
|
|
|
346
229
|
}
|
|
347
230
|
|
|
348
231
|
/**
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
* prose rather than in the fingerprint footer).
|
|
232
|
+
* Rejects a hit that mentions the sha only in prose; a body-less issue is
|
|
233
|
+
* trusted.
|
|
352
234
|
*
|
|
353
235
|
* @param {{ body?: string }} issue
|
|
354
236
|
* @param {string} sha
|
|
@@ -360,10 +242,7 @@ function issueCarriesFingerprint(issue, sha) {
|
|
|
360
242
|
}
|
|
361
243
|
|
|
362
244
|
/**
|
|
363
|
-
*
|
|
364
|
-
* {@link issueCarriesFingerprint}, this is strict on a missing body — a
|
|
365
|
-
* location match is only meaningful when the issue actually carries a
|
|
366
|
-
* semantic-key footer to compare against.
|
|
245
|
+
* Strict on a missing body: a location match needs a footer to compare.
|
|
367
246
|
*
|
|
368
247
|
* @param {{ body?: string }} issue
|
|
369
248
|
* @param {string} key
|
|
@@ -375,7 +254,6 @@ function issueCarriesSemanticKey(issue, key) {
|
|
|
375
254
|
}
|
|
376
255
|
|
|
377
256
|
/**
|
|
378
|
-
* Decide the route decision from a confirmed matched issue's state.
|
|
379
257
|
* @param {{ state?: string }} issue
|
|
380
258
|
* @returns {'update-existing'|'regression-of-closed'}
|
|
381
259
|
*/
|
|
@@ -385,23 +263,8 @@ function decisionForIssue(issue) {
|
|
|
385
263
|
}
|
|
386
264
|
|
|
387
265
|
/**
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
* Confirmation admits two different strengths of claim, and collapsing them
|
|
392
|
-
* was the source of two wrong routes:
|
|
393
|
-
*
|
|
394
|
-
* - An issue carrying the finding's exact **fingerprint** owns it. That is
|
|
395
|
-
* identity: this issue tracks *this* finding.
|
|
396
|
-
* - An issue matching only on the location-based **semantic key** is merely
|
|
397
|
-
* adjacent: it tracks *a* finding at the same `area␟primaryFile`.
|
|
398
|
-
*
|
|
399
|
-
* Owners win outright when any exist. Location-only matches are not discarded
|
|
400
|
-
* — they are the whole point of the semantic key and remain the pool when
|
|
401
|
-
* nothing carries the fingerprint (a reworded finding at an unchanged
|
|
402
|
-
* location). The pool is sorted by issue number so a genuine tie resolves to
|
|
403
|
-
* the earliest-filed issue rather than to whatever order the search port
|
|
404
|
-
* happened to return.
|
|
266
|
+
* Fingerprint owners win outright over location-only neighbours. Sorted so a
|
|
267
|
+
* tie resolves to the earliest-filed issue, not search order.
|
|
405
268
|
*
|
|
406
269
|
* @param {Array<{ number: number, state: string, body?: string }>} confirmed
|
|
407
270
|
* @param {string} sha
|
|
@@ -415,28 +278,8 @@ function attributedPool(confirmed, sha) {
|
|
|
415
278
|
}
|
|
416
279
|
|
|
417
280
|
/**
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* Shared by both the semantic-first and fingerprint-only code paths so the
|
|
421
|
-
* decision enum is identical regardless of how candidates were gathered.
|
|
422
|
-
*
|
|
423
|
-
* **Attribution decides, not array order (Story #5045).** The pool used to be
|
|
424
|
-
* read flat, which produced two wrong answers whenever more than one issue
|
|
425
|
-
* confirmed:
|
|
426
|
-
*
|
|
427
|
-
* 1. Two open matches routed `duplicate` pinned to `open[0]` — whichever
|
|
428
|
-
* issue the search port happened to return first. With per-Story
|
|
429
|
-
* provenance that pick is answerable rather than arbitrary: the issue
|
|
430
|
-
* carrying the finding's own fingerprint owns it, and a sibling matching
|
|
431
|
-
* only by location does not.
|
|
432
|
-
* 2. Any open match at all masked a closed one, so a finding whose
|
|
433
|
-
* fingerprint is owned by a **closed** Story routed `update-existing`
|
|
434
|
-
* against an open neighbour — a genuine regression filed as a
|
|
435
|
-
* business-as-usual update. Attribution restores it: state is read off the
|
|
436
|
-
* owning issue, not off whatever else shares its location.
|
|
437
|
-
*
|
|
438
|
-
* {@link attributedPool} owns that selection; the decision below reads only
|
|
439
|
-
* the pool it returns.
|
|
281
|
+
* State is read off the attributed issue, so an open neighbour cannot mask a
|
|
282
|
+
* regression of the closed owner.
|
|
440
283
|
*
|
|
441
284
|
* @param {Array<{ number: number, state: string }>} confirmed
|
|
442
285
|
* @param {string} sha
|
|
@@ -469,15 +312,8 @@ function decideFromConfirmed(confirmed, sha) {
|
|
|
469
312
|
}
|
|
470
313
|
|
|
471
314
|
/**
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
* when a `semanticKey` is supplied (audit dedup opts in via
|
|
475
|
-
* `options.semanticKeyConfirm`), ALSO by the location-based **semantic-key**
|
|
476
|
-
* footer. A semantic candidate that merely *looks* similar but carries neither
|
|
477
|
-
* footer is dropped here — semantic similarity widens the net; a deterministic
|
|
478
|
-
* footer (fingerprint or semantic key) is what confirms identity. The semantic
|
|
479
|
-
* key catches a reworded finding whose fingerprint has drifted but whose
|
|
480
|
-
* location is unchanged.
|
|
315
|
+
* Only a deterministic footer (fingerprint, or semantic key when supplied)
|
|
316
|
+
* confirms identity.
|
|
481
317
|
*
|
|
482
318
|
* @param {Array<unknown>} hits
|
|
483
319
|
* @param {{ sha: string, semanticKey?: string }} identity
|
|
@@ -496,13 +332,7 @@ function confirmCandidates(hits, { sha, semanticKey = '' }) {
|
|
|
496
332
|
}
|
|
497
333
|
|
|
498
334
|
/**
|
|
499
|
-
*
|
|
500
|
-
* dropping an issue number an earlier pool already contributed.
|
|
501
|
-
*
|
|
502
|
-
* The fingerprint pool is passed first, so when both ports return the same
|
|
503
|
-
* Issue it is that pool's record — the one retrieved by exact identity — that
|
|
504
|
-
* survives into confirmation. Records without a usable number are left for
|
|
505
|
-
* {@link confirmCandidates} to reject, exactly as a single port's would be.
|
|
335
|
+
* First-seen wins, so the fingerprint pool's record survives a tie.
|
|
506
336
|
*
|
|
507
337
|
* @param {Array<unknown>} pools
|
|
508
338
|
* @returns {Array<object>}
|
|
@@ -519,18 +349,10 @@ function unionCandidatePools(pools) {
|
|
|
519
349
|
}
|
|
520
350
|
|
|
521
351
|
/**
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
* A run with a single wired port returns that port's result **verbatim**, so
|
|
525
|
-
* the fingerprint-only wiring (`qa-explore`, and every caller that injects no
|
|
526
|
-
* semantic port) keeps its behaviour exactly — including how a non-array
|
|
527
|
-
* return is handled downstream by {@link confirmCandidates}.
|
|
528
|
-
*
|
|
529
|
-
* Both ports are awaited together; a rejection from either propagates rather
|
|
530
|
-
* than degrading silently to a partial pool.
|
|
352
|
+
* A single port's result is returned verbatim; a rejection propagates.
|
|
531
353
|
*
|
|
532
354
|
* @param {object} finding
|
|
533
|
-
* @param {string} sha
|
|
355
|
+
* @param {string} sha
|
|
534
356
|
* @param {{ searchIssues?: Function, searchCandidates?: Function }} ports
|
|
535
357
|
* @returns {Promise<Array<object>|unknown>}
|
|
536
358
|
*/
|
|
@@ -544,55 +366,18 @@ async function gatherCandidates(finding, sha, ports) {
|
|
|
544
366
|
}
|
|
545
367
|
|
|
546
368
|
/**
|
|
547
|
-
* Route a finding against existing Issues
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
* - `searchIssues(sha)` is the **exact** lookup. A fingerprint sha is one
|
|
553
|
-
* high-signal term, so it retrieves the Issue whose footer carries it.
|
|
554
|
-
* - `searchCandidates(finding)` is the **meaning-first** pass. It widens the
|
|
555
|
-
* pool to Issues describing the same problem under a different title, so a
|
|
556
|
-
* reworded finding or a moved file still confirms by semantic key.
|
|
557
|
-
*
|
|
558
|
-
* This was a ternary until Story #5079: an injected semantic port *replaced*
|
|
559
|
-
* the fingerprint lookup instead of widening it. Production always injects
|
|
560
|
-
* one, so `searchIssues` was dead code on the live path and dedup rested
|
|
561
|
-
* entirely on a ~20-token bag-of-words query that does not reliably retrieve
|
|
562
|
-
* the Issue. The audit loop consequently re-filed Stories it had already
|
|
563
|
-
* filed, against the workflow's "Never open a duplicate Issue" constraint.
|
|
564
|
-
* Running both ports and unioning their pools is what closes that loop.
|
|
565
|
-
*
|
|
566
|
-
* A port that rejects **propagates**. A pool gathered from only some of its
|
|
567
|
-
* sources is not a smaller pool, it is an unknown one, so the caller
|
|
568
|
-
* (`classifyGroupsAgainstGitHub`) must record a degraded lookup rather than
|
|
569
|
-
* report a confident `new`.
|
|
570
|
-
*
|
|
571
|
-
* **Confirm.** The pooled candidates are filtered down to those that actually
|
|
572
|
-
* carry the finding's fingerprint footer — or, when `semanticKeyConfirm` is
|
|
573
|
-
* on, its location-based semantic-key footer — then resolved:
|
|
574
|
-
* - An open match → `update-existing` (or `duplicate` when more than one
|
|
575
|
-
* open issue carries the fingerprint).
|
|
576
|
-
* - A closed match (no open match) → `regression-of-closed`.
|
|
577
|
-
* - No confirmed match → `new`.
|
|
578
|
-
*
|
|
579
|
-
* The decision enum is identical however the candidates were gathered.
|
|
369
|
+
* Route a finding against existing Issues. Every wired port runs and pools
|
|
370
|
+
* union: the semantic search must widen, never replace, the exact sha lookup
|
|
371
|
+
* (a bag-of-words query alone re-files duplicates). A rejecting port
|
|
372
|
+
* propagates — a partial pool is unknown, not a confident `new`.
|
|
580
373
|
*
|
|
581
374
|
* @param {object} finding
|
|
582
375
|
* @param {object} ports
|
|
583
376
|
* @param {(sha: string) => Promise<Array<{ number: number, state: string, body?: string }>>} [ports.searchIssues]
|
|
584
|
-
* Fingerprint-keyed lookup over open+closed issues. Runs whenever it is
|
|
585
|
-
* supplied. Required when `searchCandidates` is not.
|
|
586
377
|
* @param {(finding: object) => Promise<Array<{ number: number, state: string, title?: string, body?: string }>>} [ports.searchCandidates]
|
|
587
|
-
* Meaning-first candidate search over open+closed issues (and Epic
|
|
588
|
-
* sub-issues). Runs whenever it is supplied, alongside `searchIssues` rather
|
|
589
|
-
* than instead of it; the union is then confirmed by footer.
|
|
590
378
|
* @param {object} [options]
|
|
591
|
-
* @param {boolean} [options.semanticKeyConfirm=false] —
|
|
592
|
-
*
|
|
593
|
-
* alone. Opt-in so the audit dedup path catches a reworded finding at an
|
|
594
|
-
* unchanged location while the qa-explore path (which does not stamp
|
|
595
|
-
* semantic-key footers) stays fingerprint-exact and byte-identical.
|
|
379
|
+
* @param {boolean} [options.semanticKeyConfirm=false] — opt-in; qa-explore
|
|
380
|
+
* stamps no semantic keys.
|
|
596
381
|
* @returns {Promise<{ decision: 'new'|'update-existing'|'duplicate'|'regression-of-closed', matchedIssue: object|null, fingerprint: string }>}
|
|
597
382
|
*/
|
|
598
383
|
export async function routeFinding(
|
|
@@ -612,14 +397,11 @@ export async function routeFinding(
|
|
|
612
397
|
const { full: sha } = fingerprintFinding(finding);
|
|
613
398
|
const semanticKey = options.semanticKeyConfirm ? semanticKeyFor(finding) : '';
|
|
614
399
|
|
|
615
|
-
// Gather: every wired port runs, and their pools union (Story #5079).
|
|
616
400
|
const hits = await gatherCandidates(finding, sha, {
|
|
617
401
|
searchIssues,
|
|
618
402
|
searchCandidates,
|
|
619
403
|
});
|
|
620
404
|
|
|
621
|
-
// Confirm identity by fingerprint footer (and, when opted in, the
|
|
622
|
-
// location-based semantic-key footer) over the pooled candidates.
|
|
623
405
|
const confirmed = confirmCandidates(hits, { sha, semanticKey });
|
|
624
406
|
|
|
625
407
|
return decideFromConfirmed(confirmed, sha);
|