mandrel 2.59.0 → 2.61.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 +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- 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 +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- 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 +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- 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 +57 -49
- 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 +7 -19
- 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 +39 -121
- 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 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- 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 +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- 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 +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- 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 -124
- 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 +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- 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 +123 -191
- 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 +22 -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 +28 -156
- 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 +121 -157
- 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 +118 -462
- 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 +37 -307
- 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/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- 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 +16 -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 +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- 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 -91
- 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 +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- 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 +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- 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 +136 -486
- 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 +96 -0
- 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 +180 -273
- 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 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- 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 -135
- 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 +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- 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 +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- 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 +67 -209
- 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 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- 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 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- 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/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- 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/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- 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 +60 -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 +326 -523
- 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 +17 -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 +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- 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/schemas/model-attribution.schema.json +0 -53
- 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 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- 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/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- 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 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,41 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* already-open (skip), or re-occurring (skip, but flag).
|
|
6
|
-
*
|
|
7
|
-
* This module owns **no** fingerprint or dedup logic. It routes every
|
|
8
|
-
* finding through the shared `lib/findings/route-finding.js` helper — the
|
|
9
|
-
* single dedup/route implementation, shared verbatim with `qa-explore` — and
|
|
10
|
-
* folds the per-finding `routeFinding` decisions up to a group action:
|
|
11
|
-
*
|
|
12
|
-
* - any finding routes to `update-existing` / `duplicate` → `skip-open`
|
|
13
|
-
* - else any finding routes to `regression-of-closed` → `skip-reoccurring`
|
|
14
|
-
* - else (every finding is `new`) → `create`
|
|
15
|
-
*
|
|
16
|
-
* The GitHub lookup is delegated to a `provider` port the caller injects,
|
|
17
|
-
* exposing `findIssuesByFingerprint(sha)` → `{ number, state, body }[]`. The
|
|
18
|
-
* port is adapted into the `searchIssues` shape the shared helper expects.
|
|
19
|
-
* When the caller ALSO injects a `searchCandidates(finding)` port (production
|
|
20
|
-
* wires it to `semantic-issue-search.js`), routing runs the meaning-first
|
|
21
|
-
* Stage-1 pass and opts into location-based semantic-key confirmation so a
|
|
22
|
-
* reworded finding at an unchanged location still dedupes against its Issue
|
|
23
|
-
* (Story #4626).
|
|
24
|
-
*
|
|
25
|
-
* When the caller injects a `listAuditIssues(labels)` port, the whole dedup
|
|
26
|
-
* corpus is pre-fetched **once per run** off the list endpoint and indexed by
|
|
27
|
-
* both provenance footers, so `findIssuesByFingerprint` is answered locally and
|
|
28
|
-
* the rate-limited search API is spent only on findings with no exact hit.
|
|
29
|
-
*
|
|
30
|
-
* A caller that already holds the corpus injects it directly as `issues`
|
|
31
|
-
* instead (Story #5301) — the host fetched it by whatever access path it has,
|
|
32
|
-
* which is what lets dedup run on a host with no `gh` CLI at all. That source
|
|
33
|
-
* needs no provider: with an index in play the exact lookup is answered from
|
|
34
|
-
* memory and `findIssuesByFingerprint` is never called, so the port is required
|
|
35
|
-
* only on the un-indexed path where it is genuinely used.
|
|
36
|
-
*
|
|
37
|
-
* Pure orchestration: this module performs no network I/O itself, and reads no
|
|
38
|
-
* file — the caller hands over an array, never a path.
|
|
2
|
+
* Classify each group `create`, `skip-open` (any open match) or
|
|
3
|
+
* `skip-reoccurring` (any closed match) by folding `route-finding.js`
|
|
4
|
+
* decisions. No I/O.
|
|
39
5
|
*/
|
|
40
6
|
|
|
41
7
|
import { routeFinding, semanticKeyFor } from '../findings/route-finding.js';
|
|
@@ -52,12 +18,7 @@ import { lookupLocally } from './issue-index.js';
|
|
|
52
18
|
*/
|
|
53
19
|
|
|
54
20
|
/**
|
|
55
|
-
*
|
|
56
|
-
* no imports, no I/O — so the module stays pure orchestration (Story #4678).
|
|
57
|
-
*
|
|
58
|
-
* Both degrade paths run through here, so the wording an operator reads for a
|
|
59
|
-
* failed index pre-fetch matches the wording for a failed per-group lookup:
|
|
60
|
-
* one vocabulary for "the GitHub read did not complete", whichever read it was.
|
|
21
|
+
* One vocabulary for both degrade paths (index pre-fetch and per-group lookup).
|
|
61
22
|
*
|
|
62
23
|
* @param {unknown} err
|
|
63
24
|
* @returns {string}
|
|
@@ -75,7 +36,6 @@ function describeDegradeReason(err) {
|
|
|
75
36
|
}
|
|
76
37
|
|
|
77
38
|
/**
|
|
78
|
-
* Stable operator-facing label for a group in a degrade report.
|
|
79
39
|
* @param {object} group
|
|
80
40
|
* @returns {string}
|
|
81
41
|
*/
|
|
@@ -84,11 +44,7 @@ function groupLabel(group) {
|
|
|
84
44
|
}
|
|
85
45
|
|
|
86
46
|
/**
|
|
87
|
-
*
|
|
88
|
-
* group action. Extracted so the top-level loop can wrap it in one try/catch:
|
|
89
|
-
* a search failure that survives the endpoint budget (an HTTP 422, or a rate
|
|
90
|
-
* limit still exhausted after the cooldown) throws out of here and is caught
|
|
91
|
-
* once per group rather than aborting the whole scan (Story #4678).
|
|
47
|
+
* Throws on lookup failure; caught per group by the caller.
|
|
92
48
|
*
|
|
93
49
|
* @param {object} group
|
|
94
50
|
* @param {object} routing — `{ searchIssues, semanticPort, routeOptions }`.
|
|
@@ -141,14 +97,8 @@ async function classifyOneGroup(
|
|
|
141
97
|
}
|
|
142
98
|
|
|
143
99
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* With no local index this is the historical wiring: the provider answers the
|
|
147
|
-
* exact lookup and the semantic port always runs. With an index, the exact
|
|
148
|
-
* lookup is answered from memory, and the semantic port — the only remaining
|
|
149
|
-
* network call — runs **only** when the index holds no exact fingerprint hit.
|
|
150
|
-
* That is the whole saving: a finding the sweep has already filed costs zero
|
|
151
|
-
* requests, and only a genuinely-unrecognised one is worth a search.
|
|
100
|
+
* With an index, the exact lookup is answered from memory and the semantic
|
|
101
|
+
* search (the only network call left) runs only when there is no exact hit.
|
|
152
102
|
*
|
|
153
103
|
* @param {object} canonical — the canonical finding projection.
|
|
154
104
|
* @param {string} sha — its full fingerprint.
|
|
@@ -171,25 +121,15 @@ function portsFor(canonical, sha, { searchIssues, semanticPort, index }) {
|
|
|
171
121
|
* @param {object} params
|
|
172
122
|
* @param {Array<object>} params.groups — output of `groupFindings`.
|
|
173
123
|
* @param {{ findIssuesByFingerprint: (sha: string) => Promise<Array<{ number: number, state: string, body?: string }>> }} params.provider
|
|
124
|
+
* Only read on the un-indexed path.
|
|
174
125
|
* @param {(finding: object) => Promise<Array<{ number: number, state: string, title?: string, body?: string }>>} [params.searchCandidates]
|
|
175
|
-
*
|
|
176
|
-
* When supplied, routing runs the Stage-1 semantic pass and opts into
|
|
177
|
-
* location-based semantic-key confirmation.
|
|
126
|
+
* Enables the semantic pass and semantic-key confirmation.
|
|
178
127
|
* @param {(labels: string[]) => Promise<Array<object>>} [params.listAuditIssues]
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* @param {Array<object>} [params.issues]
|
|
183
|
-
* Optional pre-fetched corpus the caller already holds, used in preference to
|
|
184
|
-
* `listAuditIssues`. Supplying it makes `provider` optional: with an index in
|
|
185
|
-
* play no provider read port is ever invoked, which is what lets a host with
|
|
186
|
-
* no `gh` CLI dedup at all (Story #5301). An empty array is a valid corpus —
|
|
187
|
-
* a first sweep — and is NOT read as "no index".
|
|
128
|
+
* Fetched once and indexed.
|
|
129
|
+
* @param {Array<object>} [params.issues] Pre-fetched corpus, preferred over
|
|
130
|
+
* `listAuditIssues`; lets a host with no `gh` dedup. `[]` is a valid corpus.
|
|
188
131
|
* @param {(entry: { group: object, reason: string }) => void} [params.onDegraded]
|
|
189
|
-
*
|
|
190
|
-
* (Story #4678). The group is then classified `create` — a soft-fail, never
|
|
191
|
-
* fatal. Pure orchestration: this module performs no network I/O and swallows
|
|
192
|
-
* no failure silently.
|
|
132
|
+
* Notified per group whose lookup failed; that group soft-fails to `create`.
|
|
193
133
|
* @returns {Promise<{ classifications: GroupClassification[], summary: { create: number, skipOpen: number, skipReoccurring: number, dedupDegraded: { count: number, groups: Array<{ group: string, reason: string }> } } }>}
|
|
194
134
|
*/
|
|
195
135
|
export async function classifyGroupsAgainstGitHub({
|
|
@@ -212,11 +152,7 @@ export async function classifyGroupsAgainstGitHub({
|
|
|
212
152
|
issues,
|
|
213
153
|
});
|
|
214
154
|
if (error) {
|
|
215
|
-
//
|
|
216
|
-
// a degraded group: the count names groups classified without a check, and
|
|
217
|
-
// every group still gets one here, off the per-finding search path. Until
|
|
218
|
-
// Story #5301 this failure was swallowed whole, so the operator saw only
|
|
219
|
-
// the downstream per-group degradation and could not tell what caused it.
|
|
155
|
+
// Not counted as a degraded group: per-finding search still checks each.
|
|
220
156
|
const reason = `issue-index pre-fetch failed: ${describeDegradeReason(error)}`;
|
|
221
157
|
summary.dedupDegraded.indexPrefetch = reason;
|
|
222
158
|
if (typeof onDegraded === 'function') onDegraded({ group: null, reason });
|
|
@@ -229,8 +165,6 @@ export async function classifyGroupsAgainstGitHub({
|
|
|
229
165
|
try {
|
|
230
166
|
result = await classifyOneGroup(group, routing);
|
|
231
167
|
} catch (err) {
|
|
232
|
-
// A dedup lookup that cannot complete degrades this group to `create`
|
|
233
|
-
// with a recorded reason — never aborts the whole scan.
|
|
234
168
|
const reason = describeDegradeReason(err);
|
|
235
169
|
const entry = { group: groupLabel(group), reason };
|
|
236
170
|
summary.dedupDegraded.count += 1;
|
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the `/mandrel-plan` seed one-pager (`seed-from-findings.js`) and the
|
|
7
|
-
* standalone Story-draft transcript (`audit-to-stories.js`). A sweep is the
|
|
8
|
-
* clearest case for a container — every Story shares a provenance and the
|
|
9
|
-
* operator almost always wants them delivered together — so the Epic is the
|
|
10
|
-
* **default** here, unlike the offer `/mandrel-plan` makes on an ad-hoc plan.
|
|
11
|
-
*
|
|
12
|
-
* It stays a directive in the text rather than an automatic write: the
|
|
13
|
-
* workflow's Phase 4 HITL stop is where an operator declines it.
|
|
14
|
-
*
|
|
15
|
-
* Since Story #5155 the directive names adoption first: a repeat sweep over the
|
|
16
|
-
* same area is the case most likely to already have a container, and opening a
|
|
17
|
-
* second one beside it is the failure this ordering exists to prevent.
|
|
2
|
+
* The container-Epic directive both `/audit-to-stories` output paths carry.
|
|
3
|
+
* For a sweep the Epic is the default (shared provenance), declinable at the
|
|
4
|
+
* HITL stop; adoption of an existing Epic is named first so a repeat sweep
|
|
5
|
+
* does not open a second container.
|
|
18
6
|
*
|
|
19
7
|
* @module lib/audit-to-stories/epic-grouping-directive
|
|
20
8
|
*/
|
|
@@ -22,8 +10,6 @@
|
|
|
22
10
|
import { EPIC_SUGGESTION_THRESHOLD } from '../orchestration/plan-persist/epic-ops.js';
|
|
23
11
|
|
|
24
12
|
/**
|
|
25
|
-
* Render the grouping directive for a proposed Story set.
|
|
26
|
-
*
|
|
27
13
|
* @param {unknown[]} groups The proposed Stories (only the count is read).
|
|
28
14
|
* @returns {string} Markdown paragraph(s).
|
|
29
15
|
*/
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `/audit-to-stories` parses `audit-*-results.md` into findings shaped as
|
|
6
|
-
* `{ dimension, severity, title, normalisedTitle, files, ... }`. The shared
|
|
7
|
-
* dedup/route helper (`lib/findings/route-finding.js`) fingerprints over the
|
|
8
|
-
* canonical identity `{ title, area, primaryFile, severity, labels }`. This
|
|
9
|
-
* module is the thin, audit-specific adapter that maps the former onto the
|
|
10
|
-
* latter and reuses the shared helper's primitives — it contains **no**
|
|
11
|
-
* fingerprint or dedup logic of its own. The single dedup/route
|
|
12
|
-
* implementation lives in `lib/findings/route-finding.js`, shared verbatim
|
|
13
|
-
* with `qa-explore`.
|
|
2
|
+
* Project parsed audit findings onto the shared findings identity. No
|
|
3
|
+
* fingerprint or dedup logic of its own — that lives in `route-finding.js`.
|
|
14
4
|
*/
|
|
15
5
|
|
|
16
6
|
import {
|
|
@@ -21,13 +11,8 @@ import {
|
|
|
21
11
|
} from '../findings/route-finding.js';
|
|
22
12
|
|
|
23
13
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* normalises the title; `files[0]` is the primary file the parser pulled
|
|
27
|
-
* from the finding body. `dimension` is the identity axis (carried as
|
|
28
|
-
* `area`) and also the sole label so two findings in the same dimension that
|
|
29
|
-
* are otherwise identical collide exactly as the legacy
|
|
30
|
-
* `(dimension, normalisedTitle, primaryFile)` key did.
|
|
14
|
+
* `dimension` is both `area` and the sole label, so identity stays
|
|
15
|
+
* `(dimension, normalisedTitle, primaryFile)`; severity is excluded.
|
|
31
16
|
*
|
|
32
17
|
* @param {{ dimension?: string, normalisedTitle?: string, files?: string[] }} finding
|
|
33
18
|
* @returns {{ title: string, area: string, primaryFile: string, severity: string, labels: string[] }}
|
|
@@ -48,8 +33,6 @@ export function toCanonicalFinding(finding) {
|
|
|
48
33
|
}
|
|
49
34
|
|
|
50
35
|
/**
|
|
51
|
-
* Compute the shared-helper fingerprint for a single audit finding.
|
|
52
|
-
*
|
|
53
36
|
* @param {object} finding
|
|
54
37
|
* @returns {{ short: string, full: string, components: object }}
|
|
55
38
|
*/
|
|
@@ -58,13 +41,7 @@ export function fingerprintAuditFinding(finding) {
|
|
|
58
41
|
}
|
|
59
42
|
|
|
60
43
|
/**
|
|
61
|
-
*
|
|
62
|
-
* shared helper. Stable across a reworded title; used to confirm a dedup
|
|
63
|
-
* match when the fingerprint has drifted (Story #4626).
|
|
64
|
-
*
|
|
65
|
-
* Module-internal since the ledger moved to the shared findings layer and takes
|
|
66
|
-
* its projection injected: `renderSemanticKeyFooter` below is the only caller,
|
|
67
|
-
* and re-exporting it for none would trip `dead-exports:production`.
|
|
44
|
+
* Location-based key, stable across a reworded title.
|
|
68
45
|
*
|
|
69
46
|
* @param {object} finding
|
|
70
47
|
* @returns {string}
|
|
@@ -74,10 +51,6 @@ function semanticKeyForAuditFinding(finding) {
|
|
|
74
51
|
}
|
|
75
52
|
|
|
76
53
|
/**
|
|
77
|
-
* Stamp every audit finding with its shared-helper fingerprint and return a
|
|
78
|
-
* new array. Mirrors the legacy `withFingerprints` contract so downstream
|
|
79
|
-
* grouping / story-body / dedupe consumers keep reading `finding.fingerprint`.
|
|
80
|
-
*
|
|
81
54
|
* @template T
|
|
82
55
|
* @param {Array<T>} findings
|
|
83
56
|
* @returns {Array<T & { fingerprint: { short: string, full: string } }>}
|
|
@@ -93,9 +66,7 @@ export function withFingerprints(findings) {
|
|
|
93
66
|
}
|
|
94
67
|
|
|
95
68
|
/**
|
|
96
|
-
*
|
|
97
|
-
* via the shared helper's single footer renderer. Findings must already
|
|
98
|
-
* carry `fingerprint.full` (set by {@link withFingerprints}).
|
|
69
|
+
* Findings must already carry `fingerprint.full` ({@link withFingerprints}).
|
|
99
70
|
*
|
|
100
71
|
* @param {Array<{ fingerprint?: { full?: string } }>} findings
|
|
101
72
|
* @returns {string}
|
|
@@ -111,11 +82,7 @@ export function renderFingerprintFooter(findings) {
|
|
|
111
82
|
}
|
|
112
83
|
|
|
113
84
|
/**
|
|
114
|
-
*
|
|
115
|
-
* the shared helper's single footer renderer. Stamped alongside the
|
|
116
|
-
* fingerprint footer so a later reworded finding at the same location still
|
|
117
|
-
* confirms a dedup match (Story #4626). Findings do not need a precomputed
|
|
118
|
-
* key — it is derived from each finding's canonical projection here.
|
|
85
|
+
* Lets a reworded finding at the same location still confirm a dedup match.
|
|
119
86
|
*
|
|
120
87
|
* @param {Array<object>} findings
|
|
121
88
|
* @returns {string}
|
|
@@ -1,24 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* 2. **Adjacent files in the same module directory** — when the
|
|
7
|
-
* directory hash matches and there is no stronger signal.
|
|
8
|
-
* 3. **Root-cause keyword overlap** — shared topical n-gram across
|
|
9
|
-
* Current State / Title.
|
|
10
|
-
*
|
|
11
|
-
* Cross-audit grouping is enabled by default: a `security` finding and a
|
|
12
|
-
* `clean-code` finding on the same file produce a single group with both
|
|
13
|
-
* dimensions captured (`group.dimensions` is an array — callers map this
|
|
14
|
-
* to multiple `audit::<dim>` labels).
|
|
15
|
-
*
|
|
16
|
-
* Dependency edges (Recommendation of A references the file Current
|
|
17
|
-
* State of B flags) are emitted as a separate `edges` array — they do
|
|
18
|
-
* NOT merge the groups. The CLI surfaces them in the preview so the
|
|
19
|
-
* operator can decide if a sequencing constraint is worth flagging.
|
|
20
|
-
*
|
|
21
|
-
* Pure: no I/O.
|
|
2
|
+
* Cluster findings (across lenses) into Stories by: same primary file, then
|
|
3
|
+
* same directory with root-cause keyword overlap, then keyword overlap alone.
|
|
4
|
+
* Dependency edges (A's recommendation names B's file) are reported
|
|
5
|
+
* separately and never merge groups. Pure.
|
|
22
6
|
*/
|
|
23
7
|
|
|
24
8
|
import { highestSeverity as highestSeverityOf } from '../findings/severity.js';
|
|
@@ -38,16 +22,8 @@ function pickPrimaryFile(finding) {
|
|
|
38
22
|
}
|
|
39
23
|
|
|
40
24
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* The rank map this replaces knew four levels and not `info`, so an Info
|
|
45
|
-
* finding tied with a finding carrying no severity at all — the same partial
|
|
46
|
-
* vocabulary this Story removes everywhere else.
|
|
47
|
-
*
|
|
48
|
-
* A group whose findings all lack a usable severity still reports `null`, not
|
|
49
|
-
* the SSOT's `info` floor: absent is not the same claim as "graded lowest",
|
|
50
|
-
* and the callers that tally and threshold on this value distinguish them.
|
|
25
|
+
* `null` (not `info`) when no finding states a severity: absent is not
|
|
26
|
+
* "graded lowest", and callers distinguish them.
|
|
51
27
|
*
|
|
52
28
|
* @param {Array<{ severity?: string }>} findings
|
|
53
29
|
* @returns {string|null} a canonical severity, or null when none is stated.
|
|
@@ -88,7 +64,6 @@ function tokenisePhrase(text) {
|
|
|
88
64
|
}
|
|
89
65
|
|
|
90
66
|
function rootCauseSignature(finding) {
|
|
91
|
-
// Topical tokens drawn from title + current-state.
|
|
92
67
|
const title = tokenisePhrase(finding.normalisedTitle ?? finding.title ?? '');
|
|
93
68
|
const state = tokenisePhrase(finding.currentState ?? '');
|
|
94
69
|
return new Set([...title, ...state]);
|
|
@@ -143,8 +118,7 @@ function synthesizeTitle(group) {
|
|
|
143
118
|
}
|
|
144
119
|
|
|
145
120
|
function detectDependencyEdges(groups) {
|
|
146
|
-
// A
|
|
147
|
-
// group A's Recommendation text (i.e. fixing A requires B to land).
|
|
121
|
+
// A → B when A's recommendation mentions a file B owns.
|
|
148
122
|
const fileToGroup = new Map();
|
|
149
123
|
for (const g of groups) {
|
|
150
124
|
const filesIter = Array.isArray(g.files) ? g.files : [...g.files];
|
|
@@ -176,8 +150,6 @@ function detectDependencyEdges(groups) {
|
|
|
176
150
|
}
|
|
177
151
|
|
|
178
152
|
/**
|
|
179
|
-
* Cluster findings into Stories.
|
|
180
|
-
*
|
|
181
153
|
* @param {Array<{
|
|
182
154
|
* dimension: string,
|
|
183
155
|
* severity: string|null,
|
|
@@ -204,7 +176,6 @@ export function groupFindings(findings) {
|
|
|
204
176
|
if (primary) {
|
|
205
177
|
key = `file:${primary}`;
|
|
206
178
|
} else {
|
|
207
|
-
// No file → try signature-based merge with an existing group.
|
|
208
179
|
const { key: matchKey, sig } = bestSignatureGroupKey(finding, sigBuckets);
|
|
209
180
|
if (matchKey) {
|
|
210
181
|
key = matchKey;
|
|
@@ -227,9 +198,8 @@ export function groupFindings(findings) {
|
|
|
227
198
|
attachFindingToGroup(groups.get(key), finding);
|
|
228
199
|
}
|
|
229
200
|
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
// overlap by ≥ 3 tokens. This implements signal #2.
|
|
201
|
+
// Merge single-finding groups into a same-directory group sharing ≥ 3
|
|
202
|
+
// signature tokens.
|
|
233
203
|
const groupArray = [...groups.values()];
|
|
234
204
|
const merged = new Set();
|
|
235
205
|
for (let i = 0; i < groupArray.length; i += 1) {
|
|
@@ -1,42 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lib/audit-to-stories/issue-corpus.js — where the dedup corpus comes from,
|
|
3
|
-
* and how a corpus that could not be fetched is described to the operator.
|
|
4
|
-
*
|
|
5
|
-
* Dedup needs exactly one thing from GitHub: the Issues carrying an `audit::*`
|
|
6
|
-
* label. Until Story #5301 the only source was the provider's list port, which
|
|
7
|
-
* spawns `gh`, so a host without a `gh` CLI — a Claude Code cloud sandbox,
|
|
8
|
-
* where `gh` is absent and direct API access is disabled while the GitHub MCP
|
|
9
|
-
* tools work fine — could not dedup at all: every group classified `create`
|
|
10
|
-
* and a scheduled sweep re-filed what it had already filed.
|
|
11
|
-
*
|
|
12
|
-
* Sourcing lives here rather than in `dedupe-against-github.js` so that module
|
|
13
|
-
* stays what its own header claims — pure routing of findings to verdicts —
|
|
14
|
-
* and so the empty-corpus and failed-fetch cases cannot diverge between call
|
|
15
|
-
* sites. Nothing here reaches the network or the filesystem: a caller that
|
|
16
|
-
* already holds the corpus passes the array in.
|
|
17
|
-
*/
|
|
1
|
+
/** Source and describe the dedup corpus. No I/O. */
|
|
18
2
|
|
|
19
3
|
import { auditLabelsForFindings } from './audit-lenses.js';
|
|
20
4
|
import { buildIssueIndex } from './issue-index.js';
|
|
21
5
|
|
|
22
6
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* is no `gh` CLI. Otherwise the run's `audit::*` Issues are pre-fetched off the
|
|
28
|
-
* list port, once.
|
|
29
|
-
*
|
|
30
|
-
* Two results deliberately do NOT collapse to "no index", because a null index
|
|
31
|
-
* silently returns the run to the per-finding search — which on a
|
|
32
|
-
* provider-less host is no dedup at all, the failure this path exists to kill.
|
|
33
|
-
* An **empty** injected corpus is a legitimate first sweep and yields a real
|
|
34
|
-
* zero-row index. A **failed** pre-fetch hands back its `error` so the caller
|
|
35
|
-
* can say so in its own words: an operator who cannot see that the pre-fetch
|
|
36
|
-
* failed cannot tell a checked plan from an unchecked one.
|
|
37
|
-
*
|
|
38
|
-
* Module-internal: every caller reaches it through `prepareDedupRouting`, so
|
|
39
|
-
* the empty-corpus and failed-fetch cases cannot diverge between call sites.
|
|
7
|
+
* An injected `issues` corpus wins; else pre-fetch once off the list port.
|
|
8
|
+
* An empty corpus is a real zero-row index, and a failed pre-fetch returns its
|
|
9
|
+
* `error`: neither may collapse to a null index, which silently means no dedup
|
|
10
|
+
* on a provider-less host.
|
|
40
11
|
*
|
|
41
12
|
* @param {{ listAuditIssues?: Function, groups?: Array<object>,
|
|
42
13
|
* issues?: Array<object> }} params
|
|
@@ -65,17 +36,7 @@ async function resolveIssueCorpus({ listAuditIssues, groups, issues }) {
|
|
|
65
36
|
}
|
|
66
37
|
|
|
67
38
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* A run with neither an injected corpus nor a list port has no index to
|
|
71
|
-
* describe, and `{ source: 'none', size: 0 }` says nothing the field's absence
|
|
72
|
-
* does not — while inviting the reading "an index was consulted and it was
|
|
73
|
-
* empty", the exact confusion this whole path exists to remove. Omitting it
|
|
74
|
-
* also leaves the summary a pure per-finding-search run emits byte-identical
|
|
75
|
-
* to what it has always been.
|
|
76
|
-
*
|
|
77
|
-
* A failed pre-fetch is the one `none` that IS described: there the run ended
|
|
78
|
-
* *without* an index it expected to have, and the operator needs to see that.
|
|
39
|
+
* Omits `dedupIndex` when no index was expected; describes a failed prefetch.
|
|
79
40
|
*
|
|
80
41
|
* @param {object} summary — the seeded counters.
|
|
81
42
|
* @param {{ source: string, index: object|null, error?: unknown }} resolution
|
|
@@ -87,24 +48,12 @@ function withIndexDescription(summary, { source, index, error }) {
|
|
|
87
48
|
}
|
|
88
49
|
|
|
89
50
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* what the corpus was and whether fetching it degraded.
|
|
93
|
-
*
|
|
94
|
-
* The provider port is validated here because this is where "is there a usable
|
|
95
|
-
* dedup source at all" is actually known. It is required only on the
|
|
96
|
-
* un-indexed path: once an index exists every exact lookup is answered from
|
|
97
|
-
* memory and `findIssuesByFingerprint` is never called, so demanding it there
|
|
98
|
-
* would be the one thing standing between a `gh`-less host and a real dedup
|
|
99
|
-
* run.
|
|
51
|
+
* Routing ports, resolved index and seeded summary. The provider port is
|
|
52
|
+
* required only without a corpus: with an index, exact lookups never call it.
|
|
100
53
|
*
|
|
101
54
|
* @param {{ groups?: Array<object>, provider?: object,
|
|
102
55
|
* searchCandidates?: Function, listAuditIssues?: Function,
|
|
103
56
|
* issues?: Array<object> }} params
|
|
104
|
-
* The seeded `summary` comes back with it: the corpus is the only thing that
|
|
105
|
-
* knows what the index was, and returning the counters beside it keeps the
|
|
106
|
-
* caller from reconstructing a shape it does not own.
|
|
107
|
-
*
|
|
108
57
|
* @returns {Promise<{ routing: object, summary: object, error?: unknown }>}
|
|
109
58
|
* @throws {Error} when neither a provider read port nor a corpus is supplied.
|
|
110
59
|
*/
|
|
@@ -132,17 +81,12 @@ export async function prepareDedupRouting({
|
|
|
132
81
|
typeof searchCandidates === 'function' ? searchCandidates : undefined;
|
|
133
82
|
return {
|
|
134
83
|
routing: {
|
|
135
|
-
// routeFinding hands the port the sha it computed off the canonical
|
|
136
|
-
// projection, which equals the sha the group already carries.
|
|
137
84
|
searchIssues: hasProviderPort
|
|
138
85
|
? (sha) => provider.findIssuesByFingerprint(sha)
|
|
139
86
|
: undefined,
|
|
140
87
|
semanticPort,
|
|
141
|
-
// An index carries the semantic-key map, so
|
|
142
|
-
//
|
|
143
|
-
// the `bySemanticKey` half of the pool the local lookup just built, and a
|
|
144
|
-
// provider-less run would be fingerprint-exact only — strictly weaker
|
|
145
|
-
// than the path it replaces.
|
|
88
|
+
// An index carries the semantic-key map, so confirmation is free; without
|
|
89
|
+
// it a provider-less run would be fingerprint-exact only.
|
|
146
90
|
routeOptions: {
|
|
147
91
|
semanticKeyConfirm: Boolean(semanticPort) || Boolean(index),
|
|
148
92
|
},
|
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Dedup used to answer every finding with a **search** round-trip: one
|
|
6
|
-
* `findIssuesByFingerprint(sha)` per finding, plus a meaning-first semantic
|
|
7
|
-
* search on top. GitHub's search endpoint is rate-limited an order of magnitude
|
|
8
|
-
* harder than the list endpoint, so a full-scope sweep — hundreds of findings —
|
|
9
|
-
* spent its whole budget re-discovering the same few dozen Issues, and then
|
|
10
|
-
* degraded the rest of the run to `create`, which is how a sweep opens
|
|
11
|
-
* duplicates of Issues it already filed.
|
|
12
|
-
*
|
|
13
|
-
* The Issues that can possibly match are exactly those carrying an `audit::*`
|
|
14
|
-
* label, and there are tens of them, not hundreds. Listing them **once per run**
|
|
15
|
-
* and indexing their provenance footers answers every exact-fingerprint lookup
|
|
16
|
-
* locally, for free. The search API is then spent only where it is the only
|
|
17
|
-
* thing that can help: a finding with no exact hit, whose fingerprint may have
|
|
18
|
-
* drifted under a rewording.
|
|
19
|
-
*
|
|
20
|
-
* Pure: the caller injects the list port and this module performs no I/O.
|
|
2
|
+
* Local index of `audit::*` Issues by provenance footer, listed once per run.
|
|
3
|
+
* Search is far more rate-limited than list, so exact-fingerprint lookups are
|
|
4
|
+
* answered here and search is spent only on findings with no exact hit. Pure.
|
|
21
5
|
*/
|
|
22
6
|
|
|
23
7
|
import {
|
|
@@ -26,8 +10,6 @@ import {
|
|
|
26
10
|
} from '../findings/route-finding.js';
|
|
27
11
|
|
|
28
12
|
/**
|
|
29
|
-
* Add `record` to the list `map` keys under `key`.
|
|
30
|
-
*
|
|
31
13
|
* @param {Map<string, object[]>} map
|
|
32
14
|
* @param {string} key
|
|
33
15
|
* @param {object} record
|
|
@@ -39,10 +21,7 @@ function push(map, key, record) {
|
|
|
39
21
|
}
|
|
40
22
|
|
|
41
23
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* An issue carrying neither footer is indexed under nothing — it can never
|
|
45
|
-
* confirm a match, exactly as it could not when it came back from a search.
|
|
24
|
+
* An issue with neither footer is indexed under nothing.
|
|
46
25
|
*
|
|
47
26
|
* @param {Array<{ number: number, state: string, body?: string }>} issues
|
|
48
27
|
* @returns {{ byFingerprint: Map<string, object[]>, bySemanticKey: Map<string, object[]>, size: number }}
|
|
@@ -65,11 +44,8 @@ export function buildIssueIndex(issues) {
|
|
|
65
44
|
}
|
|
66
45
|
|
|
67
46
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* Order matters downstream: `routeFinding` keeps the first record contributed
|
|
71
|
-
* for an issue number, and the record retrieved by exact identity is the one
|
|
72
|
-
* that should survive into confirmation.
|
|
47
|
+
* Fingerprint hits first: `routeFinding` keeps the first record per issue
|
|
48
|
+
* number, and the exact-identity one should survive into confirmation.
|
|
73
49
|
*
|
|
74
50
|
* @param {{ byFingerprint: Map, bySemanticKey: Map }} index
|
|
75
51
|
* @param {string} sha
|
|
@@ -1,34 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Dedup needs exactly one thing from GitHub: the list of Issues carrying an
|
|
6
|
-
* `audit::*` label. Until Story #5301 the only way to get it was the provider,
|
|
7
|
-
* which spawns `gh`, so a host without a `gh` CLI — a Claude Code cloud
|
|
8
|
-
* sandbox, where `gh` is absent and direct API access is disabled but the
|
|
9
|
-
* GitHub MCP tools work fine — could not dedup at all. Every group classified
|
|
10
|
-
* `create` and a scheduled sweep re-filed findings it had already filed.
|
|
11
|
-
*
|
|
12
|
-
* `--issues-file <path>` breaks that coupling: the host fetches the list by
|
|
13
|
-
* whatever access path it has and hands over a JSON array. Nothing here knows
|
|
14
|
-
* how it was fetched, so MCP, REST, and a cached dump are all equally valid.
|
|
15
|
-
*
|
|
16
|
-
* A file that cannot be read as an issue array is a **hard error**, never a
|
|
17
|
-
* degrade. Falling back would mean "dedup did not run" on precisely the
|
|
18
|
-
* invocation whose whole purpose is that it does — and a create-only plan the
|
|
19
|
-
* operator reads as checked is how the duplicate-filing loop starts.
|
|
2
|
+
* `--issues-file`: a host-fetched `audit::*` issue corpus (MCP, REST, a dump),
|
|
3
|
+
* so dedup runs without `gh`. An unreadable file is a hard error, never a
|
|
4
|
+
* degrade — a silently create-only plan starts the duplicate-filing loop.
|
|
20
5
|
*/
|
|
21
6
|
|
|
22
7
|
import fs from 'node:fs';
|
|
23
8
|
|
|
24
9
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* `state_reason: not_planned`, …) onto `'closed'`.
|
|
28
|
-
*
|
|
29
|
-
* Shared by both corpus sources — the provider's `searchIssues` hits and the
|
|
30
|
-
* `--issues-file` array — so a host can hand over a raw `list_issues` result
|
|
31
|
-
* verbatim without knowing which spelling this repo's dedup expects.
|
|
10
|
+
* The one normaliser for every corpus source; any closed-ish `state` or
|
|
11
|
+
* `state_reason` spelling becomes `'closed'`.
|
|
32
12
|
*
|
|
33
13
|
* @param {object} hit
|
|
34
14
|
* @returns {{ number: number, state: 'open'|'closed', title: string, body: string }}
|
|
@@ -48,13 +28,6 @@ export function normaliseIssueHit(hit) {
|
|
|
48
28
|
}
|
|
49
29
|
|
|
50
30
|
/**
|
|
51
|
-
* Read and normalise a host-supplied issue corpus.
|
|
52
|
-
*
|
|
53
|
-
* `state` is read from either `state` or `state_reason`, so a closed-as-
|
|
54
|
-
* not-planned issue is recognised however the host's API spelled it. Only
|
|
55
|
-
* `number` and `body` are load-bearing: the number identifies the match and
|
|
56
|
-
* the body carries the provenance footers dedup confirms identity against.
|
|
57
|
-
*
|
|
58
31
|
* @param {string} filePath — path to a JSON array of issues.
|
|
59
32
|
* @param {{ readFileSyncImpl?: typeof fs.readFileSync }} [seams]
|
|
60
33
|
* @returns {Array<{ number: number, state: string, title: string, body: string }>}
|
|
@@ -94,9 +67,7 @@ export function loadIssuesFile(
|
|
|
94
67
|
}
|
|
95
68
|
|
|
96
69
|
/**
|
|
97
|
-
*
|
|
98
|
-
* numeric `number` can never confirm a match — exactly as it could not when it
|
|
99
|
-
* came back from a search — so it is dropped rather than indexed under nothing.
|
|
70
|
+
* Without a numeric `number` an entry can never confirm a match, so it drops.
|
|
100
71
|
*
|
|
101
72
|
* @param {unknown} entry
|
|
102
73
|
* @returns {boolean}
|
|
@@ -110,7 +81,6 @@ function isIssueLike(entry) {
|
|
|
110
81
|
}
|
|
111
82
|
|
|
112
83
|
/**
|
|
113
|
-
* Name what a non-array payload actually was, so the error points at the fix.
|
|
114
84
|
* @param {unknown} value
|
|
115
85
|
* @returns {string}
|
|
116
86
|
*/
|