mandrel 2.60.0 → 2.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +32 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,90 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* Heuristic (uniform across anchors — Story #4649):
|
|
14
|
-
* - **Actionable** (renders as a pre-drafted `gh issue create` shell
|
|
15
|
-
* command): a friction `category` with **≥ 2** occurrences under the
|
|
16
|
-
* anchor, OR a blocked event whose root cause was never resolved (the
|
|
17
|
-
* caller supplies these as `unresolvedBlockedEvents`).
|
|
18
|
-
* - **Discarded**: a friction category under the threshold with no
|
|
19
|
-
* follow-on signal. Discarded is not silent — the caller still renders
|
|
20
|
-
* the bucket, so the event stays *recorded* without opening an issue.
|
|
21
|
-
* - **Netted out** before either decision: a category with a recovery
|
|
22
|
-
* marker for that Story (see `netOutRecoveredIncidents`) contributes
|
|
23
|
-
* nothing at all.
|
|
24
|
-
*
|
|
25
|
-
* `anchorKind` deliberately does NOT move the threshold. It used to — story
|
|
26
|
-
* scope promoted singletons at `≥ 1` — which, since the v2 Epic collapse put
|
|
27
|
-
* every close on a per-Story window of population 1, made *every* un-netted
|
|
28
|
-
* friction event auto-file. Cleanly-shipped Stories accumulated "recurred 1
|
|
29
|
-
* times" issues, which is how a warning channel gets tuned out. The signal
|
|
30
|
-
* that carve-out was standing in for is served properly by
|
|
31
|
-
* `unresolvedBlockedEvents`: a Story genuinely parked at `agent::blocked`
|
|
32
|
-
* forces actionable at count 1, while one that blocked and self-resolved
|
|
33
|
-
* nets out. `anchorKind` now only selects title/body wording.
|
|
34
|
-
*
|
|
35
|
-
* Routing:
|
|
36
|
-
* - Each actionable item is routed to `framework` or `consumer` based
|
|
37
|
-
* on the dominant `source` tag for that category. "Dominant" means
|
|
38
|
-
* the source with the higher count; ties resolve to whichever source
|
|
39
|
-
* contributed the first occurrence so the ordering is deterministic.
|
|
40
|
-
*
|
|
41
|
-
* Corpus vs. trigger (Story #4850):
|
|
42
|
-
* - The run-scope gather reduces over the **whole surviving recurrence
|
|
43
|
-
* window**, not the triggering run's own Stories — deliberately, because a
|
|
44
|
-
* systemic defect fires once per Story and scored 1 under the old per-run
|
|
45
|
-
* window (see `gatherRunFrictionSignals`). The composer therefore may NOT
|
|
46
|
-
* describe its corpus as "in <the triggering run>": it names the window it
|
|
47
|
-
* was reduced over (occurrences, distinct Stories, first-to-last dates) and
|
|
48
|
-
* carries the run as a separate labelled fact. When the corpus IS confined
|
|
49
|
-
* to the run's own Stories, the plain "in <anchor>" wording is kept — that
|
|
50
|
-
* is the common single-run case and it is not a false claim there.
|
|
51
|
-
*
|
|
52
|
-
* Publishable evidence (Story #4892):
|
|
53
|
-
* - A routed item's body is filed verbatim as a real GitHub issue, and its
|
|
54
|
-
* contributing-Story line is the recurrence claim a reader triages on. The
|
|
55
|
-
* ids used to be rendered with no validation at all, so a synthetic id
|
|
56
|
-
* from a test fixture reached a live ticket unchallenged: issue #4870 was
|
|
57
|
-
* auto-filed naming `#999999`, an id the framework reserves for fixtures,
|
|
58
|
-
* alongside one real Story. Contributing ids are therefore filtered
|
|
59
|
-
* through `isPublishableTicketId` before they can be counted or printed,
|
|
60
|
-
* and a bucket whose contributing ids are ALL unpublishable is discarded
|
|
61
|
-
* rather than routed — a proposal with no resolvable evidence must not
|
|
62
|
-
* auto-file at all. The filter is a resolvability bound, never a scope
|
|
63
|
-
* narrowing: a real Story from outside the triggering run is published
|
|
64
|
-
* exactly as before, which is the cross-run recurrence the window exists
|
|
65
|
-
* to produce.
|
|
66
|
-
*
|
|
67
|
-
* Determinism:
|
|
68
|
-
* - Output arrays are sorted by `category` ASC so a given input always
|
|
69
|
-
* yields byte-identical markdown (Story #2558 AC).
|
|
70
|
-
* - The rendered window is derived from the corpus's own timestamps, never
|
|
71
|
-
* from the clock, so the module stays pure and its output reproducible.
|
|
72
|
-
*
|
|
73
|
-
* The module is pure: no I/O, no provider calls, no time-dependent state.
|
|
2
|
+
* Pure composer: source-tagged friction signals → framework / consumer /
|
|
3
|
+
* discarded proposal sections. No I/O, no clock; output sorted by `category`
|
|
4
|
+
* so a given input renders byte-identically.
|
|
5
|
+
*
|
|
6
|
+
* A category is actionable at ≥ 2 occurrences (any anchor kind — a per-Story
|
|
7
|
+
* window has population 1, so a lower bar files every event) or when an
|
|
8
|
+
* unresolved block forces it; recovered incidents net out first. Actionable
|
|
9
|
+
* items route to the dominant `source` (ties → first seen). The corpus is the
|
|
10
|
+
* whole recurrence window, so bodies name the window, not the triggering run.
|
|
11
|
+
* Unpublishable (fixture) Story ids are never printed, and a bucket whose ids
|
|
12
|
+
* are all unpublishable is discarded rather than filed.
|
|
74
13
|
*
|
|
75
14
|
* @typedef {Object} FrictionSignal
|
|
76
|
-
* @property {string} category
|
|
15
|
+
* @property {string} category
|
|
77
16
|
* @property {"framework"|"consumer"} source
|
|
78
|
-
* @property {number} [storyId]
|
|
79
|
-
*
|
|
80
|
-
* @property {string} [
|
|
81
|
-
*
|
|
82
|
-
* @property {string|null} [ts] ISO-8601 emit time (Story #4850), carried by
|
|
83
|
-
* `normalizeGatheredSignal`; `null` when the row
|
|
84
|
-
* carried none a `Date` could read.
|
|
85
|
-
* @property {object} [details] Kind-specific payload; a record with
|
|
86
|
-
* `details.recovered === true` is a recovery
|
|
87
|
-
* marker for its own category.
|
|
17
|
+
* @property {number} [storyId] Used to net out recovered incidents.
|
|
18
|
+
* @property {string} [tool] Descriptive only, never routing.
|
|
19
|
+
* @property {string|null} [ts] ISO-8601; `null` when unreadable.
|
|
20
|
+
* @property {object} [details] `details.recovered === true` marks a recovery.
|
|
88
21
|
*
|
|
89
22
|
* @typedef {Object} BlockedEvent
|
|
90
23
|
* @property {number} ticketId
|
|
@@ -93,17 +26,11 @@
|
|
|
93
26
|
* @property {string} [summary]
|
|
94
27
|
*
|
|
95
28
|
* @typedef {Object} RoutedProposalsInput
|
|
96
|
-
* @property {number} anchorId
|
|
97
|
-
* @property {'story'|'run'} [anchorKind] Wording
|
|
98
|
-
* @property {string} [runToken]
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* it is an input now, so the composer never emits a token the caller then has
|
|
102
|
-
* to rewrite.
|
|
103
|
-
* @property {Array<number|string>} [anchorStoryIds] The triggering run's own
|
|
104
|
-
* Story ids. Decides whether the corpus is confined to the run (the anchor is
|
|
105
|
-
* then a true scope) or spans Stories outside it (the anchor is then only the
|
|
106
|
-
* trigger). Defaults to `[anchorId]`.
|
|
29
|
+
* @property {number} anchorId
|
|
30
|
+
* @property {'story'|'run'} [anchorKind] Wording only (default `story`).
|
|
31
|
+
* @property {string} [runToken] `plan-run::<id>` / `adhoc-<ids>`.
|
|
32
|
+
* @property {Array<number|string>} [anchorStoryIds] The run's own Stories;
|
|
33
|
+
* decides whether the corpus is confined to the run. Defaults to `[anchorId]`.
|
|
107
34
|
* @property {string} frameworkRepo `"<owner>/<repo>"`.
|
|
108
35
|
* @property {string} consumerRepo `"<owner>/<repo>"`.
|
|
109
36
|
* @property {FrictionSignal[]} [signals]
|
|
@@ -115,16 +42,15 @@
|
|
|
115
42
|
* @property {"framework"|"consumer"} source
|
|
116
43
|
* @property {string} title
|
|
117
44
|
* @property {string} body
|
|
118
|
-
* @property {string} command
|
|
45
|
+
* @property {string} command Pre-drafted `gh issue create` line.
|
|
119
46
|
*
|
|
120
47
|
* @typedef {Object} DiscardedItem
|
|
121
48
|
* @property {string} category
|
|
122
49
|
* @property {number} occurrences
|
|
123
50
|
* @property {"framework"|"consumer"} source
|
|
124
|
-
* @property {string[]} tools
|
|
125
|
-
* @property {string} fingerprint Stable 8-hex shape token
|
|
126
|
-
* @property {number} storyCount Distinct publishable Stories
|
|
127
|
-
* spans — the cross-run recurrence count.
|
|
51
|
+
* @property {string[]} tools
|
|
52
|
+
* @property {string} fingerprint Stable 8-hex shape token.
|
|
53
|
+
* @property {number} storyCount Distinct publishable Stories spanned.
|
|
128
54
|
*
|
|
129
55
|
* @typedef {Object} RoutedProposals
|
|
130
56
|
* @property {RoutedItem[]} framework
|
|
@@ -140,19 +66,12 @@ import {
|
|
|
140
66
|
} from '../observability/runtime-friction.js';
|
|
141
67
|
import { isPublishableTicketId } from '../reserved-test-ids.js';
|
|
142
68
|
|
|
143
|
-
/**
|
|
144
|
-
* Empty result helper — returned for zero-input callers so the consumer
|
|
145
|
-
* never needs to defensively spread undefineds.
|
|
146
|
-
*
|
|
147
|
-
* @returns {RoutedProposals}
|
|
148
|
-
*/
|
|
69
|
+
/** @returns {RoutedProposals} */
|
|
149
70
|
function emptyResult() {
|
|
150
71
|
return { framework: [], consumer: [], discarded: [] };
|
|
151
72
|
}
|
|
152
73
|
|
|
153
74
|
/**
|
|
154
|
-
* Normalise a stringy input to a trimmed string, or empty.
|
|
155
|
-
*
|
|
156
75
|
* @param {unknown} value
|
|
157
76
|
* @returns {string}
|
|
158
77
|
*/
|
|
@@ -162,10 +81,6 @@ function asString(value) {
|
|
|
162
81
|
}
|
|
163
82
|
|
|
164
83
|
/**
|
|
165
|
-
* Epoch milliseconds for a signal's `ts`, or `null` when it carries none a
|
|
166
|
-
* `Date` can read. Pure, so the composer stays time-independent: the window it
|
|
167
|
-
* renders is a property of the corpus, never of the clock.
|
|
168
|
-
*
|
|
169
84
|
* @param {unknown} ts
|
|
170
85
|
* @returns {number|null}
|
|
171
86
|
*/
|
|
@@ -176,8 +91,6 @@ function tsMillis(ts) {
|
|
|
176
91
|
}
|
|
177
92
|
|
|
178
93
|
/**
|
|
179
|
-
* Key a signal into its netting bucket: one `(category, storyId)` pair.
|
|
180
|
-
*
|
|
181
94
|
* @param {string} category
|
|
182
95
|
* @param {number} storyId
|
|
183
96
|
* @returns {string}
|
|
@@ -187,27 +100,11 @@ function incidentKey(category, storyId) {
|
|
|
187
100
|
}
|
|
188
101
|
|
|
189
102
|
/**
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* `story-blocked`, a confirmed land for `close-failed`. When a Story has such
|
|
196
|
-
* a marker, that incident was transient: lease contention or a stale label
|
|
197
|
-
* read under concurrent shared-checkout pressure (swarm-os friction #581), a
|
|
198
|
-
* close that failed once and succeeded on retry. This drops **every** record
|
|
199
|
-
* in that category for that Story (both the original incident and its
|
|
200
|
-
* recovery marker), so the retro counts only incidents that never resolved.
|
|
201
|
-
*
|
|
202
|
-
* The netting is per `(category, storyId)`, not 1:1 pairing: a Story that
|
|
203
|
-
* ever recovered from an incident in the run is treated as non-terminal for
|
|
204
|
-
* that category for the whole run. That is a deliberate coarsening — the
|
|
205
|
-
* aggregate is a routing heuristic, not an incident ledger, and the signal
|
|
206
|
-
* stream carries no reliable ordering to reconstruct interleaved
|
|
207
|
-
* incident/recover cycles. Keying on the category (rather than netting a
|
|
208
|
-
* Story wholesale) is what keeps a recovered close from also cancelling that
|
|
209
|
-
* Story's unrelated `story-blocked`. Records for other categories, and
|
|
210
|
-
* Stories with no recovery marker, pass through untouched.
|
|
103
|
+
* Drop every record in a `(category, storyId)` pair that carries a recovery
|
|
104
|
+
* marker (`details.recovered === true`), so only never-resolved incidents are
|
|
105
|
+
* counted. Deliberately coarse — the stream has no reliable ordering to pair
|
|
106
|
+
* incident/recover cycles — and keyed per category so a recovered close does
|
|
107
|
+
* not cancel the same Story's unrelated `story-blocked`.
|
|
211
108
|
*
|
|
212
109
|
* @param {FrictionSignal[]} signals
|
|
213
110
|
* @returns {FrictionSignal[]}
|
|
@@ -228,20 +125,8 @@ function netOutRecoveredIncidents(signals) {
|
|
|
228
125
|
}
|
|
229
126
|
|
|
230
127
|
/**
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* This is what replaces the retired story-scope threshold carve-out. A
|
|
234
|
-
* `story-blocked` record whose Story has no companion recovery marker is a
|
|
235
|
-
* Story still parked at `agent::blocked` — a human owes it a decision, and
|
|
236
|
-
* that is worth filing at a single occurrence. One that recovered is netted
|
|
237
|
-
* out by {@link netOutRecoveredIncidents} and produces no event here, so the
|
|
238
|
-
* two mechanisms agree by construction.
|
|
239
|
-
*
|
|
240
|
-
* Callers previously passed a hardcoded `[]`, which left
|
|
241
|
-
* `blockedForceActionable` permanently empty and made the carve-out the only
|
|
242
|
-
* thing that could file anything at story scope.
|
|
243
|
-
*
|
|
244
|
-
* Pure. Sorted by `ticketId` so the routed output stays deterministic.
|
|
128
|
+
* A `story-blocked` record with no recovery marker is a Story still parked at
|
|
129
|
+
* `agent::blocked`, worth filing at one occurrence. Sorted by `ticketId`.
|
|
245
130
|
*
|
|
246
131
|
* @param {FrictionSignal[]} signals
|
|
247
132
|
* @returns {BlockedEvent[]}
|
|
@@ -280,21 +165,12 @@ export function deriveUnresolvedBlockedEvents(signals) {
|
|
|
280
165
|
}
|
|
281
166
|
|
|
282
167
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* Deliberately over the detail **keys**, never their values: a `reason` names
|
|
287
|
-
* the file or command that failed and differs on every occurrence, so
|
|
288
|
-
* hashing values would mint a fresh fingerprint per event and identify
|
|
289
|
-
* nothing. The keys plus the emitting tool are what make two occurrences "the
|
|
290
|
-
* same defect".
|
|
291
|
-
*
|
|
292
|
-
* Descriptive only. Routing and de-duplication stay keyed on `category`, so a
|
|
293
|
-
* fingerprint can never split one filed issue into two.
|
|
168
|
+
* Hash of the emitting tools and `details` KEYS (values vary per event, so
|
|
169
|
+
* would identify nothing). Descriptive only — routing stays keyed on category.
|
|
294
170
|
*
|
|
295
171
|
* @param {string} category
|
|
296
|
-
* @param {string[]} tools Sorted, de-duplicated
|
|
297
|
-
* @param {string[]} detailKeys Sorted, de-duplicated
|
|
172
|
+
* @param {string[]} tools Sorted, de-duplicated.
|
|
173
|
+
* @param {string[]} detailKeys Sorted, de-duplicated.
|
|
298
174
|
* @returns {string} 8 hex characters.
|
|
299
175
|
*/
|
|
300
176
|
function fingerprintBucket(category, tools, detailKeys) {
|
|
@@ -306,21 +182,9 @@ function fingerprintBucket(category, tools, detailKeys) {
|
|
|
306
182
|
}
|
|
307
183
|
|
|
308
184
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
* Two keys because two emitter conventions, and the divergence was silent: the
|
|
313
|
-
* degradation emitters write a singular `details.reason` string, while the
|
|
314
|
-
* light path's refusal emitter (`light-escalation.recordScopeFriction`) writes
|
|
315
|
-
* `details.reasons` — an **array**, because one backstop verdict can object on
|
|
316
|
-
* sensitivity and magnitude in the same pass. Reading only the singular key is
|
|
317
|
-
* why every `light-scope-rejected` follow-up rendered with no `Reason:` line
|
|
318
|
-
* at all (issue #5237), which defeated Story #4837's whole intent for that
|
|
319
|
-
* emitter: the filed issue named a count and a category, and the refusal text
|
|
320
|
-
* that would have told a reader which ceiling fired stayed in the ledger.
|
|
321
|
-
*
|
|
322
|
-
* Non-string members are skipped rather than coerced — `String(value)` would
|
|
323
|
-
* put `[object Object]` in a live issue body.
|
|
185
|
+
* Reason texts from both emitter shapes: singular `details.reason` and the
|
|
186
|
+
* light-path refusal's `details.reasons` array. Non-strings are skipped, not
|
|
187
|
+
* coerced to `[object Object]`.
|
|
324
188
|
*
|
|
325
189
|
* @param {object} details
|
|
326
190
|
* @returns {string[]}
|
|
@@ -339,9 +203,7 @@ function collectReasons(details) {
|
|
|
339
203
|
}
|
|
340
204
|
|
|
341
205
|
/**
|
|
342
|
-
*
|
|
343
|
-
* usable `ts` widens nothing — it is counted in `total` but cannot date the
|
|
344
|
-
* corpus, so it must not be able to shrink the range either.
|
|
206
|
+
* A row with no usable `ts` is counted but never moves the window.
|
|
345
207
|
*
|
|
346
208
|
* @param {{ firstMs: number|null, lastMs: number|null }} entry
|
|
347
209
|
* @param {number|null} ms
|
|
@@ -354,19 +216,9 @@ function widenWindow(entry, ms) {
|
|
|
354
216
|
}
|
|
355
217
|
|
|
356
218
|
/**
|
|
357
|
-
* Aggregate
|
|
358
|
-
*
|
|
359
|
-
*
|
|
360
|
-
* Records with a missing/invalid `category` are skipped (no silent
|
|
361
|
-
* "" bucket). Records with an unknown `source` default to `"consumer"`
|
|
362
|
-
* — that matches the source-classifier's safe default.
|
|
363
|
-
*
|
|
364
|
-
* `category` is deliberately still the aggregation unit (Story #4824): it is
|
|
365
|
-
* what titles a filed issue and what the graduator's idempotency marker
|
|
366
|
-
* fingerprints, so splitting the bucket by emitter would file N issues where
|
|
367
|
-
* the loop is designed to file one. The emitter tools, `details` key set, and
|
|
368
|
-
* the distinct Stories a bucket spans ride **on** the entry instead, purely
|
|
369
|
-
* so a roll-up can name what it counted.
|
|
219
|
+
* Aggregate by `category` — the unit the graduator's idempotency marker keys
|
|
220
|
+
* on, so it must not split by emitter. Missing category is skipped; unknown
|
|
221
|
+
* `source` defaults to `"consumer"`.
|
|
370
222
|
*
|
|
371
223
|
* @param {FrictionSignal[]} signals
|
|
372
224
|
* @returns {Map<string, {
|
|
@@ -416,22 +268,14 @@ function aggregateByCategory(signals) {
|
|
|
416
268
|
if (tool.length > 0) entry.tools.add(tool);
|
|
417
269
|
if (sig.details !== null && typeof sig.details === 'object') {
|
|
418
270
|
for (const key of Object.keys(sig.details)) entry.detailKeys.add(key);
|
|
419
|
-
//
|
|
420
|
-
// #4837): the surface that degraded and the reason text. They are what
|
|
421
|
-
// turn "tool-degraded ×6" into "the scoped-lint gate could not execute
|
|
422
|
-
// and failed open" — the thing a reader absent from the run needs.
|
|
423
|
-
// Values never reach `detailKeys`, so the bucket fingerprint (hashed
|
|
424
|
-
// over keys, deliberately) is untouched by them.
|
|
271
|
+
// Surface and reason values reach the body, never the fingerprint.
|
|
425
272
|
const surface = asString(sig.details.surface);
|
|
426
273
|
if (surface.length > 0) entry.surfaces.add(surface);
|
|
427
274
|
for (const reason of collectReasons(sig.details)) {
|
|
428
275
|
entry.reasons.add(reason);
|
|
429
276
|
}
|
|
430
277
|
}
|
|
431
|
-
//
|
|
432
|
-
// rather than dropped: it must never be counted or printed as recurrence
|
|
433
|
-
// evidence, but "this bucket's only contributing ids were synthetic" is
|
|
434
|
-
// exactly what stops it auto-filing (see `hasPublishableStoryEvidence`).
|
|
278
|
+
// Unpublishable ids are withheld, not dropped: they gate auto-filing.
|
|
435
279
|
if (Number.isInteger(sig.storyId) && sig.storyId > 0) {
|
|
436
280
|
if (isPublishableTicketId(sig.storyId)) entry.storyIds.add(sig.storyId);
|
|
437
281
|
else entry.withheldStoryIds.add(sig.storyId);
|
|
@@ -441,17 +285,8 @@ function aggregateByCategory(signals) {
|
|
|
441
285
|
}
|
|
442
286
|
|
|
443
287
|
/**
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* Three cases, and the middle one is the point:
|
|
447
|
-
* - Some publishable id → yes, file it (the withheld ids are simply absent
|
|
448
|
-
* from the body).
|
|
449
|
-
* - Contributing ids, none publishable → **no**. Every id the bucket could
|
|
450
|
-
* cite is synthetic, so a filed issue would assert recurrence evidence
|
|
451
|
-
* that resolves to nothing. The bucket is discarded instead.
|
|
452
|
-
* - No contributing ids at all → yes. That is a bucket forced actionable by
|
|
453
|
-
* an unresolved block with no aggregated signals behind it; it never cited
|
|
454
|
-
* a Story, so there is nothing unresolvable about it.
|
|
288
|
+
* False only when every contributing id is unpublishable — a filed issue would
|
|
289
|
+
* then cite evidence that resolves to nothing. No ids at all is fine.
|
|
455
290
|
*
|
|
456
291
|
* @param {{ storyIds: Set<number>, withheldStoryIds: Set<number> }} entry
|
|
457
292
|
* @returns {boolean}
|
|
@@ -461,16 +296,6 @@ function hasPublishableStoryEvidence(entry) {
|
|
|
461
296
|
}
|
|
462
297
|
|
|
463
298
|
/**
|
|
464
|
-
* Project an aggregate entry's descriptive fields onto a `DiscardedItem`
|
|
465
|
-
* (Story #4824).
|
|
466
|
-
*
|
|
467
|
-
* A roll-up that discards every candidate used to render as a bare
|
|
468
|
-
* `` `category` ×1 `` per row, which is how a defect recurring once per Story
|
|
469
|
-
* across eighteen consecutive Stories stayed invisible. The row now names the
|
|
470
|
-
* emitting tools, the bucket fingerprint, and how many distinct Stories it
|
|
471
|
-
* spans — the last is the cross-run count the widened recurrence window
|
|
472
|
-
* exists to produce.
|
|
473
|
-
*
|
|
474
299
|
* @param {{ category: string, tools: Set<string>, detailKeys: Set<string>, storyIds: Set<number> }} entry
|
|
475
300
|
* @returns {{ tools: string[], fingerprint: string, storyCount: number }}
|
|
476
301
|
*/
|
|
@@ -485,20 +310,8 @@ function describeBucket(entry) {
|
|
|
485
310
|
}
|
|
486
311
|
|
|
487
312
|
/**
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
* Story #4824 put the emitting tools, the shape fingerprint and the
|
|
491
|
-
* distinct-Story span on the aggregate entry, but projected them only onto
|
|
492
|
-
* the *discarded* rows — so the one bucket that actually became a GitHub
|
|
493
|
-
* issue was rendered from a category and a count alone. Measured on issue
|
|
494
|
-
* #4836: a `tool-degraded ×6` body that never named `native-review-lint`,
|
|
495
|
-
* never named the `scoped-lint` surface, and never named the reason, so the
|
|
496
|
-
* review gate that could not execute and failed open appeared nowhere in the
|
|
497
|
-
* ticket opened about it.
|
|
498
|
-
*
|
|
499
|
-
* Every collection is sorted so the same input renders byte-identically —
|
|
500
|
-
* the body is written to a live issue on every recurrence, and an unstable
|
|
501
|
-
* ordering would rewrite it with no change of meaning.
|
|
313
|
+
* Evidence an actionable body names. Collections are sorted: the body is
|
|
314
|
+
* rewritten to a live issue on every recurrence.
|
|
502
315
|
*
|
|
503
316
|
* @param {{
|
|
504
317
|
* category: string,
|
|
@@ -522,9 +335,7 @@ function describeEvidence(entry) {
|
|
|
522
335
|
surfaces: [...entry.surfaces].sort(),
|
|
523
336
|
reasons: [...entry.reasons].sort(),
|
|
524
337
|
storyIds: [...entry.storyIds].sort((a, b) => a - b),
|
|
525
|
-
//
|
|
526
|
-
// projected onto `describeBucket`: a discarded row is rendered from the
|
|
527
|
-
// bucket shape, and the window belongs to the claim a *filed* issue makes.
|
|
338
|
+
// Only a filed issue claims a window; discarded rows omit it.
|
|
528
339
|
window: { firstMs: entry.firstMs, lastMs: entry.lastMs },
|
|
529
340
|
};
|
|
530
341
|
}
|
|
@@ -549,9 +360,7 @@ const MAX_RENDERED_REASONS = 3;
|
|
|
549
360
|
const MAX_RENDERED_STORIES = 12;
|
|
550
361
|
|
|
551
362
|
/**
|
|
552
|
-
*
|
|
553
|
-
* say. A missing field is omitted outright rather than rendered as "none":
|
|
554
|
-
* an absent emitter is not the finding.
|
|
363
|
+
* `null` (omitted) rather than "none" when there are no values.
|
|
555
364
|
*
|
|
556
365
|
* @param {string} label
|
|
557
366
|
* @param {string[]} values
|
|
@@ -562,11 +371,6 @@ function evidenceLine(label, values) {
|
|
|
562
371
|
}
|
|
563
372
|
|
|
564
373
|
/**
|
|
565
|
-
* Render the contributing-Story line: the distinct Stories that emitted into
|
|
566
|
-
* this bucket. This is the cross-run recurrence evidence — the difference
|
|
567
|
-
* between "happened six times somewhere" and "happened on these six Stories,
|
|
568
|
-
* so it is not one bad afternoon".
|
|
569
|
-
*
|
|
570
374
|
* @param {number[]} storyIds
|
|
571
375
|
* @param {number} storyCount
|
|
572
376
|
* @returns {string|null}
|
|
@@ -581,9 +385,6 @@ function storiesLine(storyIds, storyCount) {
|
|
|
581
385
|
}
|
|
582
386
|
|
|
583
387
|
/**
|
|
584
|
-
* Render the reason texts the emitters supplied, capped so one pathological
|
|
585
|
-
* bucket cannot produce an unreadable issue body.
|
|
586
|
-
*
|
|
587
388
|
* @param {string[]} reasons
|
|
588
389
|
* @returns {string|null}
|
|
589
390
|
*/
|
|
@@ -596,9 +397,7 @@ function reasonsLine(reasons) {
|
|
|
596
397
|
}
|
|
597
398
|
|
|
598
399
|
/**
|
|
599
|
-
*
|
|
600
|
-
* `firstSource` so byte-identical inputs always produce byte-identical
|
|
601
|
-
* routing.
|
|
400
|
+
* Ties resolve to `firstSource` so routing is deterministic.
|
|
602
401
|
*
|
|
603
402
|
* @param {{ bySource: { framework: number, consumer: number }, firstSource: "framework"|"consumer" }} entry
|
|
604
403
|
* @returns {"framework"|"consumer"}
|
|
@@ -611,12 +410,6 @@ function dominantSource(entry) {
|
|
|
611
410
|
}
|
|
612
411
|
|
|
613
412
|
/**
|
|
614
|
-
* Name the triggering anchor. For a run that means its own token when the
|
|
615
|
-
* caller supplied one (Story #4850) — `run-epilogue.js` previously let the
|
|
616
|
-
* composer print the primary Story's numeric id as if it were the run id and
|
|
617
|
-
* then rewrote it by regex, which meant the rendered text and the caller's
|
|
618
|
-
* notion of the run could silently disagree.
|
|
619
|
-
*
|
|
620
413
|
* @param {'story'|'run'} kind
|
|
621
414
|
* @param {number} id
|
|
622
415
|
* @param {string} runToken
|
|
@@ -627,13 +420,6 @@ function formatAnchor(kind, id, runToken) {
|
|
|
627
420
|
}
|
|
628
421
|
|
|
629
422
|
/**
|
|
630
|
-
* Label the evidence fact that names the triggering anchor.
|
|
631
|
-
*
|
|
632
|
-
* Tracks `anchorKind` for the same reason {@link formatAnchor} does. Story
|
|
633
|
-
* #4850 introduced the fact with a fixed `Triggering run` label, which on the
|
|
634
|
-
* story-scope path called a Story a run (`Triggering run: Story #7`) — the one
|
|
635
|
-
* place in this file where the wording did not follow the anchor.
|
|
636
|
-
*
|
|
637
423
|
* @param {'story'|'run'} kind
|
|
638
424
|
* @returns {string}
|
|
639
425
|
*/
|
|
@@ -642,11 +428,8 @@ function formatTriggerLabel(kind) {
|
|
|
642
428
|
}
|
|
643
429
|
|
|
644
430
|
/**
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
* Day granularity on purpose: the window is triage context ("this has been
|
|
648
|
-
* recurring for three weeks"), and a full timestamp would rewrite the live
|
|
649
|
-
* issue body on every recurrence for no change of meaning.
|
|
431
|
+
* UTC day, deliberately: a full timestamp would rewrite the live issue body on
|
|
432
|
+
* every recurrence.
|
|
650
433
|
*
|
|
651
434
|
* @param {number|null} ms
|
|
652
435
|
* @returns {string}
|
|
@@ -656,9 +439,7 @@ function isoDay(ms) {
|
|
|
656
439
|
}
|
|
657
440
|
|
|
658
441
|
/**
|
|
659
|
-
*
|
|
660
|
-
* bucket carried a readable `ts`. Omitting it is the honest degradation: an
|
|
661
|
-
* undateable corpus must not be given a made-up range.
|
|
442
|
+
* `''` when the corpus is undateable — never a made-up range.
|
|
662
443
|
*
|
|
663
444
|
* @param {{ firstMs: number|null, lastMs: number|null }} window
|
|
664
445
|
* @returns {string}
|
|
@@ -671,8 +452,6 @@ function windowPhrase(window) {
|
|
|
671
452
|
}
|
|
672
453
|
|
|
673
454
|
/**
|
|
674
|
-
* The same window as the compact span a title carries.
|
|
675
|
-
*
|
|
676
455
|
* @param {{ firstMs: number|null, lastMs: number|null }} window
|
|
677
456
|
* @returns {string}
|
|
678
457
|
*/
|
|
@@ -684,8 +463,6 @@ function windowSpan(window) {
|
|
|
684
463
|
}
|
|
685
464
|
|
|
686
465
|
/**
|
|
687
|
-
* `across N Stories`, or `''` when no Story could be attributed.
|
|
688
|
-
*
|
|
689
466
|
* @param {number} storyCount
|
|
690
467
|
* @returns {string}
|
|
691
468
|
*/
|
|
@@ -694,29 +471,14 @@ function storySpan(storyCount) {
|
|
|
694
471
|
return `across ${storyCount} ${storyCount === 1 ? 'Story' : 'Stories'}`;
|
|
695
472
|
}
|
|
696
473
|
|
|
697
|
-
/**
|
|
698
|
-
* Occurrences needed before a category routes on its own. Uniform across
|
|
699
|
-
* anchors (Story #4649) — see the module header for why story scope no
|
|
700
|
-
* longer promotes singletons.
|
|
701
|
-
*/
|
|
702
474
|
const ACTIONABLE_THRESHOLD = 2;
|
|
703
475
|
|
|
704
|
-
/** A category routes when it recurred, or when a block forces it. */
|
|
705
476
|
function isActionableFriction(total, force) {
|
|
706
477
|
return total >= ACTIONABLE_THRESHOLD || Boolean(force);
|
|
707
478
|
}
|
|
708
479
|
|
|
709
480
|
/**
|
|
710
|
-
*
|
|
711
|
-
* contents (Story #4850).
|
|
712
|
-
*
|
|
713
|
-
* This line used to read `surfaced N times during <anchor>`, where `<anchor>`
|
|
714
|
-
* was the run whose epilogue happened to fire. The corpus is the whole
|
|
715
|
-
* surviving recurrence window (deliberately — see `gatherRunFrictionSignals`),
|
|
716
|
-
* so on any systemic defect the sentence asserted a scope the evidence block
|
|
717
|
-
* three lines below it already contradicted by listing foreign Stories. It now
|
|
718
|
-
* describes the window it was actually reduced over; the triggering run is a
|
|
719
|
-
* separate labelled fact, because that is what it is.
|
|
481
|
+
* Sized and dated by the corpus itself, never by the triggering run.
|
|
720
482
|
*
|
|
721
483
|
* @param {string} category
|
|
722
484
|
* @param {number} occurrences
|
|
@@ -733,22 +495,8 @@ function corpusSentence(category, occurrences, evidence) {
|
|
|
733
495
|
}
|
|
734
496
|
|
|
735
497
|
/**
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
* representation of what the operator would paste.
|
|
739
|
-
*
|
|
740
|
-
* The evidence block (Story #4837) is what makes the issue actionable by
|
|
741
|
-
* someone who was not in the run: the emitting tool, the surface that
|
|
742
|
-
* degraded, the reason the emitter gave, the distinct Stories it spans, and
|
|
743
|
-
* the shape fingerprint that ties recurrences together. Absent fields are
|
|
744
|
-
* omitted, so a bucket that genuinely carries no evidence renders as it
|
|
745
|
-
* always did rather than as a wall of "unknown".
|
|
746
|
-
*
|
|
747
|
-
* The triggering anchor leads that block (Story #4850): it is what caused this
|
|
748
|
-
* issue to be *filed now*, which is worth naming, and is exactly not the same
|
|
749
|
-
* claim as its being where the occurrences happened. Its label tracks
|
|
750
|
-
* `anchorKind` via {@link formatTriggerLabel}, so the story-scope path says
|
|
751
|
-
* `Triggering Story` rather than calling a Story a run.
|
|
498
|
+
* Plain text (no headings) so the heredoc matches what an operator pastes.
|
|
499
|
+
* The trigger is a separate fact from where the occurrences happened.
|
|
752
500
|
*
|
|
753
501
|
* @param {{
|
|
754
502
|
* anchor: { label: string, trigger: string },
|
|
@@ -786,11 +534,7 @@ function renderIssueBody({ anchor, category, occurrences, source, evidence }) {
|
|
|
786
534
|
}
|
|
787
535
|
|
|
788
536
|
/**
|
|
789
|
-
*
|
|
790
|
-
* item. The command is rendered verbatim — operators copy-paste it as-is.
|
|
791
|
-
*
|
|
792
|
-
* The body is supplied via `--body-file -` and a trailing heredoc so the
|
|
793
|
-
* multi-line content survives shell quoting on every platform.
|
|
537
|
+
* Body goes via `--body-file -` heredoc so multi-line content survives quoting.
|
|
794
538
|
*
|
|
795
539
|
* @param {{
|
|
796
540
|
* repo: string,
|
|
@@ -803,8 +547,7 @@ function renderIssueBody({ anchor, category, occurrences, source, evidence }) {
|
|
|
803
547
|
*/
|
|
804
548
|
function renderIssueCommand({ repo, title, metaLabel, category, body }) {
|
|
805
549
|
const labels = `meta::${metaLabel},friction::${category}`;
|
|
806
|
-
//
|
|
807
|
-
// running on PowerShell convert it to a `--body` flag if needed.
|
|
550
|
+
// PowerShell agents convert the heredoc to `--body`.
|
|
808
551
|
return [
|
|
809
552
|
`gh issue create --repo ${repo} --title "${title}" --label "${labels}" --body-file - <<EOF`,
|
|
810
553
|
body,
|
|
@@ -813,23 +556,9 @@ function renderIssueCommand({ repo, title, metaLabel, category, body }) {
|
|
|
813
556
|
}
|
|
814
557
|
|
|
815
558
|
/**
|
|
816
|
-
*
|
|
817
|
-
*
|
|
818
|
-
*
|
|
819
|
-
* Two forms, selected by whether the corpus is *confined* to the triggering
|
|
820
|
-
* run's own Stories:
|
|
821
|
-
*
|
|
822
|
-
* - **Confined** → `recurred N times in <anchor>`. The anchor genuinely is
|
|
823
|
-
* the scope, and this is the common single-run case; hedging it would make
|
|
824
|
-
* every ordinary title longer and vaguer for no gain.
|
|
825
|
-
* - **Spanning** → `recurred N times across M Stories (<first> → <last>)`.
|
|
826
|
-
* The anchor is dropped from the *claim* entirely (it stays in the body as
|
|
827
|
-
* the triggering fact), because naming it here is the falsehood: the
|
|
828
|
-
* occurrences did not happen in it.
|
|
829
|
-
*
|
|
830
|
-
* Retitling is de-dupe safe — the graduator's idempotency marker is
|
|
831
|
-
* category-fingerprint-only and anchor-free (Story #4837), and the title is
|
|
832
|
-
* deliberately excluded from the hash.
|
|
559
|
+
* `in <anchor>` only when the corpus is confined to the run's Stories;
|
|
560
|
+
* otherwise `across M Stories (<first> → <last>)`. Retitling is de-dupe safe:
|
|
561
|
+
* the graduator's marker excludes the title.
|
|
833
562
|
*
|
|
834
563
|
* @param {{
|
|
835
564
|
* category: string,
|
|
@@ -855,11 +584,7 @@ function renderIssueTitle({
|
|
|
855
584
|
}
|
|
856
585
|
|
|
857
586
|
/**
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
* A corpus with no attributable Story at all (a block forced actionable with no
|
|
861
|
-
* aggregated signals) counts as confined: there is no foreign evidence to
|
|
862
|
-
* contradict the anchor, so the plain wording stays.
|
|
587
|
+
* An empty corpus counts as confined.
|
|
863
588
|
*
|
|
864
589
|
* @param {number[]} storyIds
|
|
865
590
|
* @param {Set<number>} anchorStoryIds
|
|
@@ -870,8 +595,6 @@ function isCorpusConfined(storyIds, anchorStoryIds) {
|
|
|
870
595
|
}
|
|
871
596
|
|
|
872
597
|
/**
|
|
873
|
-
* Build an actionable RoutedItem for a category.
|
|
874
|
-
*
|
|
875
598
|
* @param {{
|
|
876
599
|
* anchor: { label: string, trigger: string, storyIds: Set<number> },
|
|
877
600
|
* category: string,
|
|
@@ -920,9 +643,6 @@ function buildRoutedItem({
|
|
|
920
643
|
}
|
|
921
644
|
|
|
922
645
|
/**
|
|
923
|
-
* Validate that the input shape is sane and extract typed arrays. Returns
|
|
924
|
-
* `null` when input is unusable (caller short-circuits to `emptyResult`).
|
|
925
|
-
*
|
|
926
646
|
* @param {unknown} input
|
|
927
647
|
* @returns {{
|
|
928
648
|
* anchor: { label: string, trigger: string, storyIds: Set<number> },
|
|
@@ -937,11 +657,7 @@ function normalizeAnchorKind(kind) {
|
|
|
937
657
|
}
|
|
938
658
|
|
|
939
659
|
/**
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
* The default is what keeps story-scope capture byte-identical: one Story's
|
|
943
|
-
* stream can only carry its own id, so the corpus is confined by construction
|
|
944
|
-
* and the wording never hedges.
|
|
660
|
+
* Defaults to the anchor itself, so story scope is confined by construction.
|
|
945
661
|
*
|
|
946
662
|
* @param {unknown} raw
|
|
947
663
|
* @param {number} anchorId
|
|
@@ -1051,8 +767,6 @@ function routeCategoryBuckets({
|
|
|
1051
767
|
source: info.source,
|
|
1052
768
|
frameworkRepo,
|
|
1053
769
|
consumerRepo,
|
|
1054
|
-
// Forced actionable by an unresolved block with no aggregated
|
|
1055
|
-
// signals behind it — there is no bucket to describe.
|
|
1056
770
|
evidence: emptyEvidence(),
|
|
1057
771
|
}),
|
|
1058
772
|
);
|
|
@@ -1064,15 +778,6 @@ function routeCategoryBuckets({
|
|
|
1064
778
|
}
|
|
1065
779
|
|
|
1066
780
|
/**
|
|
1067
|
-
* Compose the four routed proposal sections from aggregated source-tagged
|
|
1068
|
-
* signals.
|
|
1069
|
-
*
|
|
1070
|
-
* Pure — no I/O, no time-dependent state, no provider calls. Returns an
|
|
1071
|
-
* object with three arrays:
|
|
1072
|
-
* - `framework`: actionable items routed to the framework repo.
|
|
1073
|
-
* - `consumer`: actionable items routed to the consumer repo.
|
|
1074
|
-
* - `discarded`: single-occurrence friction with no follow-on signal.
|
|
1075
|
-
*
|
|
1076
781
|
* @param {RoutedProposalsInput} input
|
|
1077
782
|
* @returns {RoutedProposals}
|
|
1078
783
|
*/
|