mandrel 2.60.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 +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/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 +83 -239
- 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 +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 +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 +25 -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,30 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Extracts the `## Detailed Findings` section of an audit report and turns
|
|
5
|
-
* every `### <title>` block into a normalised finding record. Every audit lens
|
|
6
|
-
* report now shares one findings contract (Story #4625): a `Critical | High |
|
|
7
|
-
* Medium | Low` severity scale, a mandated `Location:` path anchor, and a
|
|
8
|
-
* dimension axis. Lenses still label the axes slightly differently — `Severity`
|
|
9
|
-
* vs `Impact`, `Dimension` vs `Category` vs `Type` — so the parser captures
|
|
10
|
-
* every key/value pair the block carries and normalises the two axes the
|
|
11
|
-
* downstream pipeline relies on (severity + dimension), harvesting the
|
|
12
|
-
* `Location:` field into `files[]` ahead of prose scraping.
|
|
13
|
-
*
|
|
14
|
-
* Pure: no filesystem I/O. The caller supplies the report text and source
|
|
15
|
-
* path; the parser returns plain objects.
|
|
2
|
+
* Parse `## Detailed Findings` of audit reports into normalised findings.
|
|
3
|
+
* Pure.
|
|
16
4
|
*/
|
|
17
5
|
|
|
18
6
|
import path from 'node:path';
|
|
19
7
|
|
|
20
8
|
import { normalizeSeverity } from '../findings/severity.js';
|
|
21
9
|
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// the second way: it parsed as prose, so the block carried no severity, and the
|
|
26
|
-
// grouping-header rule below then read the whole finding as an organisational
|
|
27
|
-
// heading. Both spellings are the same field.
|
|
10
|
+
// Accept the colon inside or outside the bold run (`**Severity:**` and
|
|
11
|
+
// `**Severity**:`); missing either drops the axis and misreads the finding as a
|
|
12
|
+
// grouping header.
|
|
28
13
|
const KEY_LINE = /^\s*-\s*\*\*([^:*]+?)\s*(?::\*\*|\*\*\s*:)\s*(.*)$/;
|
|
29
14
|
const HEADING_FINDING = /^(#{3,4})\s+(.+?)\s*$/;
|
|
30
15
|
const SEVERITY_KEY_LINE =
|
|
@@ -49,22 +34,9 @@ function unwrapInlineCode(value) {
|
|
|
49
34
|
}
|
|
50
35
|
|
|
51
36
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* The vocabulary itself is NOT written down here (Story #4877). This module used
|
|
56
|
-
* to carry its own alias table covering `critical|high|medium|mod|moderate|low`
|
|
57
|
-
* — four of the canonical five levels, missing `info`. A lens that graded a
|
|
58
|
-
* finding `Info` or `Informational` (which the shared severity scale now
|
|
59
|
-
* sanctions) therefore parsed to `null`, tallied as `unknown`, and was dropped
|
|
60
|
-
* by every severity-filtered run, `--severity low` included. Delegating to the
|
|
61
|
-
* canonical normaliser in `lib/findings/severity.js` means this parser cannot
|
|
62
|
-
* know a narrower vocabulary than the rest of the pipeline.
|
|
63
|
-
*
|
|
64
|
-
* `null` — rather than the normaliser's `info` fallback — remains the
|
|
65
|
-
* no-severity answer, because {@link deriveSeverity} walks several candidate
|
|
66
|
-
* keys and needs to distinguish "this key had no severity" from "this key said
|
|
67
|
-
* `info`".
|
|
37
|
+
* Delegates to the canonical normaliser so this parser never knows a narrower
|
|
38
|
+
* vocabulary than the pipeline. Returns `null` (not `info`) for no severity,
|
|
39
|
+
* so {@link deriveSeverity} can tell "no severity" from "said `info`".
|
|
68
40
|
*
|
|
69
41
|
* @param {unknown} token
|
|
70
42
|
* @returns {string|null}
|
|
@@ -98,36 +70,13 @@ function deriveDimension(fields, fallbackDimension) {
|
|
|
98
70
|
}
|
|
99
71
|
|
|
100
72
|
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
* on whatever path text happens to appear in the prose. The value may wrap the
|
|
106
|
-
* path in backticks and/or append a `:line` (or `:line:col`) suffix; both are
|
|
107
|
-
* stripped. Only tokens that look like paths (containing a separator) survive.
|
|
73
|
+
* Repo-relative path, or `null` for an absolute (outside `repoRoot`) or
|
|
74
|
+
* degenerate token. A bare root-level file (`AGENTS.md`) is accepted in
|
|
75
|
+
* structured fields; `requireSeparator` rejects it in prose, where it is more
|
|
76
|
+
* likely a word.
|
|
108
77
|
*
|
|
109
|
-
* @param {
|
|
110
|
-
* @
|
|
111
|
-
*/
|
|
112
|
-
/**
|
|
113
|
-
* Normalise a raw path token to a repo-relative path, or `null` when the
|
|
114
|
-
* token is not a usable file reference.
|
|
115
|
-
*
|
|
116
|
-
* Three shapes historically leaked through and poisoned grouping downstream:
|
|
117
|
-
* an **absolute** path (which can never match a repo-relative group key), a
|
|
118
|
-
* **degenerate** token such as a bare `/`, and — most damagingly — a
|
|
119
|
-
* **root-level** file such as `AGENTS.md`, which the old slash-only guard
|
|
120
|
-
* discarded outright even when it was the finding's explicit `Location:`.
|
|
121
|
-
*
|
|
122
|
-
* `requireSeparator` is what keeps that third fix from over-reaching. In the
|
|
123
|
-
* **structured** fields — the title anchor and `Location:` — a bare
|
|
124
|
-
* `AGENTS.md` is unambiguously a file, so the separator is not required. In
|
|
125
|
-
* free **prose**, a bare `description.md` is far more likely to be a word than
|
|
126
|
-
* a path, so the separator stays mandatory there.
|
|
127
|
-
*
|
|
128
|
-
* @param {string} raw — the token as it appeared in the report.
|
|
129
|
-
* @param {string} [repoRoot] — absolute repo root; absolute tokens beneath it
|
|
130
|
-
* are relativised. Omitted (the pure default) leaves absolutes to be dropped.
|
|
78
|
+
* @param {string} raw
|
|
79
|
+
* @param {string} [repoRoot] Absolute tokens beneath it are relativised.
|
|
131
80
|
* @param {{ requireSeparator?: boolean }} [options]
|
|
132
81
|
* @returns {string|null}
|
|
133
82
|
*/
|
|
@@ -151,8 +100,7 @@ function normalisePathToken(raw, repoRoot, { requireSeparator = false } = {}) {
|
|
|
151
100
|
}
|
|
152
101
|
}
|
|
153
102
|
}
|
|
154
|
-
//
|
|
155
|
-
// valid group key, so drop it rather than let it become one.
|
|
103
|
+
// Still absolute ⇒ outside the repo; never a valid group key.
|
|
156
104
|
if (out.startsWith('/') || out.startsWith('\\') || /^[A-Za-z]:/.test(out)) {
|
|
157
105
|
return null;
|
|
158
106
|
}
|
|
@@ -163,10 +111,8 @@ function normalisePathToken(raw, repoRoot, { requireSeparator = false } = {}) {
|
|
|
163
111
|
}
|
|
164
112
|
|
|
165
113
|
/**
|
|
166
|
-
* The
|
|
167
|
-
*
|
|
168
|
-
* the most reliable primary-file signal a block carries, so it seeds `files[]`
|
|
169
|
-
* ahead of `Location:` and prose scraping — `pickPrimaryFile` takes `files[0]`.
|
|
114
|
+
* The mandated title anchor (``### `path` — title``) is the strongest
|
|
115
|
+
* primary-file signal, so it seeds `files[0]` ahead of `Location:` and prose.
|
|
170
116
|
*/
|
|
171
117
|
function deriveTitleFile(title, repoRoot) {
|
|
172
118
|
const match = TITLE_ANCHOR.exec(typeof title === 'string' ? title : '');
|
|
@@ -175,6 +121,12 @@ function deriveTitleFile(title, repoRoot) {
|
|
|
175
121
|
return normalised ? [normalised] : [];
|
|
176
122
|
}
|
|
177
123
|
|
|
124
|
+
/**
|
|
125
|
+
* `Location:` paths with `:line` suffixes and backticks stripped.
|
|
126
|
+
*
|
|
127
|
+
* @param {Record<string, string>} fields
|
|
128
|
+
* @returns {string[]}
|
|
129
|
+
*/
|
|
178
130
|
function deriveLocationFiles(fields, repoRoot) {
|
|
179
131
|
const raw = fields.location;
|
|
180
132
|
if (typeof raw !== 'string' || raw.trim().length === 0) return [];
|
|
@@ -265,10 +217,6 @@ function splitFindingBlocks(reportText) {
|
|
|
265
217
|
}
|
|
266
218
|
|
|
267
219
|
/**
|
|
268
|
-
* Does this block carry the axis line that makes it a finding rather than a
|
|
269
|
-
* section header? The skeleton mandates `Severity` (or its `Impact` alias), so
|
|
270
|
-
* its absence is the signal that a heading is organisational.
|
|
271
|
-
*
|
|
272
220
|
* @param {{ bodyLines: string[] }} block
|
|
273
221
|
* @returns {boolean}
|
|
274
222
|
*/
|
|
@@ -277,12 +225,6 @@ function carriesSeverity(block) {
|
|
|
277
225
|
}
|
|
278
226
|
|
|
279
227
|
/**
|
|
280
|
-
* Does this block carry any `- **Key:** value` field bullet at all? A finding
|
|
281
|
-
* block is a field record; a grouping header is a heading with prose (or
|
|
282
|
-
* nothing) under it. Read together with {@link carriesSeverity} this is what
|
|
283
|
-
* lets an axis-less heading be recognised as organisational **without** having
|
|
284
|
-
* to see `####` children under it.
|
|
285
|
-
*
|
|
286
228
|
* @param {{ bodyLines: string[] }} block
|
|
287
229
|
* @returns {boolean}
|
|
288
230
|
*/
|
|
@@ -291,10 +233,8 @@ function carriesFieldBullet(block) {
|
|
|
291
233
|
}
|
|
292
234
|
|
|
293
235
|
/**
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* case — it used to parse as a severity-less finding with no files and no
|
|
297
|
-
* recommendation, which an unattended sweep then filed as an empty Story.
|
|
236
|
+
* No severity and no field bullets (e.g. a header over `_No findings._`) —
|
|
237
|
+
* never a finding, or an unattended sweep files an empty Story.
|
|
298
238
|
*
|
|
299
239
|
* @param {{ bodyLines: string[] }} block
|
|
300
240
|
* @returns {boolean}
|
|
@@ -304,29 +244,10 @@ function isEmptyBlock(block) {
|
|
|
304
244
|
}
|
|
305
245
|
|
|
306
246
|
/**
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
* (`### Perceivable`), each holding `####` finding blocks. Read flat, that
|
|
312
|
-
* report parsed as one severity-less finding per dimension, and the unattended
|
|
313
|
-
* sweep filed those empties. The subtree rule this applies, in order:
|
|
314
|
-
*
|
|
315
|
-
* 1. A block whose own body carries the severity axis **or any field
|
|
316
|
-
* bullet** is a finding. Its `####` sub-sections fold back into its body
|
|
317
|
-
* rather than splitting into phantom findings, so flat reports parse
|
|
318
|
-
* exactly as before.
|
|
319
|
-
* 2. A block whose title leads with a backticked path — the anchor the
|
|
320
|
-
* finding-block skeleton mandates — is a finding even when its own body
|
|
321
|
-
* is empty, because its fields live under a `#### Evidence`-style
|
|
322
|
-
* sub-section. Folding is what stops that sub-section's heading from
|
|
323
|
-
* becoming the finding's title.
|
|
324
|
-
* 3. Otherwise it is a grouping header when its children look like findings:
|
|
325
|
-
* any child carrying its own path anchor, or more than one child carrying
|
|
326
|
-
* the severity axis. A **single** axis-bearing child under an anchorless
|
|
327
|
-
* header is the `#### Evidence` shape again, so it folds.
|
|
328
|
-
* 4. A block with no children at all and nothing declared is a grouping
|
|
329
|
-
* header (or a stray heading) either way — it yields no finding.
|
|
247
|
+
* Is a `###` block a grouping header over `####` findings? Not if it declares
|
|
248
|
+
* fields or leads with a path anchor (its `#### Evidence` children fold in).
|
|
249
|
+
* Otherwise yes when it has no children, any anchored child, or more than one
|
|
250
|
+
* severity-bearing child; a single such child is the Evidence shape and folds.
|
|
330
251
|
*
|
|
331
252
|
* @param {{ title: string, bodyLines: string[] }} parent
|
|
332
253
|
* @param {Array<{ title: string, bodyLines: string[] }>} children
|
|
@@ -341,10 +262,6 @@ function isGroupingHeader(parent, children) {
|
|
|
341
262
|
}
|
|
342
263
|
|
|
343
264
|
/**
|
|
344
|
-
* Fold the flat heading stream into findings: emit a grouping header's
|
|
345
|
-
* children, fold a finding's sub-sections into its own body, and drop every
|
|
346
|
-
* block that declares nothing.
|
|
347
|
-
*
|
|
348
265
|
* @param {Array<{ level: number, title: string, bodyLines: string[] }>} blocks
|
|
349
266
|
* @returns {Array<{ level: number, title: string, bodyLines: string[] }>}
|
|
350
267
|
*/
|
|
@@ -383,11 +300,6 @@ function foldGroupingHeaders(blocks) {
|
|
|
383
300
|
}
|
|
384
301
|
|
|
385
302
|
/**
|
|
386
|
-
* Slice the `## Executive Summary` section out of a report, or `null` when the
|
|
387
|
-
* report declares none. The tally the cross-check trusts is the one the report
|
|
388
|
-
* envelope mandates *there*; a `Severity tally:` string anywhere else is prose
|
|
389
|
-
* quoting the format, not a declaration.
|
|
390
|
-
*
|
|
391
303
|
* @param {string} markdown
|
|
392
304
|
* @returns {{ start: number, end: number }|null} character offsets.
|
|
393
305
|
*/
|
|
@@ -403,22 +315,12 @@ function executiveSummaryRange(markdown) {
|
|
|
403
315
|
}
|
|
404
316
|
|
|
405
317
|
/**
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
* against what the parser actually extracted — a parse that silently drops
|
|
411
|
-
* findings is otherwise indistinguishable from a clean report. That only holds
|
|
412
|
-
* while exactly one line claims to be the tally. A report whose prose quotes
|
|
413
|
-
* the format a second time (a remediation section restating a lens's output,
|
|
414
|
-
* say) used to have whichever line the regex reached first silently adopted as
|
|
415
|
-
* the declaration, so the cross-check compared the parse against an arbitrary
|
|
416
|
-
* one of two numbers. Both are now reported and the report fails.
|
|
318
|
+
* The declared severity tally, for cross-checking the parse against what the
|
|
319
|
+
* lens says it found. Fails closed (`duplicate`) on more than one tally line,
|
|
320
|
+
* since adopting either would make the cross-check arbitrary. `Info` is never
|
|
321
|
+
* counted.
|
|
417
322
|
*
|
|
418
|
-
*
|
|
419
|
-
* scheduled work).
|
|
420
|
-
*
|
|
421
|
-
* @param {string} markdown — full report text.
|
|
323
|
+
* @param {string} markdown
|
|
422
324
|
* @returns {{ tally: {critical:number,high:number,medium:number,low:number}|null,
|
|
423
325
|
* matches: string[], duplicate: boolean }}
|
|
424
326
|
*/
|
|
@@ -430,8 +332,6 @@ export function readSeverityTally(markdown) {
|
|
|
430
332
|
const matches = [];
|
|
431
333
|
TALLY_LINE_GLOBAL.lastIndex = 0;
|
|
432
334
|
for (const hit of markdown.matchAll(TALLY_LINE_GLOBAL)) {
|
|
433
|
-
// Outside an Executive Summary the whole document is the scope; with one,
|
|
434
|
-
// a line beyond it is a stray that must not be adopted silently.
|
|
435
335
|
matches.push({ text: hit[0].trim(), groups: hit, index: hit.index });
|
|
436
336
|
}
|
|
437
337
|
const scoped = range
|
|
@@ -483,14 +383,9 @@ function parseBlockFields(bodyLines) {
|
|
|
483
383
|
}
|
|
484
384
|
|
|
485
385
|
/**
|
|
486
|
-
* Parse a single audit report's markdown text into a list of normalised
|
|
487
|
-
* findings.
|
|
488
|
-
*
|
|
489
386
|
* @param {object} params
|
|
490
|
-
* @param {string} params.markdown
|
|
491
|
-
* @param {string} params.sourceReport
|
|
492
|
-
* and dimension inference when the report omits a `Dimension:` / `Category:`
|
|
493
|
-
* / `Type:` line.
|
|
387
|
+
* @param {string} params.markdown
|
|
388
|
+
* @param {string} params.sourceReport Also the fallback dimension source.
|
|
494
389
|
* @returns {Array<{
|
|
495
390
|
* dimension: string,
|
|
496
391
|
* severity: 'critical'|'high'|'medium'|'low'|null,
|
|
@@ -547,13 +442,10 @@ export function parseAuditReport({ markdown, sourceReport, repoRoot }) {
|
|
|
547
442
|
}
|
|
548
443
|
|
|
549
444
|
/**
|
|
550
|
-
*
|
|
551
|
-
* `## Detailed Findings` section yield zero entries rather than throwing —
|
|
552
|
-
* an audit can legitimately come back empty.
|
|
445
|
+
* A report without `## Detailed Findings` yields no entries (legitimately empty).
|
|
553
446
|
*
|
|
554
447
|
* @param {Array<{ markdown: string, sourceReport: string }>} reports
|
|
555
|
-
* @param {{ repoRoot?: string }} [options]
|
|
556
|
-
* paths quoted in a report so they can match repo-relative group keys.
|
|
448
|
+
* @param {{ repoRoot?: string }} [options]
|
|
557
449
|
* @returns {Array<ReturnType<typeof parseAuditReport>[number]>}
|
|
558
450
|
*/
|
|
559
451
|
export function parseAuditReports(reports, { repoRoot } = {}) {
|
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Build the `/mandrel-plan --seed`-shaped one-pager markdown that the audit-to-
|
|
5
|
-
* stories Single-plan grouping path emits for `/mandrel-plan` to consume.
|
|
6
|
-
*
|
|
7
|
-
* The seed renders the canonical one-pager sections so the authoring
|
|
8
|
-
* pass can sharpen it without having to invent context:
|
|
9
|
-
* - Problem Statement (aggregated severity profile)
|
|
10
|
-
* - Recommended Direction (rollup of recommendations by dimension)
|
|
11
|
-
* - Key Assumptions (carries the source-report links forward)
|
|
12
|
-
* - MVP Scope (the findings themselves, flat — Story #5332)
|
|
13
|
-
* - Key Files (explicit file paths so `/mandrel-plan` authoring has concrete
|
|
14
|
-
* anchors)
|
|
15
|
-
* - Not Doing (out-of-scope items by convention)
|
|
16
|
-
*
|
|
17
|
-
* Pure: returns a string. The caller decides where to persist it.
|
|
2
|
+
* Render the `/mandrel-plan --seed` one-pager for the single-plan audit path.
|
|
3
|
+
* Pure: returns a string.
|
|
18
4
|
*/
|
|
19
5
|
|
|
20
6
|
import { SEVERITIES } from '../findings/severity.js';
|
|
@@ -39,12 +25,6 @@ const DIMENSION_LABEL = {
|
|
|
39
25
|
architecture: 'Architecture',
|
|
40
26
|
};
|
|
41
27
|
|
|
42
|
-
/**
|
|
43
|
-
* The severity profile in the seed's Problem Statement is ordered and bucketed
|
|
44
|
-
* by the canonical scale (Story #4877) rather than by a fourth local copy of
|
|
45
|
-
* it. The list this replaces omitted `info`, so an informational finding was
|
|
46
|
-
* absent from the profile the planner reads even when it survived the filter.
|
|
47
|
-
*/
|
|
48
28
|
const SEVERITY_ORDER = SEVERITIES;
|
|
49
29
|
|
|
50
30
|
function tallySeverities(findings) {
|
|
@@ -93,15 +73,8 @@ function formatRecommendedDirection(findings) {
|
|
|
93
73
|
}
|
|
94
74
|
|
|
95
75
|
/**
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* This section used to render one numbered bullet per `groupFindings` group
|
|
99
|
-
* under a `## Grouping` directive — a partition the seed had already decided
|
|
100
|
-
* before the planner read a word of it, and at a grain (`groupFindings`'s) the
|
|
101
|
-
* planner's cohesion judgment never got to review. The measured result was a
|
|
102
|
-
* sweep of 44 findings arriving as 18 Stories. The seed now states what was
|
|
103
|
-
* found and lets N reach the planner undecided; container grouping is Gate
|
|
104
|
-
* #3's call at persist, where N is known.
|
|
76
|
+
* Flat, not grouped: the seed must not pre-decide the Story partition; that
|
|
77
|
+
* is the planner's cohesion call.
|
|
105
78
|
*
|
|
106
79
|
* @param {object[]} findings
|
|
107
80
|
* @returns {string}
|
|
@@ -118,17 +91,9 @@ function formatFindingsList(findings) {
|
|
|
118
91
|
}
|
|
119
92
|
|
|
120
93
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* deliberately not attached to a visible bullet. Each group's fingerprint and
|
|
125
|
-
* location-based semantic-key footers are the identity the next sweep matches
|
|
126
|
-
* on (Story #4626), and the `audit::*` labels are the reason it ever looks at
|
|
127
|
-
* the issue at all — an indexed sweep answers exact lookups from the labelled
|
|
128
|
-
* pool without reaching the provider, so a Story missing the labels is
|
|
129
|
-
* invisible however good its fingerprints (Story #5307). They are HTML
|
|
130
|
-
* comments, so they carry no partition to the planner's eye while staying
|
|
131
|
-
* byte-identical to what the standalone-Stories path emits.
|
|
94
|
+
* Per-group dedup footers (fingerprint, semantic key, `audit::*` labels) as
|
|
95
|
+
* HTML comments: invisible to the planner, byte-identical to the standalone
|
|
96
|
+
* path. Without the labels an indexed sweep never sees the Story.
|
|
132
97
|
*
|
|
133
98
|
* @param {object[]} groups
|
|
134
99
|
* @returns {string}
|
|
@@ -1,30 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `groupFindings` detects `edges[]` between finding groups, but at emit time
|
|
6
|
-
* the groups have no issue numbers, so the ordering could only be rendered as
|
|
7
|
-
* prose. Every standalone audit Story therefore shipped with `depends_on: []`,
|
|
8
|
-
* and what actually kept a cohort from being co-dispatched onto colliding
|
|
9
|
-
* branches was an **accident**: siblings shared the sweep-wide audit provenance
|
|
10
|
-
* footers `plan-persist` stamps, and the delivery footprint guard scraped
|
|
11
|
-
* path-shaped tokens out of them. Story #5044 narrows that scrape, which is why
|
|
12
|
-
* this module lands with it — removing the accidental serializer without giving
|
|
13
|
-
* the cohort a real one would leave it less ordered than before.
|
|
14
|
-
*
|
|
15
|
-
* The shape is `plan-persist`'s two-pass crossing (`plan-persist/story-ops.js`),
|
|
16
|
-
* because it is the same problem: **create every issue first, then mirror the
|
|
17
|
-
* edges**. Both halves are written:
|
|
18
|
-
*
|
|
19
|
-
* 1. The **body footer** (`---` / `blocked by #N`) — canonical, parsed by
|
|
20
|
-
* `/mandrel-deliver`'s resolver, and the fallback when the dependencies API is
|
|
21
|
-
* unavailable.
|
|
22
|
-
* 2. The **native `blocked_by` relation** — visible in the GitHub UI,
|
|
23
|
-
* readable without parsing markdown, and settable by an operator later.
|
|
24
|
-
*
|
|
25
|
-
* Native mirroring is **non-fatal by design**, matching `plan-persist`: the
|
|
26
|
-
* footer has already been written by the time it runs, so a dependencies API
|
|
27
|
-
* that says no costs visibility, not ordering.
|
|
2
|
+
* Turn a created audit cohort's group edges into `blocked by #N` footers plus
|
|
3
|
+
* a native `blocked_by` mirror (non-fatal: the footer already orders).
|
|
28
4
|
*
|
|
29
5
|
* @module lib/audit-to-stories/wire-dependencies
|
|
30
6
|
*/
|
|
@@ -34,25 +10,15 @@ import { Logger } from '../Logger.js';
|
|
|
34
10
|
import { buildStoryBody } from './build-story-body.js';
|
|
35
11
|
|
|
36
12
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* Groups whose issue was not created — deduped against an existing Issue,
|
|
41
|
-
* suppressed by the ledger, or simply not in `issueByGroupKey` — are skipped
|
|
42
|
-
* rather than guessed at, and an edge pointing at one drops with them
|
|
43
|
-
* (`dependencyRefs` filters it). A `blocked by #undefined` would gate a Story
|
|
44
|
-
* on nothing forever, which is strictly worse than the un-ordered cohort this
|
|
45
|
-
* replaces.
|
|
13
|
+
* Groups (and edges to groups) with no created issue are skipped: a
|
|
14
|
+
* `blocked by #undefined` would gate a Story on nothing forever.
|
|
46
15
|
*
|
|
47
16
|
* @param {object} args
|
|
48
|
-
* @param {Array<object>} args.groups The `create`-eligible groups
|
|
49
|
-
* the order their issues were opened.
|
|
17
|
+
* @param {Array<object>} args.groups The `create`-eligible groups.
|
|
50
18
|
* @param {Array<{ fromGroupKey: string, toGroupKey: string }>} [args.edges]
|
|
51
19
|
* @param {Record<string, number>} args.issueByGroupKey Group key → issue number.
|
|
52
20
|
* @param {(issueNumber: number, body: string) => Promise<unknown>} args.updateBody
|
|
53
|
-
*
|
|
54
|
-
* @param {object|null} [args.provider] Provider for native edge mirroring.
|
|
55
|
-
* Omit (or pass one without the dependency ports) to write footers only.
|
|
21
|
+
* @param {object|null} [args.provider] Omit to write footers only.
|
|
56
22
|
* @returns {Promise<{
|
|
57
23
|
* storiesWired: number,
|
|
58
24
|
* bodiesUpdated: number,
|
|
@@ -92,13 +58,7 @@ export async function wireAuditStoryEdges({
|
|
|
92
58
|
}
|
|
93
59
|
|
|
94
60
|
/**
|
|
95
|
-
*
|
|
96
|
-
* whose issue also exists.
|
|
97
|
-
*
|
|
98
|
-
* A group with no resolvable blocker is deliberately left alone rather than
|
|
99
|
-
* rewritten to an identical body: an issue-body update is a mutation and a
|
|
100
|
-
* notification, and doing it for a no-op edit is noise on every Story of every
|
|
101
|
-
* sweep.
|
|
61
|
+
* Only groups with a resolvable blocker: a no-op body update still notifies.
|
|
102
62
|
*
|
|
103
63
|
* @param {object} args
|
|
104
64
|
* @returns {Array<{ groupKey: string, issueNumber: number, body: string, blockerKeys: string[] }>}
|
|
@@ -124,13 +84,8 @@ function collectWiredStories({ groups, edges, issueByGroupKey }) {
|
|
|
124
84
|
}
|
|
125
85
|
|
|
126
86
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* Two shape hazards this crossing inherits from `plan-persist`, both silent if
|
|
130
|
-
* missed: `applyBlockedByDependencies` indexes `slugToIssueNumber` with plain
|
|
131
|
-
* property access (so it must be a plain object, never a `Map` — a `Map` yields
|
|
132
|
-
* `undefined` for every lookup, skips every edge, and reports success having
|
|
133
|
-
* written nothing), and it reads `dependsOn`, not `depends_on`.
|
|
87
|
+
* Silent hazards: `slugToIssueNumber` must be a plain object (a `Map` skips
|
|
88
|
+
* every edge and reports success), and the helper reads `dependsOn`.
|
|
134
89
|
*
|
|
135
90
|
* @param {object} args
|
|
136
91
|
* @returns {Promise<{ edgesAdded: number, edgesSkipped: number, edgesFailed: number }|null>}
|
|
@@ -151,9 +106,7 @@ async function mirrorNativeEdges({ provider, wired, issueByGroupKey }) {
|
|
|
151
106
|
try {
|
|
152
107
|
const { gh, owner, repo } = provider.getDependencyWriteContext();
|
|
153
108
|
const summary = await applyBlockedByDependencies({
|
|
154
|
-
// The group key
|
|
155
|
-
// sides of an edge are keyed by — so `issueByGroupKey` is already the
|
|
156
|
-
// slug→number map the helper wants.
|
|
109
|
+
// The group key is the slug, so `issueByGroupKey` is the slug map.
|
|
157
110
|
stories: wired.map((s) => ({
|
|
158
111
|
slug: s.groupKey,
|
|
159
112
|
dependsOn: s.blockerKeys,
|
|
@@ -1,76 +1,37 @@
|
|
|
1
1
|
import { createGitInterface } from './git-utils.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* exists on `epic/<id>` HEAD, not against whatever `baselines/*.json` happens
|
|
9
|
-
* to be on the main checkout's working tree at close time. This helper is
|
|
10
|
-
* the single seam every gate uses to do that — it shells out to
|
|
11
|
-
* `git show <ref>:<path>`, parses the JSON, and memoizes the parsed object
|
|
12
|
-
* in an in-process Map keyed by `${ref}:${path}` so a single close run
|
|
13
|
-
* never re-spawns `git show` for the same (ref, path) pair.
|
|
14
|
-
*
|
|
15
|
-
* Caching contract:
|
|
16
|
-
* - The cache lives on the module — one instance per Node process. A
|
|
17
|
-
* close run is short-lived enough that staleness across invocations is
|
|
18
|
-
* not a concern (the next close re-imports the module).
|
|
19
|
-
* - Tests can call `clearBaselineCache()` to reset between cases. Real
|
|
20
|
-
* callers never need to.
|
|
21
|
-
*
|
|
22
|
-
* Failure modes:
|
|
23
|
-
* - Unresolvable ref / missing path → throws `Error` whose message names
|
|
24
|
-
* the ref AND the path so operators can act without scraping the
|
|
25
|
-
* stderr blob underneath.
|
|
26
|
-
* - `git show` succeeds but stdout is not parseable JSON → throws an
|
|
27
|
-
* Error tagged `parse-error` that names the ref + path.
|
|
28
|
-
* - The cache stores the parsed object on success; failures are NOT
|
|
29
|
-
* cached so a transient git failure doesn't poison subsequent calls.
|
|
4
|
+
* Read a JSON baseline at a git ref (`git show <ref>:<path>`), so gates
|
|
5
|
+
* compare against the committed baseline rather than the working tree.
|
|
6
|
+
* Memoized per process; failures are not cached, so a transient git error
|
|
7
|
+
* cannot poison later calls.
|
|
30
8
|
*/
|
|
31
9
|
|
|
32
10
|
const _cache = new Map();
|
|
33
11
|
|
|
34
12
|
/**
|
|
35
|
-
* Build the cache key. Exported for tests that want to assert exact key
|
|
36
|
-
* collisions (different refs vs. different paths must never collide).
|
|
37
|
-
*
|
|
38
13
|
* @param {string} ref
|
|
39
14
|
* @param {string} path
|
|
40
15
|
* @returns {string}
|
|
41
16
|
*/
|
|
42
17
|
export function cacheKeyFor(ref, path) {
|
|
43
|
-
//
|
|
44
|
-
// git ref name (per `git check-ref-format`) or a POSIX path component, so
|
|
45
|
-
// using it as the structural separator guarantees no collision between
|
|
46
|
-
// (ref="a", path="b:c") and (ref="a:b", path="c"). Tests assert this.
|
|
18
|
+
// NUL is legal in neither a ref nor a path, so keys cannot collide.
|
|
47
19
|
return `${ref}\u0000${path}`;
|
|
48
20
|
}
|
|
49
21
|
|
|
50
|
-
/**
|
|
51
|
-
* Reset the in-process cache. Tests use this to keep cases independent.
|
|
52
|
-
* Production callers never need to call it.
|
|
53
|
-
*/
|
|
22
|
+
/** Test-only cache reset. */
|
|
54
23
|
export function clearBaselineCache() {
|
|
55
24
|
_cache.clear();
|
|
56
25
|
}
|
|
57
26
|
|
|
58
27
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* @param {string} ref Git ref (e.g. `epic/1114`, `HEAD`).
|
|
62
|
-
* @param {string} path Repo-relative path (e.g. `baselines/maintainability.json`).
|
|
28
|
+
* @param {string} ref
|
|
29
|
+
* @param {string} path Repo-relative.
|
|
63
30
|
* @param {object} [opts]
|
|
64
|
-
* @param {string} [opts.cwd]
|
|
65
|
-
*
|
|
66
|
-
* @
|
|
67
|
-
*
|
|
68
|
-
* tests pass a mock.
|
|
69
|
-
* @returns {unknown} Parsed JSON value (`object` for baseline shapes; the
|
|
70
|
-
* helper does not constrain the schema — that contract belongs to the
|
|
71
|
-
* caller, e.g. `getBaseline` for the maintainability shape).
|
|
72
|
-
* @throws {Error} When the ref/path is unresolvable or the blob is not
|
|
73
|
-
* parseable JSON. The cache is NOT populated on failure.
|
|
31
|
+
* @param {string} [opts.cwd]
|
|
32
|
+
* @param {ReturnType<typeof createGitInterface>} [opts.git]
|
|
33
|
+
* @returns {unknown} Parsed JSON; the schema is the caller's contract.
|
|
34
|
+
* @throws {Error} Naming ref and path, on an unresolvable blob or bad JSON.
|
|
74
35
|
*/
|
|
75
36
|
export function readBaselineAtRef(ref, path, opts = {}) {
|
|
76
37
|
if (typeof ref !== 'string' || ref.length === 0) {
|
|
@@ -1,16 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// The shared envelope schema and the eight per-kind row/rollup schemas live
|
|
5
|
-
// under .agents/schemas/baselines/. Consumers compile them through a single
|
|
6
|
-
// AJV instance so cross-references (per-kind schemas `allOf` the envelope)
|
|
7
|
-
// resolve without each callsite re-registering the envelope.
|
|
8
|
-
//
|
|
9
|
-
// `BASELINE_SCHEMA_FILES` is the source of truth for the registered set —
|
|
10
|
-
// the mirror-drift test reads it back and compares against the on-disk
|
|
11
|
-
// directory listing to catch a new schema landing under baselines/ without
|
|
12
|
-
// being registered here.
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
1
|
+
// Baseline schema registry: one AJV instance, so per-kind schemas' `allOf`
|
|
2
|
+
// envelope references resolve. `BASELINE_SCHEMA_FILES` must match the
|
|
3
|
+
// on-disk listing (a mirror-drift test enforces it).
|
|
14
4
|
|
|
15
5
|
import { readFileSync } from 'node:fs';
|
|
16
6
|
import path from 'node:path';
|
|
@@ -35,24 +25,17 @@ export const BASELINE_ENVELOPE_FILE = 'baseline-envelope.schema.json';
|
|
|
35
25
|
|
|
36
26
|
/** Per-kind baseline schema filenames in stable registration order. */
|
|
37
27
|
export const BASELINE_KIND_SCHEMA_FILES = Object.freeze([
|
|
38
|
-
'lint.schema.json',
|
|
39
28
|
'coverage.schema.json',
|
|
40
29
|
'crap.schema.json',
|
|
41
30
|
'maintainability.schema.json',
|
|
42
31
|
'mutation.schema.json',
|
|
43
|
-
'lighthouse.schema.json',
|
|
44
32
|
'bundle-size.schema.json',
|
|
45
33
|
'duplication.schema.json',
|
|
46
34
|
]);
|
|
47
35
|
|
|
48
36
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* (Story #4902). They are registered here for two reasons: the AJV instance
|
|
52
|
-
* below is the one place a caller can compile a baselines-directory schema
|
|
53
|
-
* without re-registering the envelope, and the mirror-drift test compares
|
|
54
|
-
* this registry against the on-disk listing — an unregistered file there is
|
|
55
|
-
* drift regardless of which category it belongs to.
|
|
37
|
+
* Schemas for engine reports about baselines, not baselines themselves;
|
|
38
|
+
* registered because every file in the directory must be.
|
|
56
39
|
*/
|
|
57
40
|
const BASELINE_REPORT_SCHEMA_FILES = ['audit-baselines-envelope.schema.json'];
|
|
58
41
|
|
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Hoisted out of six baseline-kind modules (coverage, crap, lint,
|
|
6
|
-
* maintainability, mutation, lighthouse) which all shipped byte-equivalent
|
|
7
|
-
* copies of this predicate. See Story #2464.
|
|
2
|
+
* Identity or prefix-with-slash match of a row key against a component's
|
|
3
|
+
* `includes`.
|
|
8
4
|
*
|
|
9
5
|
* @param {{ includes?: string } | null | undefined} component
|
|
10
|
-
*
|
|
11
|
-
* when `includes` is not a string.
|
|
12
|
-
* @param {string} p
|
|
13
|
-
* The row's key field — `path` for code-shaped rows or `route` for
|
|
14
|
-
* lighthouse-shaped rows. The matcher is identity-equal or
|
|
15
|
-
* prefix-with-slash; callers normalize the row shape before invoking.
|
|
6
|
+
* @param {string} p Row key: `path`, or `route` for lighthouse.
|
|
16
7
|
* @returns {boolean}
|
|
17
8
|
*/
|
|
18
9
|
export function componentMatches(component, p) {
|