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,30 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* audit-to-stories.js —
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* The CLI exposes three deterministic sub-commands the host workflow
|
|
6
|
-
* (`/audit-to-stories`) invokes between HITL gates:
|
|
7
|
-
*
|
|
8
|
-
* --scan [--glob <pattern>] [--severity <threshold>]
|
|
9
|
-
* Parse every audit-*-results.md under the glob, normalise findings,
|
|
10
|
-
* stamp fingerprints, group cross-audit, and (when a provider is
|
|
11
|
-
* available) classify each group as create / skip-open / skip-reoccurring.
|
|
12
|
-
* Emits a single `audit-to-stories-plan.json` envelope to --out (or
|
|
13
|
-
* stdout when --json is set).
|
|
14
|
-
*
|
|
15
|
-
* --emit-plan-seed --plan <plan.json> --out <path>
|
|
16
|
-
* Read the plan envelope from disk, render the `/mandrel-plan --seed`
|
|
17
|
-
* seed markdown, persist to --out.
|
|
18
|
-
*
|
|
19
|
-
* --emit-stories --plan <plan.json>
|
|
20
|
-
* Read the plan envelope from disk, render the per-group `{ title,
|
|
21
|
-
* body, labels }` objects. The host LLM consumes the JSON and calls
|
|
22
|
-
* the GitHub provider (gh / mcp__github__issue_write) to open one
|
|
23
|
-
* Issue per group.
|
|
24
|
-
*
|
|
25
|
-
* Per .agents/rules/orchestration-error-handling.md, this CLI throws on
|
|
26
|
-
* unrecoverable failure rather than calling Logger.fatal so runAsCli's
|
|
27
|
-
* exit-code boundary stays robust under mocked process.exit.
|
|
2
|
+
* audit-to-stories.js — turn audit-* report findings into a dedup-checked
|
|
3
|
+
* plan, a `/mandrel-plan` seed, or standalone Story drafts. Throws rather than
|
|
4
|
+
* calling Logger.fatal so runAsCli owns the exit code.
|
|
28
5
|
*/
|
|
29
6
|
|
|
30
7
|
import fs from 'node:fs';
|
|
@@ -76,17 +53,8 @@ const DEFAULT_GLOB = 'temp/audits/audit-*-results.md';
|
|
|
76
53
|
const FAN_OUT_REPORT = 'audit-fan-out-results.md';
|
|
77
54
|
|
|
78
55
|
/**
|
|
79
|
-
* Does `finding` clear the `threshold` severity
|
|
80
|
-
*
|
|
81
|
-
* `SEVERITY_RANK` is imported from the canonical scale rather than declared
|
|
82
|
-
* here (Story #4877). The local copy this replaces ranked only four levels
|
|
83
|
-
* (`critical|high|medium|low`), so `info` — the canonical floor — ranked `0`,
|
|
84
|
-
* below even `--severity low`, and every informational finding was silently
|
|
85
|
-
* dropped from every filtered run. Sourcing the ranking from the SSOT means a
|
|
86
|
-
* level cannot exist in the vocabulary and be invisible to the filter.
|
|
87
|
-
*
|
|
88
|
-
* An unrecognised or absent severity still ranks below every real floor: it
|
|
89
|
-
* failed to parse, so it is not evidence that a threshold was met.
|
|
56
|
+
* Does `finding` clear the `threshold` floor? An unparsed severity ranks below
|
|
57
|
+
* every real floor.
|
|
90
58
|
*
|
|
91
59
|
* @param {{ severity?: string }} finding
|
|
92
60
|
* @param {string} [threshold] — a canonical level, `'all'`, or falsy for no floor.
|
|
@@ -116,11 +84,8 @@ function readReports(paths) {
|
|
|
116
84
|
}
|
|
117
85
|
|
|
118
86
|
/**
|
|
119
|
-
* Count findings per
|
|
120
|
-
*
|
|
121
|
-
* bucket so an unparseable severity is reported rather than absorbed into a
|
|
122
|
-
* real level. Derived from `SEVERITIES` so a new level appears in the tally
|
|
123
|
-
* automatically instead of falling into `unknown` (Story #4877).
|
|
87
|
+
* Count findings per canonical level, plus a visible `unknown` bucket for an
|
|
88
|
+
* unparsed severity.
|
|
124
89
|
*
|
|
125
90
|
* @param {Array<{ severity?: string }>} findings
|
|
126
91
|
* @returns {Record<string, number>}
|
|
@@ -137,18 +102,10 @@ function tallyBySeverity(findings) {
|
|
|
137
102
|
return t;
|
|
138
103
|
}
|
|
139
104
|
|
|
140
|
-
/**
|
|
141
|
-
* The four levels a report's `Severity tally:` line declares. `Info` is
|
|
142
|
-
* deliberately absent — the severity scale already excludes it from scheduled
|
|
143
|
-
* work — and `unknown` is not a level a lens can declare, so neither is
|
|
144
|
-
* comparable against the line.
|
|
145
|
-
*/
|
|
105
|
+
/** The levels a `Severity tally:` line declares; `info` and `unknown` are not comparable. */
|
|
146
106
|
const TALLY_LEVELS = Object.freeze(['critical', 'high', 'medium', 'low']);
|
|
147
107
|
|
|
148
108
|
/**
|
|
149
|
-
* Project a findings list onto the four comparable levels, so a report's
|
|
150
|
-
* declared tally and the parsed one are compared over the same axes.
|
|
151
|
-
*
|
|
152
109
|
* @param {Array<{ severity?: string }>} findings
|
|
153
110
|
* @returns {{ critical: number, high: number, medium: number, low: number }}
|
|
154
111
|
*/
|
|
@@ -167,14 +124,9 @@ function formatTally(tally) {
|
|
|
167
124
|
}
|
|
168
125
|
|
|
169
126
|
/**
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* `--auto` files unattended, so a report it cannot trust must stop the run
|
|
175
|
-
* BEFORE the ledger reconcile and before any Story payload is built: no GitHub
|
|
176
|
-
* write, no ledger write, non-zero exit. `--scan` reports and carries on — the
|
|
177
|
-
* failures ride the plan envelope for the operator to act on.
|
|
127
|
+
* Cross-check the reports, warn on stderr, and throw under
|
|
128
|
+
* `failOnReportFailures` (`--auto`) BEFORE any ledger or GitHub write; `--scan`
|
|
129
|
+
* carries the failures on the plan envelope instead.
|
|
178
130
|
*
|
|
179
131
|
* @param {object} params
|
|
180
132
|
* @param {Array<{ sourceReport: string, markdown: string }>} params.reports
|
|
@@ -209,28 +161,12 @@ function auditReportFailures({
|
|
|
209
161
|
}
|
|
210
162
|
|
|
211
163
|
/**
|
|
212
|
-
* Cross-check
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* this is where the two numbers meet. Three failure kinds are named:
|
|
219
|
-
*
|
|
220
|
-
* - `missing-tally` — the report declares no tally at all (an older or
|
|
221
|
-
* hand-written report). `allowMissingTally` downgrades ONLY this kind to a
|
|
222
|
-
* warning, for an interactive `--scan` over legacy reports.
|
|
223
|
-
* - `tally-mismatch` — the report says one thing and the parse says another.
|
|
224
|
-
* - `duplicate-tally` — the report declares the tally more than once, so there
|
|
225
|
-
* is no single number to check against. Adopting whichever line the scan
|
|
226
|
-
* reached first would compare the parse against an arbitrary one of two
|
|
227
|
-
* declarations, which is a cross-check in name only. `allowMissingTally`
|
|
228
|
-
* does NOT downgrade it: the report is contradictory, not merely old.
|
|
229
|
-
* - `unresolved-severity` — a finding parsed with no resolvable severity. It
|
|
230
|
-
* is a report defect, never an `unknown` group.
|
|
231
|
-
*
|
|
232
|
-
* Pure: returns the messages and lets the caller own the single `Logger.warn`
|
|
233
|
-
* (stderr) sink, so `--scan` JSON on stdout stays clean.
|
|
164
|
+
* Cross-check each report's declared `Severity tally:` line against what the
|
|
165
|
+
* parser extracted — a parser that silently drops findings otherwise looks
|
|
166
|
+
* like a clean report. Failure kinds: `missing-tally` (the only kind
|
|
167
|
+
* `allowMissingTally` downgrades to a warning), `tally-mismatch`,
|
|
168
|
+
* `duplicate-tally` (no single number to check; contradictory, never
|
|
169
|
+
* downgraded), and `unresolved-severity`. Pure; the caller owns stderr.
|
|
234
170
|
*
|
|
235
171
|
* @param {object} params
|
|
236
172
|
* @param {Array<{ sourceReport: string, markdown: string }>} params.reports
|
|
@@ -295,10 +231,6 @@ function crossCheckReports({ reports, findings, allowMissingTally }) {
|
|
|
295
231
|
}
|
|
296
232
|
|
|
297
233
|
/**
|
|
298
|
-
* The `--allow-missing-tally` downgrade message. It still names the report and
|
|
299
|
-
* says plainly that `--auto` ignores the flag, so an operator never reads the
|
|
300
|
-
* warning as "this report is fine".
|
|
301
|
-
*
|
|
302
234
|
* @param {{ sourceReport: string, parsed: object }} failure
|
|
303
235
|
* @returns {string}
|
|
304
236
|
*/
|
|
@@ -307,11 +239,8 @@ function missingTallyWarning(failure) {
|
|
|
307
239
|
}
|
|
308
240
|
|
|
309
241
|
/**
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* re-reading the report.
|
|
313
|
-
*
|
|
314
|
-
* Pure: returns the message string so the caller owns the single `Logger.warn`.
|
|
242
|
+
* One line per failure naming the report and BOTH tallies, so the operator
|
|
243
|
+
* sees which side is wrong.
|
|
315
244
|
*
|
|
316
245
|
* @param {Array<{ sourceReport: string, kind: string, reported: object|null, parsed: object, titles?: string[], tallyLines?: string[] }>} failures
|
|
317
246
|
* @returns {string}
|
|
@@ -321,9 +250,7 @@ function reportFailureWarning(failures) {
|
|
|
321
250
|
const titles = f.titles?.length
|
|
322
251
|
? ` findings=${f.titles.map((t) => `"${t}"`).join(', ')}`
|
|
323
252
|
: '';
|
|
324
|
-
// A duplicate
|
|
325
|
-
// single `reported` number to print, and "which two lines" is the whole
|
|
326
|
-
// remedy.
|
|
253
|
+
// A duplicate has no single `reported` number; name the competing lines.
|
|
327
254
|
const declared = f.tallyLines?.length
|
|
328
255
|
? ` declared=${f.tallyLines.map((t) => `"${t}"`).join(' | ')}`
|
|
329
256
|
: '';
|
|
@@ -337,11 +264,9 @@ function reportFailureWarning(failures) {
|
|
|
337
264
|
}
|
|
338
265
|
|
|
339
266
|
/**
|
|
340
|
-
* Test-only seam:
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* the real `--scan` CLI with a search port that fails for a subset of groups
|
|
344
|
-
* (Story #4678, AC-8), with no network. Returns null when the env var is unset.
|
|
267
|
+
* Test-only seam: `AUDIT_TO_STORIES_PROVIDER_FIXTURE` names a module whose
|
|
268
|
+
* default export replaces the whole provider adapter, so the real CLI runs
|
|
269
|
+
* with no network.
|
|
345
270
|
*
|
|
346
271
|
* @returns {Promise<object|null>}
|
|
347
272
|
*/
|
|
@@ -353,14 +278,8 @@ async function loadFixtureProvider() {
|
|
|
353
278
|
}
|
|
354
279
|
|
|
355
280
|
/**
|
|
356
|
-
* Why the live provider could not be adapted
|
|
357
|
-
*
|
|
358
|
-
* `loadProvider` used to collapse every one of these onto a bare `null`, which
|
|
359
|
-
* was survivable for the dedup path (it degrades to a create-only plan and
|
|
360
|
-
* warns) but not for `--wire-edges`, which cannot degrade and could therefore
|
|
361
|
-
* only blame "configuration" for what was just as likely an auth failure.
|
|
362
|
-
* Throwing a reason keeps the soft-fail (`loadProviderOrNull`) and lets the
|
|
363
|
-
* write path name the missing precondition (Story #5143).
|
|
281
|
+
* Why the live provider could not be adapted. A typed reason lets
|
|
282
|
+
* `--wire-edges`, which cannot degrade, name the missing precondition.
|
|
364
283
|
*/
|
|
365
284
|
class ProviderUnavailableError extends Error {
|
|
366
285
|
/**
|
|
@@ -375,13 +294,9 @@ class ProviderUnavailableError extends Error {
|
|
|
375
294
|
}
|
|
376
295
|
|
|
377
296
|
/**
|
|
378
|
-
*
|
|
379
|
-
* deduplicated
|
|
380
|
-
*
|
|
381
|
-
* `labels` is an OR across the run's lenses, which the REST list endpoint
|
|
382
|
-
* cannot express in one query (its `labels` parameter is an AND), so one call
|
|
383
|
-
* per label is the narrowest honest read. Each is a paginated **list**, not a
|
|
384
|
-
* search — a different, far larger rate-limit budget.
|
|
297
|
+
* List issues once per label (the REST `labels` filter is an AND, we need an
|
|
298
|
+
* OR) and merge them deduplicated. The list endpoint has a far larger
|
|
299
|
+
* rate-limit budget than search.
|
|
385
300
|
*
|
|
386
301
|
* @param {object} provider
|
|
387
302
|
* @param {string[]} labels
|
|
@@ -403,11 +318,8 @@ async function listIssuesForLabels(provider, labels) {
|
|
|
403
318
|
}
|
|
404
319
|
|
|
405
320
|
/**
|
|
406
|
-
* The
|
|
407
|
-
*
|
|
408
|
-
* exact-fingerprint pass and — since Story #4626 — `searchCandidates(finding)`
|
|
409
|
-
* for the meaning-first Stage-1 pass. Adapted here so no provider-shape
|
|
410
|
-
* knowledge is baked into the dedupe module.
|
|
321
|
+
* The dedupe module's read ports, adapted here so it holds no provider-shape
|
|
322
|
+
* knowledge.
|
|
411
323
|
*
|
|
412
324
|
* @param {object} provider
|
|
413
325
|
* @param {{ owner: string, repo: string }} coords
|
|
@@ -421,12 +333,8 @@ function buildDedupPorts(provider, { owner, repo }) {
|
|
|
421
333
|
return (hits ?? []).map(normaliseIssueHit);
|
|
422
334
|
},
|
|
423
335
|
/**
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
* every exact-fingerprint lookup from it, so the rate-limited search API is
|
|
427
|
-
* spent only on findings it has never seen. A provider without the list
|
|
428
|
-
* port yields `null`, which returns dedup to the per-finding search path
|
|
429
|
-
* rather than silently skipping it.
|
|
336
|
+
* Every Issue carrying one of the run's `audit::*` labels, for the
|
|
337
|
+
* fingerprint index. `null` (no list port) falls back to per-finding search.
|
|
430
338
|
*
|
|
431
339
|
* @param {string[]} labels
|
|
432
340
|
* @returns {Promise<Array<object>|null>}
|
|
@@ -436,8 +344,6 @@ function buildDedupPorts(provider, { owner, repo }) {
|
|
|
436
344
|
return listIssuesForLabels(provider, labels);
|
|
437
345
|
},
|
|
438
346
|
async searchCandidates(finding) {
|
|
439
|
-
// Wire the shared semantic search onto the provider's full-text
|
|
440
|
-
// issue search (open + closed) so route-finding's Stage-1 pass runs.
|
|
441
347
|
const search = async (query) => {
|
|
442
348
|
if (!query || query.trim().length === 0) return [];
|
|
443
349
|
const hits = await provider.searchIssues({ query, owner, repo });
|
|
@@ -449,15 +355,9 @@ function buildDedupPorts(provider, { owner, repo }) {
|
|
|
449
355
|
}
|
|
450
356
|
|
|
451
357
|
/**
|
|
452
|
-
* The provider's write ports,
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
* first call. Narrowing the adapter to the dedup read ports is what made
|
|
456
|
-
* `--wire-edges` fail closed against a correctly configured repo (Story #5143).
|
|
457
|
-
*
|
|
458
|
-
* A port the provider does not implement is omitted rather than stubbed: the
|
|
459
|
-
* wire step already degrades per port (footer-only when the native dependency
|
|
460
|
-
* ports are absent), and a stub would defeat that check.
|
|
358
|
+
* The provider's write ports, **bound** — `GitHubProvider` delegates off
|
|
359
|
+
* `this`, so an unbound reference throws. A missing port is omitted, not
|
|
360
|
+
* stubbed, so the wire step's per-port degradation still sees it.
|
|
461
361
|
*
|
|
462
362
|
* @param {object} provider
|
|
463
363
|
* @returns {Record<string, Function>}
|
|
@@ -480,9 +380,6 @@ const PROVIDER_WRITE_PORTS = [
|
|
|
480
380
|
];
|
|
481
381
|
|
|
482
382
|
/**
|
|
483
|
-
* Resolve the config and construct the live provider, converting each way that
|
|
484
|
-
* can fail into a typed refusal.
|
|
485
|
-
*
|
|
486
383
|
* @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} seams
|
|
487
384
|
* @returns {Promise<{ config: object, provider: object }>}
|
|
488
385
|
* @throws {ProviderUnavailableError}
|
|
@@ -520,14 +417,7 @@ async function constructProvider({ createProviderImpl, resolveConfigImpl }) {
|
|
|
520
417
|
}
|
|
521
418
|
|
|
522
419
|
/**
|
|
523
|
-
* Adapt the configured provider
|
|
524
|
-
* provider's own write ports, bound.
|
|
525
|
-
*
|
|
526
|
-
* The `createProviderImpl` / `resolveConfigImpl` seams let a contract test
|
|
527
|
-
* drive this exact adapter with an in-memory issue store instead of the live
|
|
528
|
-
* GitHub provider. The `AUDIT_TO_STORIES_PROVIDER_FIXTURE` fixture is returned
|
|
529
|
-
* verbatim — it stands in for the whole adapter, not for the provider behind
|
|
530
|
-
* it.
|
|
420
|
+
* Adapt the configured provider: dedup read ports plus bound write ports.
|
|
531
421
|
*
|
|
532
422
|
* @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} [seams]
|
|
533
423
|
* @returns {Promise<object>} the adapter (never null).
|
|
@@ -556,9 +446,7 @@ async function loadProvider({ createProviderImpl, resolveConfigImpl } = {}) {
|
|
|
556
446
|
}
|
|
557
447
|
|
|
558
448
|
/**
|
|
559
|
-
*
|
|
560
|
-
* there — when it cannot be adapted the dedupe step emits a create-only
|
|
561
|
-
* classification and warns the operator loudly rather than aborting the scan.
|
|
449
|
+
* Soft-fail `loadProvider` for dedup, which degrades to create-only and warns.
|
|
562
450
|
*
|
|
563
451
|
* @param {{ createProviderImpl?: Function, resolveConfigImpl?: Function }} [seams]
|
|
564
452
|
* @returns {Promise<object|null>}
|
|
@@ -572,21 +460,8 @@ async function loadProviderOrNull(seams = {}) {
|
|
|
572
460
|
}
|
|
573
461
|
|
|
574
462
|
/**
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
* - `'no-provider-port'` — the configured provider resolved but exposes no
|
|
579
|
-
* `searchIssues` port (or `loadProviderOrNull()` swallowed a typed
|
|
580
|
-
* refusal — bad config, failed construction). This is the
|
|
581
|
-
* silent-no-op the workflow's "Never open a duplicate Issue" contract
|
|
582
|
-
* was failing on: every group classifies `create` and the operator gets
|
|
583
|
-
* zero automated dedup signal. Surfacing it loudly is the whole point.
|
|
584
|
-
* - `'disabled'` — the operator passed `--no-provider`, intentionally
|
|
585
|
-
* skipping dedup. Still warned (so a re-run that opens duplicates is
|
|
586
|
-
* never a surprise), but framed as a deliberate choice.
|
|
587
|
-
*
|
|
588
|
-
* Pure: returns the message string so `buildPlan` owns the single
|
|
589
|
-
* `Logger.warn` write site and the text stays unit-testable.
|
|
463
|
+
* Warning for a dedup that did not run: `no-provider-port` (no usable provider
|
|
464
|
+
* — otherwise a silent all-`create` plan) or `disabled` (`--no-provider`).
|
|
590
465
|
*
|
|
591
466
|
* @param {'no-provider-port'|'disabled'} reason
|
|
592
467
|
* @returns {string}
|
|
@@ -611,16 +486,8 @@ function dedupSkippedWarning(reason) {
|
|
|
611
486
|
}
|
|
612
487
|
|
|
613
488
|
/**
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
* still exhausted after the endpoint budget's cooldown). Those groups degrade
|
|
617
|
-
* to `create` rather than aborting the whole scan (Story #4678); this warning
|
|
618
|
-
* names each affected group so the operator knows exactly which to check by
|
|
619
|
-
* hand. Mirrors the `dedupSkippedWarning` shape so a partially-checked plan
|
|
620
|
-
* reads as clearly as a wholly-unchecked one.
|
|
621
|
-
*
|
|
622
|
-
* Pure: returns the message string so `buildPlan` owns the single `Logger.warn`
|
|
623
|
-
* write site (stderr) and the text stays unit-testable.
|
|
489
|
+
* Warning naming each group whose lookup could not complete (422, exhausted
|
|
490
|
+
* rate limit) and so degraded to `create` unchecked.
|
|
624
491
|
*
|
|
625
492
|
* @param {Array<{ group: string, reason: string }>} entries
|
|
626
493
|
* @returns {string}
|
|
@@ -636,15 +503,9 @@ function dedupDegradedWarning(entries) {
|
|
|
636
503
|
}
|
|
637
504
|
|
|
638
505
|
/**
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
* actually check against" is the one number that separates a real dedup from a
|
|
643
|
-
* plan that merely looks checked. At zero it is the load-bearing case: an empty
|
|
644
|
-
* corpus is a legitimate first sweep AND exactly what a broken fetch writes, so
|
|
645
|
-
* the operator — not the run — decides which this was. Deliberately distinct in
|
|
646
|
-
* wording from both `dedupSkippedWarning` and `dedupDegradedWarning` so the
|
|
647
|
-
* three are never confused in a scrollback.
|
|
506
|
+
* Always emitted for `--issues-file`: the corpus size separates a real dedup
|
|
507
|
+
* from one that merely looks checked. Zero is ambiguous (first sweep or broken
|
|
508
|
+
* fetch), so the operator decides.
|
|
648
509
|
*
|
|
649
510
|
* @param {{ source?: string, size?: number }} dedupIndex
|
|
650
511
|
* @returns {string}
|
|
@@ -662,11 +523,7 @@ function dedupIndexWarning({ size = 0 } = {}) {
|
|
|
662
523
|
}
|
|
663
524
|
|
|
664
525
|
/**
|
|
665
|
-
*
|
|
666
|
-
* complete. The run still dedups — it falls back to a per-finding search — but
|
|
667
|
-
* it loses the one-list saving, and until Story #5301 this failure was
|
|
668
|
-
* swallowed whole: the operator saw only the downstream per-group degradation
|
|
669
|
-
* and could not tell that the pre-fetch itself was the cause.
|
|
526
|
+
* Warning for a failed index pre-fetch; dedup falls back to per-finding search.
|
|
670
527
|
*
|
|
671
528
|
* @param {string} reason
|
|
672
529
|
* @returns {string}
|
|
@@ -680,23 +537,10 @@ function dedupIndexDegradedWarning(reason) {
|
|
|
680
537
|
}
|
|
681
538
|
|
|
682
539
|
/**
|
|
683
|
-
*
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
* inlining them pushed the caller past its complexity ceiling. The three:
|
|
688
|
-
*
|
|
689
|
-
* - **deduped** — a provider resolved, or the host supplied a corpus, or
|
|
690
|
-
* both. A host-supplied corpus is a dedup source in its own right, which is
|
|
691
|
-
* the whole point: the gate asks "can we dedup at all", not "did a provider
|
|
692
|
-
* resolve". While it asked the latter, `--no-provider --issues-file` — the
|
|
693
|
-
* one invocation a `gh`-less host can run — short-circuited to the seeded
|
|
694
|
-
* all-`create` classifications however well the dedupe module worked.
|
|
695
|
-
* - **skipped, no port** — a provider was wanted but could not be adapted.
|
|
696
|
-
* - **skipped, disabled** — `--no-provider` with no corpus to fall back on.
|
|
697
|
-
*
|
|
698
|
-
* Every outcome warns on stderr, so the `--scan` JSON on stdout stays clean and
|
|
699
|
-
* a create-only plan is never read as "checked, found nothing".
|
|
540
|
+
* Classify every group against GitHub and warn on stderr whichever way it
|
|
541
|
+
* went. A host-supplied corpus is a dedup source on its own, so
|
|
542
|
+
* `--no-provider --issues-file` (the `gh`-less host) still dedups; only with
|
|
543
|
+
* neither a provider nor a corpus is every group `create`.
|
|
700
544
|
*
|
|
701
545
|
* @param {{ groups: Array<object>, useProvider?: boolean,
|
|
702
546
|
* issues?: Array<object>|null }} params
|
|
@@ -740,25 +584,17 @@ async function runDedupPhase(
|
|
|
740
584
|
}
|
|
741
585
|
|
|
742
586
|
/**
|
|
743
|
-
* Every warning a completed dedup pass owes the operator, in order. Pure, so
|
|
744
|
-
* the wording stays unit-testable and `runDedupPhase` keeps one write site.
|
|
745
|
-
*
|
|
746
587
|
* @param {{ issues?: Array<object>|null, summary: object }} params
|
|
747
588
|
* @returns {string[]}
|
|
748
589
|
*/
|
|
749
590
|
function dedupPhaseWarnings({ issues, summary }) {
|
|
750
591
|
const warnings = [];
|
|
751
592
|
if (issues) warnings.push(dedupIndexWarning(summary.dedupIndex));
|
|
752
|
-
// The pre-fetch failing is a distinct fact from any group's lookup failing,
|
|
753
|
-
// and used to be invisible: the operator saw only the downstream per-group
|
|
754
|
-
// degradation and could not tell what had caused it.
|
|
755
593
|
if (summary.dedupDegraded?.indexPrefetch) {
|
|
756
594
|
warnings.push(
|
|
757
595
|
dedupIndexDegradedWarning(summary.dedupDegraded.indexPrefetch),
|
|
758
596
|
);
|
|
759
597
|
}
|
|
760
|
-
// A partially-checked plan is a useful result — name the groups that degraded
|
|
761
|
-
// to create because their lookup could not complete (Story #4678).
|
|
762
598
|
if (summary.dedupDegraded?.count > 0) {
|
|
763
599
|
warnings.push(dedupDegradedWarning(summary.dedupDegraded.groups));
|
|
764
600
|
}
|
|
@@ -766,12 +602,7 @@ function dedupPhaseWarnings({ issues, summary }) {
|
|
|
766
602
|
}
|
|
767
603
|
|
|
768
604
|
/**
|
|
769
|
-
* Scan → group → dedup → (optionally) reconcile the cross-run ledger
|
|
770
|
-
* return the plan envelope.
|
|
771
|
-
*
|
|
772
|
-
* Every seam on the optional final `deps` parameter defaults to the real
|
|
773
|
-
* implementation (`.agents/rules/test-seams.md` rules 1-2, 4), so `main`,
|
|
774
|
-
* `runAuto`, and every production caller are unchanged.
|
|
605
|
+
* Scan → group → dedup → (optionally) reconcile the cross-run ledger.
|
|
775
606
|
*
|
|
776
607
|
* @param {{ glob?: string, severity?: string, useProvider?: boolean,
|
|
777
608
|
* issuesFile?: string, ledger?: object }} params
|
|
@@ -807,9 +638,7 @@ async function buildPlan(
|
|
|
807
638
|
reconcileScanLedgerImpl = reconcileScanLedger,
|
|
808
639
|
logger = Logger,
|
|
809
640
|
} = deps;
|
|
810
|
-
//
|
|
811
|
-
// error, and failing fast costs the operator nothing, where failing late
|
|
812
|
-
// would tempt a fallback that silently dedups nothing.
|
|
641
|
+
// Before reading reports: an unusable corpus is a usage error, not a fallback.
|
|
813
642
|
const issues = issuesFile ? loadIssuesFileImpl(issuesFile) : null;
|
|
814
643
|
const reportPaths = await collectReportPathsImpl(pattern ?? DEFAULT_GLOB);
|
|
815
644
|
if (reportPaths.length === 0) {
|
|
@@ -842,9 +671,7 @@ async function buildPlan(
|
|
|
842
671
|
logger,
|
|
843
672
|
});
|
|
844
673
|
const filtered = allFindings.filter((f) => meetsSeverity(f, severity));
|
|
845
|
-
//
|
|
846
|
-
// It stays visible in `summary.tally.unknown` and in `reportFailures`, but
|
|
847
|
-
// it never reaches grouping — an `unknown` group is not a thing to file.
|
|
674
|
+
// An unresolved severity is a report defect (tallied, never grouped).
|
|
848
675
|
const stamped = withFingerprints(filtered.filter((f) => Boolean(f.severity)));
|
|
849
676
|
const { groups, edges } = groupFindings(stamped);
|
|
850
677
|
|
|
@@ -853,10 +680,7 @@ async function buildPlan(
|
|
|
853
680
|
{ loadProviderImpl, classifyGroupsImpl, logger },
|
|
854
681
|
);
|
|
855
682
|
|
|
856
|
-
//
|
|
857
|
-
// suppress findings a prior run recorded as accepted-risk, and (unless the
|
|
858
|
-
// caller asked not to write) persist the updated ledger. Opt-in — the plain
|
|
859
|
-
// --scan path leaves it untouched so it never mutates a committed file.
|
|
683
|
+
// Opt-in: plain --scan never mutates the committed ledger.
|
|
860
684
|
let ledgerSummary;
|
|
861
685
|
if (ledger) {
|
|
862
686
|
const suppressed = reconcileScanLedgerImpl({
|
|
@@ -903,9 +727,8 @@ async function buildPlan(
|
|
|
903
727
|
}
|
|
904
728
|
|
|
905
729
|
/**
|
|
906
|
-
* Fold the
|
|
907
|
-
*
|
|
908
|
-
* (deliberately rejected) so the caller can suppress them.
|
|
730
|
+
* Fold the scan onto the ledger, persist it, and return the accepted-risk
|
|
731
|
+
* fingerprints to suppress.
|
|
909
732
|
*
|
|
910
733
|
* @param {object} params
|
|
911
734
|
* @param {string} params.ledgerPath
|
|
@@ -921,8 +744,7 @@ function reconcileScanLedger({ ledgerPath, findings, classifications, write }) {
|
|
|
921
744
|
ledger: prior,
|
|
922
745
|
findings,
|
|
923
746
|
issueStates,
|
|
924
|
-
//
|
|
925
|
-
// audit adapter without closing a cycle, so the projection is ours to pass.
|
|
747
|
+
// Passed in: the ledger importing the audit adapter would close a cycle.
|
|
926
748
|
toCanonical: toCanonicalFinding,
|
|
927
749
|
});
|
|
928
750
|
if (write !== false) writeLedger(ledgerPath, next);
|
|
@@ -934,8 +756,6 @@ function reconcileScanLedger({ ledgerPath, findings, classifications, write }) {
|
|
|
934
756
|
}
|
|
935
757
|
|
|
936
758
|
/**
|
|
937
|
-
* Derive a `{ fingerprint → issueState }` map from dedupe classifications so
|
|
938
|
-
* the ledger reconcile sees the live open/closed state of matched Issues.
|
|
939
759
|
* @param {Array<object>} classifications
|
|
940
760
|
* @returns {Record<string, { state: string, number: number|null }>}
|
|
941
761
|
*/
|
|
@@ -961,36 +781,21 @@ function loadPlan(planPath) {
|
|
|
961
781
|
return JSON.parse(fs.readFileSync(planPath, 'utf8'));
|
|
962
782
|
}
|
|
963
783
|
|
|
784
|
+
/** The `--auto` severity floor when `--severity` names none. */
|
|
964
785
|
const DEFAULT_SEVERITY_FLOOR = 'high';
|
|
965
786
|
|
|
966
787
|
/**
|
|
967
|
-
* Resolve the unattended-sweep severity floor: an explicit `--severity` wins,
|
|
968
|
-
* else `delivery.auditToStories.severityFloor` from config, else the built-in
|
|
969
|
-
* default (`high`). Reads config defensively so a missing/failed resolve never
|
|
970
|
-
* breaks the run.
|
|
971
|
-
*
|
|
972
788
|
* @param {string|undefined} explicit
|
|
973
|
-
* @returns {
|
|
789
|
+
* @returns {string}
|
|
974
790
|
*/
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
try {
|
|
978
|
-
const { resolveConfig } = await import('./lib/config-resolver.js');
|
|
979
|
-
const config = resolveConfig();
|
|
980
|
-
const floor = config?.delivery?.auditToStories?.severityFloor;
|
|
981
|
-
if (typeof floor === 'string' && floor.length > 0) return floor;
|
|
982
|
-
} catch (_) {
|
|
983
|
-
// fall through to default
|
|
984
|
-
}
|
|
985
|
-
return DEFAULT_SEVERITY_FLOOR;
|
|
791
|
+
function severityFloorOf(explicit) {
|
|
792
|
+
return explicit || DEFAULT_SEVERITY_FLOOR;
|
|
986
793
|
}
|
|
987
794
|
|
|
988
795
|
/**
|
|
989
|
-
* Unattended `--auto` sweep
|
|
990
|
-
*
|
|
991
|
-
*
|
|
992
|
-
* and emits the summary only; otherwise it returns the create-eligible Story
|
|
993
|
-
* payloads for the caller to open. Always resolves — never prompts.
|
|
796
|
+
* Unattended `--auto` sweep: build the plan with ledger reconciliation and
|
|
797
|
+
* return a summary plus the create-eligible Story payloads (none under
|
|
798
|
+
* `--dry-run`, which writes nothing). Never prompts.
|
|
994
799
|
*
|
|
995
800
|
* @param {object} params
|
|
996
801
|
* @param {string} [params.glob]
|
|
@@ -1017,7 +822,7 @@ async function runAuto({
|
|
|
1017
822
|
cwd,
|
|
1018
823
|
logger = Logger,
|
|
1019
824
|
}) {
|
|
1020
|
-
const floor =
|
|
825
|
+
const floor = severityFloorOf(severity);
|
|
1021
826
|
const resolvedLedgerPath = ledgerPath ?? DEFAULT_LEDGER_PATH;
|
|
1022
827
|
const plan = await buildPlan({
|
|
1023
828
|
glob,
|
|
@@ -1025,8 +830,7 @@ async function runAuto({
|
|
|
1025
830
|
useProvider,
|
|
1026
831
|
issuesFile,
|
|
1027
832
|
ledger: { path: resolvedLedgerPath, write: !dryRun },
|
|
1028
|
-
//
|
|
1029
|
-
// no operator to read a warning, so every report failure is fatal here.
|
|
833
|
+
// No operator reads warnings unattended, so every report failure is fatal.
|
|
1030
834
|
allowMissingTally: false,
|
|
1031
835
|
failOnReportFailures: true,
|
|
1032
836
|
});
|
|
@@ -1061,20 +865,14 @@ async function runAuto({
|
|
|
1061
865
|
skipReoccurring: byAction.skipReoccurring.length,
|
|
1062
866
|
suppressedByLedger: byAction.suppressed.length,
|
|
1063
867
|
},
|
|
1064
|
-
//
|
|
1065
|
-
//
|
|
1066
|
-
// the `--wire-edges --ids` map. Without them an unattended sweep cannot
|
|
1067
|
-
// record what it filed, and the ledger stays empty however well it works.
|
|
868
|
+
// The caller opens the Issues; these keys feed its `--wire-edges --ids`
|
|
869
|
+
// map, without which the ledger never records what was filed.
|
|
1068
870
|
createGroupKeys: eligible.map((g) => g?.groupKey).filter(Boolean),
|
|
1069
|
-
// Re-detected open Issues the operator may want a "re-detected" comment on.
|
|
1070
871
|
reDetected: byAction.skipOpen
|
|
1071
872
|
.flatMap((c) => c.matchedIssues ?? [])
|
|
1072
873
|
.map((i) => i.number)
|
|
1073
874
|
.filter((n) => typeof n === 'number'),
|
|
1074
|
-
//
|
|
1075
|
-
// ephemeral scheduled clone is exactly where that bites (Story #5145).
|
|
1076
|
-
// The whole decision lives in `resolveLedgerSummary` so this assembly
|
|
1077
|
-
// stays branch-free.
|
|
875
|
+
// An ephemeral clone may not be able to keep the ledger it just wrote.
|
|
1078
876
|
ledger: await resolveLedgerSummary({
|
|
1079
877
|
ledger: plan.summary?.ledger ?? null,
|
|
1080
878
|
ledgerPath: resolvedLedgerPath,
|
|
@@ -1090,16 +888,9 @@ async function runAuto({
|
|
|
1090
888
|
}
|
|
1091
889
|
|
|
1092
890
|
/**
|
|
1093
|
-
* Build
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1096
|
-
* The `--emit-stories` path opens GitHub issues directly (no decomposer
|
|
1097
|
-
* round-trip), so `assertEveryStoryHasInlineContract` never runs against these
|
|
1098
|
-
* bodies. This gate restores that guarantee at the standalone seam: each
|
|
1099
|
-
* emitted body is re-parsed through the canonical `story-body` parser and must
|
|
1100
|
-
* carry a non-empty `acceptance[]` AND a non-empty `verify[]`. A body that
|
|
1101
|
-
* fails throws, surfacing the gap instead of opening an ungated Story
|
|
1102
|
-
* (Story #4270).
|
|
891
|
+
* Build each eligible group into a Story and throw BEFORE any issue is opened
|
|
892
|
+
* unless every body re-parses with non-empty `acceptance[]` and `verify[]` —
|
|
893
|
+
* this path skips the decomposer's inline-contract assertion.
|
|
1103
894
|
*
|
|
1104
895
|
* @param {Array<{ group: object }>} eligible — classifications eligible to create.
|
|
1105
896
|
* @param {Array<{ fromGroupKey: string, toGroupKey: string }>} edges — sequencing edges.
|
|
@@ -1130,14 +921,8 @@ function buildAndGateStories(eligible, edges) {
|
|
|
1130
921
|
}
|
|
1131
922
|
|
|
1132
923
|
/**
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1135
|
-
* `--wire-edges` cannot degrade — the `blocked by #N` footers are the only
|
|
1136
|
-
* thing `/mandrel-deliver`'s resolver reads — so the one thing its failure owes the
|
|
1137
|
-
* operator is which of the preconditions is actually unmet. The message it
|
|
1138
|
-
* replaced ("Configure github.owner/repo (and auth), or wire the edges by
|
|
1139
|
-
* hand") blamed configuration for an auth failure and pointed at a manual
|
|
1140
|
-
* fallback for what is a wiring bug (Story #5143).
|
|
924
|
+
* The unmet precondition, keyed by `loadProvider`'s refusal reason.
|
|
925
|
+
* `--wire-edges` cannot degrade, so its error must name which one.
|
|
1141
926
|
*/
|
|
1142
927
|
const WIRE_EDGES_PRECONDITIONS = {
|
|
1143
928
|
'no-config': 'github.owner and github.repo are not both set in .agentrc.json',
|
|
@@ -1166,18 +951,9 @@ function wireEdgesPreconditionError(reason, detail) {
|
|
|
1166
951
|
}
|
|
1167
952
|
|
|
1168
953
|
/**
|
|
1169
|
-
*
|
|
1170
|
-
*
|
|
1171
|
-
*
|
|
1172
|
-
* This is the second half of the two-pass crossing `--emit-stories` starts. The
|
|
1173
|
-
* host opens one Issue per group from the emitted drafts, then replays the
|
|
1174
|
-
* `groupKey → issueNumber` map here; each Story whose blockers now exist is
|
|
1175
|
-
* re-rendered with a canonical `blocked by #N` footer and the same edges are
|
|
1176
|
-
* mirrored as native `blocked_by` relations.
|
|
1177
|
-
*
|
|
1178
|
-
* The same map is what the cross-run ledger needs to record what this run
|
|
1179
|
-
* filed, so the record rides along here rather than arriving as a second
|
|
1180
|
-
* command an operator must remember (Story #5305).
|
|
954
|
+
* Second pass after `--emit-stories`: given the opened `groupKey →
|
|
955
|
+
* issueNumber` map, re-render each Story with `blocked by #N` footers, mirror
|
|
956
|
+
* them as native `blocked_by`, and record the filed issues in the ledger.
|
|
1181
957
|
*
|
|
1182
958
|
* @param {object} params
|
|
1183
959
|
* @param {object} params.plan A `--scan` plan envelope.
|
|
@@ -1206,12 +982,8 @@ async function wireEdges(
|
|
|
1206
982
|
.filter((c) => c.action === 'create')
|
|
1207
983
|
.map((c) => c.group);
|
|
1208
984
|
|
|
1209
|
-
// Record
|
|
1210
|
-
//
|
|
1211
|
-
// the host most likely to lack one is the `gh`-less host where the ledger is
|
|
1212
|
-
// the only duplicate protection there is. Recording first means such a run
|
|
1213
|
-
// still remembers what it filed, and the precondition error below still
|
|
1214
|
-
// surfaces unchanged afterwards.
|
|
985
|
+
// Record before loading the provider: a `gh`-less host, whose only duplicate
|
|
986
|
+
// protection is the ledger, must still remember what it filed.
|
|
1215
987
|
const ledger = recordFiledIssuesImpl({
|
|
1216
988
|
ledgerPath,
|
|
1217
989
|
groups,
|
|
@@ -1240,8 +1012,7 @@ async function wireEdges(
|
|
|
1240
1012
|
}
|
|
1241
1013
|
|
|
1242
1014
|
/**
|
|
1243
|
-
*
|
|
1244
|
-
* or a path to a file containing one.
|
|
1015
|
+
* `--ids`: inline JSON `{ groupKey: issueNumber }` or a path to one.
|
|
1245
1016
|
*
|
|
1246
1017
|
* @param {string|undefined} raw
|
|
1247
1018
|
* @returns {Record<string, number>}
|
|
@@ -1295,7 +1066,6 @@ export const __testing = {
|
|
|
1295
1066
|
dedupIndexDegradedWarning,
|
|
1296
1067
|
buildAndGateStories,
|
|
1297
1068
|
runAuto,
|
|
1298
|
-
resolveSeverityFloor,
|
|
1299
1069
|
reconcileScanLedger,
|
|
1300
1070
|
issueStatesFromClassifications,
|
|
1301
1071
|
wireEdges,
|
|
@@ -1303,13 +1073,7 @@ export const __testing = {
|
|
|
1303
1073
|
};
|
|
1304
1074
|
|
|
1305
1075
|
/**
|
|
1306
|
-
* The CLI core: dispatch one
|
|
1307
|
-
* Extracted from the `main` shell so the whole sub-command table (including
|
|
1308
|
-
* the no-sub-command usage throw) is reachable without spawning the CLI.
|
|
1309
|
-
*
|
|
1310
|
-
* Every seam on the optional final `deps` parameter defaults to the real
|
|
1311
|
-
* implementation (`.agents/rules/test-seams.md` rules 1-2, 4), so `main` and
|
|
1312
|
-
* every production invocation are unchanged.
|
|
1076
|
+
* The CLI core: dispatch one sub-command and persist its output.
|
|
1313
1077
|
*
|
|
1314
1078
|
* @param {string[]} [argv]
|
|
1315
1079
|
* @param {{
|
|
@@ -1324,12 +1088,7 @@ export const __testing = {
|
|
|
1324
1088
|
* @returns {Promise<void>}
|
|
1325
1089
|
*/
|
|
1326
1090
|
/**
|
|
1327
|
-
* The one-line `--ledger-commit` outcome,
|
|
1328
|
-
*
|
|
1329
|
-
* Names the branch and the PR on success — the two things an operator needs to
|
|
1330
|
-
* go look at it — and the skip reason otherwise, because "nothing happened" and
|
|
1331
|
-
* "the ledger was already clean" are different facts and only one of them is
|
|
1332
|
-
* fine.
|
|
1091
|
+
* The one-line `--ledger-commit` outcome: branch and PR, or the skip reason.
|
|
1333
1092
|
*
|
|
1334
1093
|
* @param {{ committed?: boolean, reason?: string, branch?: string,
|
|
1335
1094
|
* prUrl?: string|null, resumed?: boolean, ledgerPath?: string }} [result]
|
|
@@ -1342,8 +1101,6 @@ function describeLedgerCommit(result) {
|
|
|
1342
1101
|
}
|
|
1343
1102
|
|
|
1344
1103
|
/**
|
|
1345
|
-
* The success half: the branch, whether it resumed a half-finished one, and
|
|
1346
|
-
* the PR to go look at.
|
|
1347
1104
|
* @param {object} result
|
|
1348
1105
|
* @returns {string}
|
|
1349
1106
|
*/
|
|
@@ -1354,8 +1111,7 @@ function ledgerCommittedLine(result) {
|
|
|
1354
1111
|
}
|
|
1355
1112
|
|
|
1356
1113
|
/**
|
|
1357
|
-
*
|
|
1358
|
-
* which state is still only in the working tree.
|
|
1114
|
+
* Names the ledger file: its state is still only in the working tree.
|
|
1359
1115
|
* @param {object} [result]
|
|
1360
1116
|
* @returns {string}
|
|
1361
1117
|
*/
|
|
@@ -1366,14 +1122,8 @@ function ledgerSkippedLine(result) {
|
|
|
1366
1122
|
}
|
|
1367
1123
|
|
|
1368
1124
|
/**
|
|
1369
|
-
*
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
1372
|
-
* `meetsSeverity` reads an unknown threshold as rank `0`, so a typo — the
|
|
1373
|
-
* classic being `--severity Hgh` — quietly widened the run to every finding
|
|
1374
|
-
* instead of narrowing it. On an unattended sweep that is the difference
|
|
1375
|
-
* between filing a batch and filing the backlog, with nothing on stderr to say
|
|
1376
|
-
* so. An absent flag stays absent: the floor then resolves from config.
|
|
1125
|
+
* Reject an unknown `--severity`: `meetsSeverity` would read a typo as rank 0
|
|
1126
|
+
* and silently widen the run to every finding. Absent stays absent.
|
|
1377
1127
|
*
|
|
1378
1128
|
* @param {string|undefined} raw
|
|
1379
1129
|
* @returns {string|undefined} the canonical level.
|
|
@@ -1447,15 +1197,10 @@ export async function runAuditToStories(
|
|
|
1447
1197
|
})
|
|
1448
1198
|
).summary;
|
|
1449
1199
|
|
|
1450
|
-
//
|
|
1451
|
-
//
|
|
1452
|
-
// findings, so the PR attempt is the last thing the run does (Story #5145).
|
|
1200
|
+
// Runs after the summary is persisted: a broken remote must not cost the
|
|
1201
|
+
// sweep's findings.
|
|
1453
1202
|
const commitLedger = async () => {
|
|
1454
1203
|
if (!values['ledger-commit'] || values['dry-run']) return;
|
|
1455
|
-
// Say what happened. The tail used to run silently, so an operator could
|
|
1456
|
-
// not tell a ledger PR from a skip without going to look for the branch —
|
|
1457
|
-
// and a skip is the outcome that matters, because it means the sweep's
|
|
1458
|
-
// memory is still only in the working tree.
|
|
1459
1204
|
Logger.warn(
|
|
1460
1205
|
describeLedgerCommit(
|
|
1461
1206
|
await runLedgerCommitImpl({ ledgerPath: values.ledger }),
|
|
@@ -1495,18 +1240,11 @@ export async function runAuditToStories(
|
|
|
1495
1240
|
plan: loadPlanImpl(values.plan),
|
|
1496
1241
|
issueByGroupKey: parseIssueMapImpl(values.ids),
|
|
1497
1242
|
ledgerPath: values.ledger,
|
|
1498
|
-
//
|
|
1499
|
-
// the Issues were really opened, where recording is never wrong — so the
|
|
1500
|
-
// record is on by default here and `--dry-run` is what suppresses it.
|
|
1243
|
+
// The Issues really exist here, so recording defaults on.
|
|
1501
1244
|
write: !values['dry-run'],
|
|
1502
1245
|
});
|
|
1503
1246
|
|
|
1504
|
-
//
|
|
1505
|
-
// renders its sub-command's output; persisting it — and the stdout newline a
|
|
1506
|
-
// piped run needs — happens once, below. The chain restated that tail in
|
|
1507
|
-
// every arm, so each new sub-command paid for it twice: once in the branch
|
|
1508
|
-
// and once in the complexity budget. The optional fourth slot is an
|
|
1509
|
-
// after-persist tail for work that must not pre-empt the report.
|
|
1247
|
+
// [flag, render, newlineOnStdout, afterPersist?]
|
|
1510
1248
|
const subcommands = [
|
|
1511
1249
|
['auto', async () => json(await runAutoSummary()), true, commitLedger],
|
|
1512
1250
|
['scan', async () => json(await scanPlan()), true],
|
|
@@ -1528,17 +1266,9 @@ export async function runAuditToStories(
|
|
|
1528
1266
|
}
|
|
1529
1267
|
|
|
1530
1268
|
/**
|
|
1531
|
-
*
|
|
1532
|
-
*
|
|
1533
|
-
*
|
|
1534
|
-
* numbers yet — so this is where a human driving the create pass by hand sees
|
|
1535
|
-
* the ordering they will replay through `--wire-edges` (Story #5044).
|
|
1536
|
-
*
|
|
1537
|
-
* The trailing `--- grouping ---` block carries the container-Epic default
|
|
1538
|
-
* (Story #5139), so the standalone path states it where it is actually read.
|
|
1539
|
-
* The `--json` form stays a bare array on purpose: it is a documented output
|
|
1540
|
-
* shape with a test asserting it, and the Epic is an operator decision the
|
|
1541
|
-
* workflow's Phase 4 stop owns, not a field a machine consumer acts on.
|
|
1269
|
+
* Human-readable `--emit-stories` transcript. `dependsOn` is shown because the
|
|
1270
|
+
* blockers have no issue numbers yet (they are replayed via `--wire-edges`).
|
|
1271
|
+
* The Epic grouping block is text-only; `--json` stays a bare array.
|
|
1542
1272
|
*
|
|
1543
1273
|
* @param {Array<{ title: string, labels: string[], body: string, groupKey?: string, dependsOn?: string[] }>} built
|
|
1544
1274
|
* @returns {string}
|