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,260 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI: third-party GitHub Action pinning gate.
|
|
3
|
-
*
|
|
4
|
-
* Story #4079 (audit::devops). Closes a supply-chain regression window the
|
|
5
|
-
* `ci.yml` / `release-please.yml` comments *claimed* was guarded by a
|
|
6
|
-
* nonexistent `npm run audit-security` gate. There is no such npm script;
|
|
7
|
-
* `audit-security` is only a manual `/audit-security` slash-command lens.
|
|
8
|
-
* Nothing actually enforced that third-party `uses:` refs stay SHA-pinned,
|
|
9
|
-
* so a future edit reverting `trufflehog@<sha>` to `@main` would pass CI
|
|
10
|
-
* silently.
|
|
11
|
-
*
|
|
12
|
-
* This script scans `.github/workflows/*.yml` (and `*.yaml`), extracts every
|
|
13
|
-
* `uses:` ref, and fails the build when a **third-party** action (anything
|
|
14
|
-
* not under the first-party `actions/*` org) is pinned to a floating ref
|
|
15
|
-
* instead of a full 40-char commit SHA. First-party `actions/*` refs are
|
|
16
|
-
* allowed on major-version tags (`@v4`) — Dependabot's `github-actions`
|
|
17
|
-
* ecosystem bumps those in-place, matching the rationale in the workflow
|
|
18
|
-
* file headers.
|
|
19
|
-
*
|
|
20
|
-
* A "floating ref" is any of:
|
|
21
|
-
* - a branch head: `@main`, `@master`
|
|
22
|
-
* - a tag / partial-SHA that is not a full 40-hex-char commit SHA
|
|
23
|
-
* (`@v5`, `@v3.95.3`, `@release`, a 7-char short SHA, …)
|
|
24
|
-
*
|
|
25
|
-
* Contract:
|
|
26
|
-
* - Scans the workflows directory (default `.github/workflows`, override
|
|
27
|
-
* with `--dir <path>`).
|
|
28
|
-
* - Prints `<file>:<lineNo> <ref> — <reason>` for each violation, then a
|
|
29
|
-
* one-line summary even on a clean scan so operators see the "ok" signal.
|
|
30
|
-
* - With `--json`: writes a structured envelope to stdout and skips the
|
|
31
|
-
* human summary.
|
|
32
|
-
* - Exit codes: 0 = no violations; 1 = at least one floating third-party
|
|
33
|
-
* ref. A missing / empty workflows directory exits 0 (nothing to gate).
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import fs from 'node:fs';
|
|
37
|
-
import path from 'node:path';
|
|
38
|
-
import process from 'node:process';
|
|
39
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Parse argv for `--dir <path>` and `--json`. Exported so unit tests can pin
|
|
43
|
-
* the parser.
|
|
44
|
-
*
|
|
45
|
-
* @param {string[]} argv
|
|
46
|
-
* @returns {{ dir: string | null, json: boolean }}
|
|
47
|
-
*/
|
|
48
|
-
export function parseArgv(argv = []) {
|
|
49
|
-
let dir = null;
|
|
50
|
-
let json = false;
|
|
51
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
52
|
-
const a = argv[i];
|
|
53
|
-
if (a === '--dir') {
|
|
54
|
-
const next = argv[i + 1];
|
|
55
|
-
if (next && !next.startsWith('--')) {
|
|
56
|
-
dir = next;
|
|
57
|
-
i += 1;
|
|
58
|
-
}
|
|
59
|
-
} else if (a === '--json') {
|
|
60
|
-
json = true;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return { dir, json };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Is the given ref suffix a full 40-char hex commit SHA?
|
|
68
|
-
*
|
|
69
|
-
* @param {string} ref The portion after the `@` in a `uses:` value.
|
|
70
|
-
* @returns {boolean}
|
|
71
|
-
*/
|
|
72
|
-
export function isFullSha(ref) {
|
|
73
|
-
return /^[0-9a-f]{40}$/i.test(ref);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Is the action a first-party `actions/*` action (e.g. `actions/checkout`)?
|
|
78
|
-
* First-party refs are allowed to float on major-version tags because
|
|
79
|
-
* Dependabot's `github-actions` ecosystem bumps them in-place.
|
|
80
|
-
*
|
|
81
|
-
* Local (`./…`) and reusable-workflow (`owner/repo/.github/workflows/x.yml`)
|
|
82
|
-
* refs and Docker refs (`docker://…`) are out of scope for the SHA-pin gate;
|
|
83
|
-
* `isFirstParty` only matters for `owner/repo[@ref]` registry actions.
|
|
84
|
-
*
|
|
85
|
-
* @param {string} action The portion before the `@` in a `uses:` value.
|
|
86
|
-
* @returns {boolean}
|
|
87
|
-
*/
|
|
88
|
-
export function isFirstParty(action) {
|
|
89
|
-
return /^actions\//.test(action);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Pure helper: scan a single workflow file's text for `uses:` refs and return
|
|
94
|
-
* the violations. A violation is a third-party `owner/repo@ref` where `ref`
|
|
95
|
-
* is not a full 40-char SHA.
|
|
96
|
-
*
|
|
97
|
-
* Skips:
|
|
98
|
-
* - local actions (`uses: ./path`)
|
|
99
|
-
* - Docker refs (`uses: docker://…`)
|
|
100
|
-
* - first-party `actions/*` refs (allowed on major-version tags)
|
|
101
|
-
* - refs with no `@` (pinned by default branch implicitly — flagged as a
|
|
102
|
-
* violation: an unpinned third-party ref floats on the default branch)
|
|
103
|
-
*
|
|
104
|
-
* @param {string} file Relative file label used in violation rows.
|
|
105
|
-
* @param {string} text The file contents.
|
|
106
|
-
* @returns {Array<{ file: string, line: number, action: string, ref: string | null, reason: string }>}
|
|
107
|
-
*/
|
|
108
|
-
export function scanWorkflowText(file, text) {
|
|
109
|
-
const violations = [];
|
|
110
|
-
const lines = text.split(/\r?\n/);
|
|
111
|
-
// Match `uses:` values, optionally quoted. The value runs until whitespace
|
|
112
|
-
// or a `#` comment. Capture the raw value for downstream parsing.
|
|
113
|
-
const usesRe = /^\s*(?:-\s*)?uses:\s*['"]?([^'"#\s]+)['"]?/;
|
|
114
|
-
for (let i = 0; i < lines.length; i += 1) {
|
|
115
|
-
const m = usesRe.exec(lines[i]);
|
|
116
|
-
if (!m) continue;
|
|
117
|
-
const value = m[1];
|
|
118
|
-
const lineNo = i + 1;
|
|
119
|
-
// Local actions and Docker refs are out of scope for the SHA-pin gate.
|
|
120
|
-
if (value.startsWith('./') || value.startsWith('docker://')) continue;
|
|
121
|
-
const atIndex = value.indexOf('@');
|
|
122
|
-
const action = atIndex === -1 ? value : value.slice(0, atIndex);
|
|
123
|
-
const ref = atIndex === -1 ? null : value.slice(atIndex + 1);
|
|
124
|
-
// First-party actions/* may float on major-version tags.
|
|
125
|
-
if (isFirstParty(action)) continue;
|
|
126
|
-
if (ref === null) {
|
|
127
|
-
violations.push({
|
|
128
|
-
file,
|
|
129
|
-
line: lineNo,
|
|
130
|
-
action,
|
|
131
|
-
ref: null,
|
|
132
|
-
reason: 'third-party action with no ref floats on the default branch',
|
|
133
|
-
});
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (!isFullSha(ref)) {
|
|
137
|
-
const floating = ref === 'main' || ref === 'master';
|
|
138
|
-
violations.push({
|
|
139
|
-
file,
|
|
140
|
-
line: lineNo,
|
|
141
|
-
action,
|
|
142
|
-
ref,
|
|
143
|
-
reason: floating
|
|
144
|
-
? `third-party action pinned to branch head @${ref} (CWE-1357)`
|
|
145
|
-
: `third-party action @${ref} is not a full 40-char commit SHA`,
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return violations;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Enumerate workflow files (`*.yml` / `*.yaml`) directly under `dir`.
|
|
154
|
-
* Returns absolute paths sorted for deterministic output. A missing directory
|
|
155
|
-
* yields an empty list.
|
|
156
|
-
*
|
|
157
|
-
* @param {string} dir Absolute workflows directory.
|
|
158
|
-
* @returns {string[]}
|
|
159
|
-
*/
|
|
160
|
-
export function listWorkflowFiles(dir) {
|
|
161
|
-
let entries;
|
|
162
|
-
try {
|
|
163
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
164
|
-
} catch {
|
|
165
|
-
return [];
|
|
166
|
-
}
|
|
167
|
-
return entries
|
|
168
|
-
.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name))
|
|
169
|
-
.map((e) => path.join(dir, e.name))
|
|
170
|
-
.sort();
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Pure helper: render the human-readable report. One line per violation
|
|
175
|
-
* followed by a one-line summary. The summary carries a `(gate fail)` /
|
|
176
|
-
* `(ok)` marker so the result is visible in CI output.
|
|
177
|
-
*
|
|
178
|
-
* @param {Array<{ file: string, line: number, action: string, ref: string | null, reason: string }>} violations
|
|
179
|
-
* @returns {string}
|
|
180
|
-
*/
|
|
181
|
-
export function renderReport(violations) {
|
|
182
|
-
const lines = [];
|
|
183
|
-
for (const v of violations) {
|
|
184
|
-
const refLabel = v.ref === null ? '(no ref)' : `@${v.ref}`;
|
|
185
|
-
lines.push(`${v.file}:${v.line} ${v.action}${refLabel} — ${v.reason}`);
|
|
186
|
-
}
|
|
187
|
-
const tag = violations.length > 0 ? '(gate fail)' : '(ok)';
|
|
188
|
-
lines.push(`[action-pinning] violations=${violations.length} ${tag}`);
|
|
189
|
-
return lines.join('\n');
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Top-level CLI entry. Exported so tests can drive the full pipeline against a
|
|
194
|
-
* fixture workflows directory without touching the repo's real workflows.
|
|
195
|
-
*
|
|
196
|
-
* @param {{
|
|
197
|
-
* argv?: string[],
|
|
198
|
-
* cwd?: string,
|
|
199
|
-
* stdout?: { write: (s: string) => void },
|
|
200
|
-
* stderr?: { write: (s: string) => void },
|
|
201
|
-
* }} [opts]
|
|
202
|
-
* @returns {Promise<number>} exit code: 0 = clean; 1 = floating third-party ref
|
|
203
|
-
*/
|
|
204
|
-
export async function runCli({
|
|
205
|
-
argv = process.argv.slice(2),
|
|
206
|
-
cwd = process.cwd(),
|
|
207
|
-
stdout = process.stdout,
|
|
208
|
-
stderr = process.stderr,
|
|
209
|
-
} = {}) {
|
|
210
|
-
const { dir, json } = parseArgv(argv);
|
|
211
|
-
const resolvedDir = path.resolve(
|
|
212
|
-
cwd,
|
|
213
|
-
dir ?? path.join('.github', 'workflows'),
|
|
214
|
-
);
|
|
215
|
-
|
|
216
|
-
const files = listWorkflowFiles(resolvedDir);
|
|
217
|
-
const violations = [];
|
|
218
|
-
for (const file of files) {
|
|
219
|
-
let text;
|
|
220
|
-
try {
|
|
221
|
-
text = fs.readFileSync(file, 'utf-8');
|
|
222
|
-
} catch {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
violations.push(...scanWorkflowText(path.relative(cwd, file), text));
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
const exitCode = violations.length > 0 ? 1 : 0;
|
|
229
|
-
|
|
230
|
-
if (json) {
|
|
231
|
-
const envelope = {
|
|
232
|
-
kind: 'action-pinning-report',
|
|
233
|
-
dir: resolvedDir,
|
|
234
|
-
filesScanned: files.length,
|
|
235
|
-
violations,
|
|
236
|
-
exitCode,
|
|
237
|
-
};
|
|
238
|
-
stdout.write(`${JSON.stringify(envelope, null, 2)}\n`);
|
|
239
|
-
} else {
|
|
240
|
-
if (files.length === 0) {
|
|
241
|
-
stderr.write(
|
|
242
|
-
`[action-pinning] ⚠ no workflow files found under ${resolvedDir}\n`,
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
stdout.write(`\n--- action-pinning scan ---\n`);
|
|
246
|
-
stdout.write(`${renderReport(violations)}\n`);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
return exitCode;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async function main() {
|
|
253
|
-
return runCli();
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
runAsCli(import.meta.url, main, {
|
|
257
|
-
source: 'action-pinning',
|
|
258
|
-
propagateExitCode: true,
|
|
259
|
-
errorPrefix: '[action-pinning] ❌ Fatal error',
|
|
260
|
-
});
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CLI: attribute a red `npm audit` result to the diff or to the merge base.
|
|
4
|
-
*
|
|
5
|
-
* Runs from `ci.yml` immediately after the required "Dependency Vulnerability
|
|
6
|
-
* Audit (SCA)" step fails, and only on a pull request. It re-audits the merge
|
|
7
|
-
* base's committed lockfile and says, as the first line a reader sees,
|
|
8
|
-
* whether this branch caused the failure.
|
|
9
|
-
*
|
|
10
|
-
* The verdict never changes whether the branch may land — see
|
|
11
|
-
* `attributionExitCode` in `lib/audit-attribution.js`. It changes how long it
|
|
12
|
-
* takes to understand why it may not.
|
|
13
|
-
*
|
|
14
|
-
* Exit codes:
|
|
15
|
-
* 0 — the probe could not reach a verdict (`unknown`); the SCA step's own
|
|
16
|
-
* failure stands unmodified.
|
|
17
|
-
* 1 — a verdict was reached: `pre-existing` or `introduced-by-this-diff`.
|
|
18
|
-
* Both fail, because the advisory is real either way.
|
|
19
|
-
*/
|
|
20
|
-
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
21
|
-
import { tmpdir } from 'node:os';
|
|
22
|
-
import path from 'node:path';
|
|
23
|
-
import process from 'node:process';
|
|
24
|
-
|
|
25
|
-
import {
|
|
26
|
-
attributionExitCode,
|
|
27
|
-
auditAdvisories,
|
|
28
|
-
deriveVerdict,
|
|
29
|
-
diffAdvisories,
|
|
30
|
-
renderAdvisoryDetail,
|
|
31
|
-
renderAttribution,
|
|
32
|
-
UNKNOWN,
|
|
33
|
-
} from './lib/audit-attribution.js';
|
|
34
|
-
import { execFileCapture } from './lib/child-exec.js';
|
|
35
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
36
|
-
import { Logger } from './lib/Logger.js';
|
|
37
|
-
|
|
38
|
-
/** The label the nightly sweep keys its reusable tracking issue on. */
|
|
39
|
-
const TRACKING_LABEL = 'meta::dependency-advisory';
|
|
40
|
-
|
|
41
|
-
const HELP = {
|
|
42
|
-
invocation:
|
|
43
|
-
'node .agents/scripts/check-audit-attribution.js --base <ref> [--cwd <dir>]',
|
|
44
|
-
summary:
|
|
45
|
-
'Say whether a red high-severity npm advisory came from this pull request or was already on its merge base.',
|
|
46
|
-
flags: [
|
|
47
|
-
['--base <ref>', 'Base commit or ref to attribute against. Required.'],
|
|
48
|
-
['--cwd <dir>', 'Repository root. Default: process.cwd().'],
|
|
49
|
-
[
|
|
50
|
-
'--no-tracking-issue',
|
|
51
|
-
"Skip the `gh issue list` lookup for the nightly sweep's tracking issue.",
|
|
52
|
-
],
|
|
53
|
-
],
|
|
54
|
-
notes: [
|
|
55
|
-
'Run it only after the required SCA step has already failed — it re-audits\nthe base to attribute that failure, and reports `unknown` when the head\naudits clean.',
|
|
56
|
-
"Exit codes:\n 0 unknown — the probe degraded; the SCA step's own failure stands\n 1 a verdict was reached (pre-existing or introduced-by-this-diff)",
|
|
57
|
-
'Both real verdicts exit 1. A check that passed on `pre-existing` would let\nadvisories accumulate on `main` unnoticed, which is what the nightly sweep\n(.github/workflows/dependency-audit-cron.yml) exists to prevent.',
|
|
58
|
-
],
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export function parseArgs(argv) {
|
|
62
|
-
const out = { base: null, cwd: process.cwd(), trackingIssue: true };
|
|
63
|
-
for (let i = 2; i < argv.length; i += 1) {
|
|
64
|
-
// Read the option KEY, not the dashed spelling: the key is what the
|
|
65
|
-
// negation guard and every reader below name.
|
|
66
|
-
const key = argv[i].replace(/^--/, '');
|
|
67
|
-
if (key === 'base') out.base = argv[++i] ?? null;
|
|
68
|
-
else if (key === 'cwd') out.cwd = argv[++i] ?? out.cwd;
|
|
69
|
-
// A runner with no `gh` credentials would spend a subprocess to fail; the
|
|
70
|
-
// verdict never depended on the lookup, so let the caller skip it.
|
|
71
|
-
else if (key === 'no-tracking-issue') out.trackingIssue = false;
|
|
72
|
-
}
|
|
73
|
-
return out;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Materialize the base commit's manifest pair into a scratch directory.
|
|
78
|
-
*
|
|
79
|
-
* Read out of git rather than from a checkout — the job's working tree is the
|
|
80
|
-
* head, and swapping files in it to run a probe is exactly the kind of side
|
|
81
|
-
* effect this must not have.
|
|
82
|
-
*
|
|
83
|
-
* @returns {string} the scratch directory (caller removes it)
|
|
84
|
-
*/
|
|
85
|
-
function materializeBase({ cwd, base, git }) {
|
|
86
|
-
const dir = mkdtempSync(path.join(tmpdir(), 'audit-attribution-'));
|
|
87
|
-
for (const file of ['package.json', 'package-lock.json']) {
|
|
88
|
-
writeFileSync(path.join(dir, file), git(cwd, 'show', `${base}:${file}`));
|
|
89
|
-
}
|
|
90
|
-
return dir;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// `execFileCapture` owns the stdout ceiling, `shell: false` and error
|
|
94
|
-
// normalisation for the whole tree — a lockfile is large enough that a
|
|
95
|
-
// re-forked local ceiling would be a real defect, not a style point.
|
|
96
|
-
const defaultGit = (cwd, ...args) => execFileCapture('git', args, { cwd });
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* The decision core, with every I/O collaborator injectable
|
|
100
|
-
* (`.agents/rules/test-seams.md` rules 1-2, 4) so the whole verdict table is
|
|
101
|
-
* reachable without a git history, a network, or an npm spawn.
|
|
102
|
-
*
|
|
103
|
-
* @returns {{ verdict: string, exitCode: number, lines: string[] }}
|
|
104
|
-
*/
|
|
105
|
-
export function runAttribution(argv = process.argv, deps = {}) {
|
|
106
|
-
const {
|
|
107
|
-
git = defaultGit,
|
|
108
|
-
auditHead = auditAdvisories,
|
|
109
|
-
auditBase = auditAdvisories,
|
|
110
|
-
materialize = materializeBase,
|
|
111
|
-
lookupTrackingIssue = defaultLookupTrackingIssue,
|
|
112
|
-
cleanup = (dir) => rmSync(dir, { recursive: true, force: true }),
|
|
113
|
-
logger = Logger,
|
|
114
|
-
} = deps;
|
|
115
|
-
const args = parseArgs(argv);
|
|
116
|
-
|
|
117
|
-
if (!args.base) {
|
|
118
|
-
const lines = renderAttribution({
|
|
119
|
-
verdict: UNKNOWN,
|
|
120
|
-
reason: 'no --base ref was supplied',
|
|
121
|
-
});
|
|
122
|
-
for (const line of lines) logger.info(line);
|
|
123
|
-
return { verdict: UNKNOWN, exitCode: 0, lines };
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const head = auditTheHead({ args, auditHead });
|
|
127
|
-
if (head.reason) {
|
|
128
|
-
return report({ verdict: UNKNOWN, args, logger, reason: head.reason });
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const { baseAudit, reason } = auditTheBase({
|
|
132
|
-
args,
|
|
133
|
-
git,
|
|
134
|
-
auditBase,
|
|
135
|
-
materialize,
|
|
136
|
-
cleanup,
|
|
137
|
-
});
|
|
138
|
-
const { introduced, preExisting } = diffAdvisories({
|
|
139
|
-
head: head.advisories,
|
|
140
|
-
base: baseAudit?.advisories ?? null,
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
// Per advisory: the merge base is "already failing for this" exactly when it
|
|
144
|
-
// carries every advisory the head does. A base red for its own advisory must
|
|
145
|
-
// not absolve a diff that added a different one.
|
|
146
|
-
const verdict = deriveVerdict({
|
|
147
|
-
headFailed: true,
|
|
148
|
-
baseAudit: baseAudit && { failed: introduced.length === 0 },
|
|
149
|
-
});
|
|
150
|
-
return report({
|
|
151
|
-
verdict,
|
|
152
|
-
args,
|
|
153
|
-
logger,
|
|
154
|
-
reason,
|
|
155
|
-
trackingIssue: resolveTrackingIssue({
|
|
156
|
-
verdict,
|
|
157
|
-
args,
|
|
158
|
-
lookupTrackingIssue,
|
|
159
|
-
}),
|
|
160
|
-
introduced,
|
|
161
|
-
preExisting,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Audit the head tree, converting both no-verdict cases — the audit itself
|
|
167
|
-
* broke, or the head is clean — into a `reason` the caller reports as
|
|
168
|
-
* `unknown`. Neither is an accusation, and neither is worth auditing a base for.
|
|
169
|
-
*
|
|
170
|
-
* @param {{ args: object, auditHead: Function }} ctx
|
|
171
|
-
* @returns {{ advisories?: Array<object>, reason: string|null }}
|
|
172
|
-
*/
|
|
173
|
-
function auditTheHead({ args, auditHead }) {
|
|
174
|
-
try {
|
|
175
|
-
const head = auditHead(args.cwd);
|
|
176
|
-
return head.failed
|
|
177
|
-
? { advisories: head.advisories, reason: null }
|
|
178
|
-
: {
|
|
179
|
-
reason:
|
|
180
|
-
'the head tree audits clean, so there is nothing to attribute',
|
|
181
|
-
};
|
|
182
|
-
} catch (err) {
|
|
183
|
-
return { reason: msg(err) };
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Look the nightly sweep's tracking issue up, unless there is no verdict to
|
|
189
|
-
* attach it to or `--no-tracking-issue` said not to spend the round-trip.
|
|
190
|
-
*
|
|
191
|
-
* @param {{ verdict: string, args: object, lookupTrackingIssue: Function }} ctx
|
|
192
|
-
* @returns {number|null}
|
|
193
|
-
*/
|
|
194
|
-
function resolveTrackingIssue({ verdict, args, lookupTrackingIssue }) {
|
|
195
|
-
if (verdict === UNKNOWN || !args.trackingIssue) return null;
|
|
196
|
-
return safeLookup(lookupTrackingIssue, args.cwd);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Materialize the merge base and audit it, converting every way that can fail
|
|
201
|
-
* into a `reason` rather than a throw. The scratch directory is always removed.
|
|
202
|
-
*
|
|
203
|
-
* @param {object} ctx
|
|
204
|
-
* @returns {{ baseAudit: object|null, reason: string|null }}
|
|
205
|
-
*/
|
|
206
|
-
function auditTheBase({ args, git, auditBase, materialize, cleanup }) {
|
|
207
|
-
let dir = null;
|
|
208
|
-
try {
|
|
209
|
-
dir = materialize({ cwd: args.cwd, base: args.base, git });
|
|
210
|
-
return { baseAudit: auditBase(dir), reason: null };
|
|
211
|
-
} catch (err) {
|
|
212
|
-
return { baseAudit: null, reason: msg(err) };
|
|
213
|
-
} finally {
|
|
214
|
-
if (dir) {
|
|
215
|
-
try {
|
|
216
|
-
cleanup(dir);
|
|
217
|
-
} catch {
|
|
218
|
-
// A leaked scratch dir under the OS temp root is not worth failing a
|
|
219
|
-
// report over.
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function msg(err) {
|
|
226
|
-
return String(err?.message ?? err).slice(0, 200);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function report({
|
|
230
|
-
verdict,
|
|
231
|
-
args,
|
|
232
|
-
logger,
|
|
233
|
-
reason = null,
|
|
234
|
-
trackingIssue = null,
|
|
235
|
-
introduced = [],
|
|
236
|
-
preExisting = [],
|
|
237
|
-
}) {
|
|
238
|
-
const lines = [
|
|
239
|
-
...renderAttribution({
|
|
240
|
-
verdict,
|
|
241
|
-
baseRef: args.base,
|
|
242
|
-
trackingIssue,
|
|
243
|
-
reason,
|
|
244
|
-
}),
|
|
245
|
-
// The two lists are reported separately even when the verdict is
|
|
246
|
-
// `introduced-by-this-diff`: an author fixing B still needs to know A is
|
|
247
|
-
// not theirs.
|
|
248
|
-
...renderAdvisoryDetail({ introduced, preExisting }),
|
|
249
|
-
];
|
|
250
|
-
for (const line of lines) logger.info(line);
|
|
251
|
-
return {
|
|
252
|
-
verdict,
|
|
253
|
-
exitCode: attributionExitCode(verdict),
|
|
254
|
-
lines,
|
|
255
|
-
introduced,
|
|
256
|
-
preExisting,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Look up the open tracking issue by LABEL, not a title search: GitHub's
|
|
262
|
-
* issue search index lags, and the nightly sweep keys the same issue the same
|
|
263
|
-
* way for the same reason.
|
|
264
|
-
*/
|
|
265
|
-
function defaultLookupTrackingIssue(cwd) {
|
|
266
|
-
const out = execFileCapture(
|
|
267
|
-
'gh',
|
|
268
|
-
[
|
|
269
|
-
'issue',
|
|
270
|
-
'list',
|
|
271
|
-
'--label',
|
|
272
|
-
TRACKING_LABEL,
|
|
273
|
-
'--state',
|
|
274
|
-
'open',
|
|
275
|
-
'--limit',
|
|
276
|
-
'1',
|
|
277
|
-
'--json',
|
|
278
|
-
'number',
|
|
279
|
-
'--jq',
|
|
280
|
-
'.[0].number // empty',
|
|
281
|
-
],
|
|
282
|
-
{ cwd },
|
|
283
|
-
).trim();
|
|
284
|
-
return out ? Number(out) : null;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
function safeLookup(lookup, cwd) {
|
|
288
|
-
try {
|
|
289
|
-
const n = lookup(cwd);
|
|
290
|
-
return Number.isInteger(n) ? n : null;
|
|
291
|
-
} catch {
|
|
292
|
-
// No token, no network, no `gh` — the verdict is still worth printing.
|
|
293
|
-
return null;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
runAsCli(import.meta.url, async () => runAttribution().exitCode, {
|
|
298
|
-
source: 'audit-attribution',
|
|
299
|
-
propagateExitCode: true,
|
|
300
|
-
errorPrefix: '[audit-attribution] ❌ Fatal error',
|
|
301
|
-
usage: HELP,
|
|
302
|
-
});
|