mandrel 2.60.0 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +10 -10
- package/.agents/agents/story-worker.md +1 -1
- package/.agents/docs/agentrc-reference.json +4 -82
- package/.agents/docs/configuration.md +20 -87
- package/.agents/docs/workflows.md +1 -1
- package/.agents/instructions.md +1 -3
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/agentrc.schema.json +11 -486
- package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +14 -14
- package/.agents/scripts/acceptance-eval.js +32 -164
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +9 -45
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +46 -172
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +32 -99
- package/.agents/scripts/deliver-light.js +14 -101
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +36 -133
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +10 -50
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +31 -143
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -35
- package/.agents/scripts/lib/config/explain.js +9 -80
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +10 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
- package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
- package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -126
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +31 -259
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +21 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +83 -358
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -104
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +27 -111
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +31 -148
- package/.agents/scripts/plan-run-epilogue.js +11 -37
- package/.agents/scripts/pr-watch-with-update.js +76 -267
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -209
- package/.agents/scripts/stories-wave-tick.js +102 -472
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/deliver-digest.md +6 -4
- package/.agents/workflows/helpers/deliver-reference.md +114 -188
- package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
- package/.agents/workflows/helpers/plan-reference.md +86 -139
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +25 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +105 -661
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +15 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +16 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1183
- package/.agents/rules/known-tooling-behavior.md +0 -200
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -368
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -218
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -125
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,56 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Story body schema validator (
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* `body` to a **markdown string** via `serialize()` from
|
|
7
|
-
* `lib/story-body/story-body.js` (the decompose-author skill mandates this,
|
|
8
|
-
* and `createOp` in `epic-spec-reconciler-ops.js` throws on an object body —
|
|
9
|
-
* Story #3302). So at plan-time validation the Story body is a string, not an
|
|
10
|
-
* object. To make the rules below actually fire on canonical plans, a string
|
|
11
|
-
* body is **parsed** back into its structured form via `parseStoryBody`
|
|
12
|
-
* before the section checks run (Story #3906 — previously the validator
|
|
13
|
-
* `shouldSkipTicket`-skipped every string body, so the vague-verb check and
|
|
14
|
-
* non-empty-goal check never ran on any real decomposition). A still-structured object body (e.g. a caller that passes
|
|
15
|
-
* the pre-serialize shape directly) is validated as-is.
|
|
16
|
-
*
|
|
17
|
-
* Only `type: 'story'` tickets are validated; Feature/Epic tickets and
|
|
18
|
-
* null/empty bodies pass through. There is no `type::task` ticket layer in
|
|
19
|
-
* the 2-tier hierarchy (Epic → Story).
|
|
20
|
-
*
|
|
21
|
-
* Required after parse/normalize: a non-empty `goal`, and non-empty
|
|
22
|
-
* `changes` and `acceptance` arrays — and `changes` items must name at least
|
|
23
|
-
* one path-shaped token so vague verbs ("clean up", "refactor") can't slip
|
|
24
|
-
* through. Story #5342 dropped the non-empty `verify` requirement: an empty
|
|
25
|
-
* `verify[]` is a dry-run warning the ticket validator raises, not a
|
|
26
|
-
* refusal.
|
|
27
|
-
*
|
|
28
|
-
* `acceptance` / `verify` are the **top-level machine contract** (Story
|
|
29
|
-
* #4541). The decomposer prompt tells authors to write those lists once at
|
|
30
|
-
* the ticket's top level and omit the matching body sections; persist syncs
|
|
31
|
-
* them into the body at assemble time. Validation runs *before* that sync,
|
|
32
|
-
* so this validator resolves each contract field from the parsed body and
|
|
33
|
-
* falls back to the ticket's top-level array when the body section is
|
|
34
|
-
* absent. Without that fallback the validator rejected the very shape its
|
|
35
|
-
* own prompt prescribes.
|
|
36
|
-
*
|
|
37
|
-
* `body.changes` items must be object-form `{ path: string, assumption: enum }`
|
|
38
|
-
* entries (Story #2636 shape). Plain string bullets are rejected at parse
|
|
39
|
-
* time and by this validator.
|
|
40
|
-
*
|
|
41
|
-
* Object-form items must declare an `assumption` ∈ `creates |
|
|
42
|
-
* refactors-existing | exists | deletes`. The optional `body.references`
|
|
43
|
-
* array uses the same object shape and is the home for paths the Story
|
|
44
|
-
* reads but does not modify (test fixtures, sibling modules, etc.).
|
|
45
|
-
*
|
|
46
|
-
* `body.verify` entries are commands, nothing more: Story #5312 deleted the
|
|
47
|
-
* `(<tier>)` suffix, the `manual:<reason>` escape and the repair pass that
|
|
48
|
-
* appended the suffix for the author, and Story #5342 deleted the last rule
|
|
49
|
-
* — the non-empty check. This validator no longer scores `verify` at all.
|
|
50
|
-
*
|
|
51
|
-
* The errors are batched and surfaced as a single thrown Error so the
|
|
52
|
-
* planner can see every offending slug in one pass instead of fixing one
|
|
53
|
-
* at a time.
|
|
2
|
+
* Story body schema validator. String bodies (the canonical serialized form)
|
|
3
|
+
* are parsed before checking. Requires a non-empty `goal`, `acceptance`, and
|
|
4
|
+
* `changes` of `{ path, assumption }` objects; `references` is optional, same
|
|
5
|
+
* shape. `verify` is not scored. Errors are batched into one throw.
|
|
54
6
|
*/
|
|
55
7
|
|
|
56
8
|
import { suggestPathEntryFix } from '../story-body/body-format-lints.js';
|
|
@@ -61,48 +13,23 @@ import {
|
|
|
61
13
|
import { FILE_ASSUMPTION_VALUES } from './file-assumption-enum.js';
|
|
62
14
|
|
|
63
15
|
/**
|
|
64
|
-
*
|
|
65
|
-
* - it is not a Story (only `type: 'story'` tickets are validated here),
|
|
66
|
-
* - it has no body (null / undefined / empty-or-whitespace string — there
|
|
67
|
-
* is nothing to inspect).
|
|
68
|
-
*
|
|
69
|
-
* Under the 2-tier hierarchy (Epic → Story), Stories carry the
|
|
70
|
-
* implementation scope inline. A canonical decomposition serializes the
|
|
71
|
-
* Story body to a markdown string, so a *string* body is NOT skipped here
|
|
72
|
-
* (Story #3906) — `validateTaskBodyShape` parses it back into structured
|
|
73
|
-
* form via `parseStoryBody` before applying the section rules. This is what
|
|
74
|
-
* makes the vague-verb / non-empty-goal checks actually fire
|
|
75
|
-
* on real plans. Features (and everything else) use narrative string bodies
|
|
76
|
-
* and are skipped by the `type !== 'story'` guard.
|
|
77
|
-
*
|
|
78
|
-
* Returns `true` when the ticket should be ignored by
|
|
79
|
-
* `collectTaskBodyErrors`, `false` when the body should be inspected.
|
|
16
|
+
* Non-Stories and empty bodies are skipped; string bodies are NOT.
|
|
80
17
|
*
|
|
81
18
|
* @param {object} ticket
|
|
82
19
|
* @returns {boolean}
|
|
83
20
|
*/
|
|
84
21
|
function shouldSkipTicket(ticket) {
|
|
85
22
|
if (!ticket) return true;
|
|
86
|
-
// Only Stories carry an inline implementation contract in the 2-tier
|
|
87
|
-
// world. Features (and everything else) use narrative bodies.
|
|
88
23
|
if (ticket.type !== 'story') return true;
|
|
89
24
|
const body = ticket.body;
|
|
90
25
|
if (body == null) return true;
|
|
91
|
-
// An empty / whitespace-only string body carries no contract to inspect.
|
|
92
26
|
if (typeof body === 'string' && body.trim() === '') return true;
|
|
93
27
|
return false;
|
|
94
28
|
}
|
|
95
29
|
|
|
96
30
|
/**
|
|
97
|
-
* Resolve a Story ticket's body to the structured object the section rules
|
|
98
|
-
* operate on. A string body is the canonical serialized form — parse it via
|
|
99
|
-
* `parseStoryBody` (Story #3906). An object body is already structured and
|
|
100
|
-
* is returned verbatim (a caller may pass the pre-serialize shape directly).
|
|
101
|
-
*
|
|
102
31
|
* @param {object} ticket Story whose body passed `shouldSkipTicket`.
|
|
103
|
-
* @returns {{ body: object|null, error: string|null }}
|
|
104
|
-
* structured object when resolvable; `error` is a single message when a
|
|
105
|
-
* string body could not be parsed (mutually exclusive with `body`).
|
|
32
|
+
* @returns {{ body: object|null, error: string|null }} Mutually exclusive.
|
|
106
33
|
*/
|
|
107
34
|
function resolveStructuredBody(ticket) {
|
|
108
35
|
const raw = ticket.body;
|
|
@@ -122,25 +49,15 @@ function resolveStructuredBody(ticket) {
|
|
|
122
49
|
}
|
|
123
50
|
}
|
|
124
51
|
|
|
125
|
-
/**
|
|
126
|
-
* The two contract fields that live at the ticket's top level and are
|
|
127
|
-
* synced into the body by `plan-persist` at assemble time.
|
|
128
|
-
*/
|
|
129
52
|
const CONTRACT_FIELDS = Object.freeze(['acceptance', 'verify']);
|
|
130
53
|
|
|
131
54
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* sections; `assemblePlanStories#syncContractFieldFromTopLevel` performs
|
|
136
|
-
* the sync, but it runs *after* validation. So an absent body section is
|
|
137
|
-
* not a violation when the ticket carries the list at top level — it is the
|
|
138
|
-
* preferred shape. A body section that is present and disagrees with the
|
|
139
|
-
* top level is left alone here: the sync itself fails closed on that
|
|
140
|
-
* mismatch, and duplicating the check would report it twice.
|
|
55
|
+
* Fall back to top-level `acceptance[]` / `verify[]` (the preferred authoring
|
|
56
|
+
* shape): assembly syncs them into the body only after validation. A
|
|
57
|
+
* disagreeing body section is left to the sync, which fails closed.
|
|
141
58
|
*
|
|
142
59
|
* @param {object} ticket
|
|
143
|
-
* @param {object} bodyObject
|
|
60
|
+
* @param {object} bodyObject
|
|
144
61
|
* @returns {object} A copy of `bodyObject` with the contract fields resolved.
|
|
145
62
|
*/
|
|
146
63
|
function resolveContractFieldsFromTopLevel(ticket, bodyObject) {
|
|
@@ -156,19 +73,7 @@ function resolveContractFieldsFromTopLevel(ticket, bodyObject) {
|
|
|
156
73
|
}
|
|
157
74
|
|
|
158
75
|
/**
|
|
159
|
-
*
|
|
160
|
-
* array means clean. Splits the per-ticket cascade out of
|
|
161
|
-
* `collectTaskBodyErrors` so the iteration stays straight-line and so
|
|
162
|
-
* each section's defensive checks are independently testable.
|
|
163
|
-
*
|
|
164
|
-
* Accepts both the canonical **serialized string** body (parsed back into
|
|
165
|
-
* structured form via `parseStoryBody` — Story #3906) and the
|
|
166
|
-
* pre-serialize **structured object** body. A string body that cannot be
|
|
167
|
-
* parsed surfaces a single error.
|
|
168
|
-
*
|
|
169
|
-
* @param {object} ticket Story whose `body` has already passed the
|
|
170
|
-
* `shouldSkipTicket` filter (i.e. `body` is a non-empty string or an
|
|
171
|
-
* object).
|
|
76
|
+
* @param {object} ticket Story whose `body` passed `shouldSkipTicket`.
|
|
172
77
|
* @returns {string[]}
|
|
173
78
|
*/
|
|
174
79
|
export function validateTaskBodyShape(ticket) {
|
|
@@ -192,12 +97,6 @@ export function validateTaskBodyShape(ticket) {
|
|
|
192
97
|
}
|
|
193
98
|
|
|
194
99
|
/**
|
|
195
|
-
* Predicate: is `entry` a well-formed object-form path entry? Returns
|
|
196
|
-
* `true` only when it carries a non-empty `path` string and an
|
|
197
|
-
* `assumption` from the canonical enum. Bare objects without these
|
|
198
|
-
* fields surface as errors via `collectChangesErrors` /
|
|
199
|
-
* `collectReferencesErrors`.
|
|
200
|
-
*
|
|
201
100
|
* @param {unknown} entry
|
|
202
101
|
* @returns {entry is { path: string, assumption: typeof FILE_ASSUMPTION_VALUES[number] }}
|
|
203
102
|
*/
|
|
@@ -209,10 +108,7 @@ export function isObjectPathEntry(entry) {
|
|
|
209
108
|
}
|
|
210
109
|
|
|
211
110
|
/**
|
|
212
|
-
*
|
|
213
|
-
* has at least one invalid field? Distinct from `isObjectPathEntry` so
|
|
214
|
-
* we can route bad objects through a specific error message instead of
|
|
215
|
-
* silently collapsing them into the "name no path-shaped token" bucket.
|
|
111
|
+
* An object that is not a valid entry, so it gets a specific error message.
|
|
216
112
|
*
|
|
217
113
|
* @param {unknown} entry
|
|
218
114
|
* @returns {boolean}
|
|
@@ -220,8 +116,6 @@ export function isObjectPathEntry(entry) {
|
|
|
220
116
|
export function isMalformedObjectPathEntry(entry) {
|
|
221
117
|
if (entry === null || typeof entry !== 'object') return false;
|
|
222
118
|
if (isObjectPathEntry(entry)) return false;
|
|
223
|
-
// Anything that's an object and isn't a valid entry is malformed —
|
|
224
|
-
// string-form bullets fall through this predicate (they're not objects).
|
|
225
119
|
return true;
|
|
226
120
|
}
|
|
227
121
|
|
|
@@ -269,7 +163,6 @@ function collectChangesErrors(prefix, rawChanges) {
|
|
|
269
163
|
* @returns {string[]}
|
|
270
164
|
*/
|
|
271
165
|
function collectReferencesErrors(prefix, rawReferences) {
|
|
272
|
-
// `body.references` is optional — absent / null / undefined is fine.
|
|
273
166
|
if (rawReferences === undefined || rawReferences === null) return [];
|
|
274
167
|
if (!Array.isArray(rawReferences)) {
|
|
275
168
|
return [
|
|
@@ -308,10 +201,6 @@ function collectAcceptanceErrors(prefix, rawAcceptance) {
|
|
|
308
201
|
* @returns {string[]}
|
|
309
202
|
*/
|
|
310
203
|
/**
|
|
311
|
-
* Validate every 2-tier Story in `tickets` whose `body` is a structured
|
|
312
|
-
* object. Returns an array of error strings (one per offending slug); empty
|
|
313
|
-
* array means clean.
|
|
314
|
-
*
|
|
315
204
|
* @param {object[]} tickets
|
|
316
205
|
* @returns {string[]}
|
|
317
206
|
*/
|
|
@@ -325,9 +214,6 @@ export function collectTaskBodyErrors(tickets) {
|
|
|
325
214
|
}
|
|
326
215
|
|
|
327
216
|
/**
|
|
328
|
-
* Throw a single batched error if any Story body is malformed; otherwise
|
|
329
|
-
* return `tickets` unchanged.
|
|
330
|
-
*
|
|
331
217
|
* @param {object[]} tickets
|
|
332
218
|
* @returns {object[]}
|
|
333
219
|
*/
|
|
@@ -1,49 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* same Story. Rather than invent a new state column, the lease rides the
|
|
7
|
-
* ticket's existing **assignees** surface: the single assignee *is* the lease
|
|
8
|
-
* owner.
|
|
9
|
-
*
|
|
10
|
-
* **A foreign claim is a refusal, full stop (Story #5006).** The lease shipped
|
|
11
|
-
* with a TTL: a claim whose owner's last heartbeat was older than
|
|
12
|
-
* `delivery.lease.ttlMs` counted as stale and was silently reclaimed. The
|
|
13
|
-
* `story.heartbeat` emitter that would have fed it was structurally inert (it
|
|
14
|
-
* demanded an `epicId >= 1` that v2, which has no Epics, never supplies) and
|
|
15
|
-
* was deleted, after which every guard pinned `heartbeatAt` to `now` so the
|
|
16
|
-
* liveness test always answered "live" — the TTL, the heartbeat parameter and
|
|
17
|
-
* the reclaim branch were an elaborate way of writing `true`. They are gone.
|
|
18
|
-
* A stranded claim is cleared with `--steal`, which is now the only way past
|
|
19
|
-
* a foreign owner.
|
|
20
|
-
*
|
|
21
|
-
* The two exported operations are deliberately thin and provider-agnostic:
|
|
22
|
-
*
|
|
23
|
-
* - `acquireLease` — claim an unassigned ticket, re-affirm a self-held
|
|
24
|
-
* claim, or — with `steal: true` — forcibly transfer a
|
|
25
|
-
* foreign claim.
|
|
26
|
-
* - `releaseLease` — clear the assignment, but only when the operator
|
|
27
|
-
* still holds it (a no-op once the ticket was
|
|
28
|
-
* reassigned elsewhere, so a late release never steals
|
|
29
|
-
* a claim back from whoever took over).
|
|
30
|
-
*
|
|
31
|
-
* Provider contract (a subset of `ITicketingProvider`):
|
|
32
|
-
* - `getTicket(id)` → `{ assignees: string[], ... }`
|
|
33
|
-
* - `updateTicket(id, { assignees })` replaces the assignee list.
|
|
34
|
-
* - `updateTicket(id, { addAssignees })` appends to it (Story #5112).
|
|
2
|
+
* Assignee-as-lease: the ticket's single assignee is the lease owner. A
|
|
3
|
+
* foreign claim is always refused; `steal: true` (`--steal`) is the only way
|
|
4
|
+
* past one. Provider needs `getTicket` and `updateTicket` with `assignees`
|
|
5
|
+
* (replace) or `addAssignees` (append).
|
|
35
6
|
*/
|
|
36
7
|
|
|
37
8
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* templates carry this sentinel so `github.operatorHandle` is schema-present
|
|
41
|
-
* without naming a real person; each contributor overrides it with their own
|
|
42
|
-
* handle in the gitignored `.agentrc.local.json`. It is NOT a usable lease
|
|
43
|
-
* owner: `normalizeOperatorHandle` maps it to `null` so the guards fail closed
|
|
44
|
-
* (a contributor who never set their handle is loudly refused, never silently
|
|
45
|
-
* coordinated under a shared identity) and no assignee PATCH ever writes a
|
|
46
|
-
* literal `[USERNAME]` (HTTP 422).
|
|
9
|
+
* Shipped placeholder handle. Normalizes to `null` so an unset handle fails
|
|
10
|
+
* closed and no PATCH writes a literal `[USERNAME]` (HTTP 422).
|
|
47
11
|
*/
|
|
48
12
|
// kept (dead-export allowlist): public config sentinel — the distributed
|
|
49
13
|
// `.agentrc.json` / templates carry this literal; exported so consumers and
|
|
@@ -52,17 +16,8 @@ export const OPERATOR_HANDLE_PLACEHOLDER = '@[USERNAME]';
|
|
|
52
16
|
const OPERATOR_HANDLE_PLACEHOLDER_BARE = '[USERNAME]';
|
|
53
17
|
|
|
54
18
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* strips a single leading `@` so an `@`-prefixed `operatorHandle` matches a
|
|
58
|
-
* bare assignee login (otherwise the assignee PATCH is rejected HTTP 422 and
|
|
59
|
-
* the self-held-claim comparison `owner === operator` never matches).
|
|
60
|
-
*
|
|
61
|
-
* Returns `null` for a non-string, empty, whitespace-only, or placeholder
|
|
62
|
-
* handle (`@[USERNAME]`) so each caller can apply its own absent-handling
|
|
63
|
-
* (degrade to a no-op, or throw). Treating the placeholder as unset is what
|
|
64
|
-
* makes the shipped sentinel safe: a contributor who never overrode it is
|
|
65
|
-
* indistinguishable from one who set nothing, so the guards fail closed.
|
|
19
|
+
* Bare login (trimmed, one leading `@` stripped) so it matches assignee
|
|
20
|
+
* logins. `null` for empty or placeholder input; callers decide how to fail.
|
|
66
21
|
*
|
|
67
22
|
* @param {unknown} raw
|
|
68
23
|
* @returns {string|null}
|
|
@@ -77,9 +32,7 @@ export function normalizeOperatorHandle(raw) {
|
|
|
77
32
|
}
|
|
78
33
|
|
|
79
34
|
/**
|
|
80
|
-
*
|
|
81
|
-
* single-holder: the first assignee is authoritative. Returns `null` for an
|
|
82
|
-
* unassigned ticket.
|
|
35
|
+
* The first assignee is authoritative.
|
|
83
36
|
*
|
|
84
37
|
* @param {string[]|undefined|null} assignees
|
|
85
38
|
* @returns {string|null}
|
|
@@ -90,8 +43,6 @@ export function currentOwner(assignees) {
|
|
|
90
43
|
}
|
|
91
44
|
|
|
92
45
|
/**
|
|
93
|
-
* Validate and normalise the shared option bag for the lease operations.
|
|
94
|
-
*
|
|
95
46
|
* @param {string} op
|
|
96
47
|
* @param {object} opts
|
|
97
48
|
* @returns {{ provider: object, ticketId: number, operator: string }}
|
|
@@ -113,34 +64,13 @@ function normaliseOpts(op, opts) {
|
|
|
113
64
|
}
|
|
114
65
|
|
|
115
66
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* Outcomes:
|
|
119
|
-
* - Unassigned ticket → assign operator, `acquired: true`,
|
|
120
|
-
* `reason: 'unclaimed'`.
|
|
121
|
-
* - Operator already holds it → no write, `acquired: true`,
|
|
122
|
-
* `reason: 'already-held'`.
|
|
123
|
-
* - Foreign claim, no steal → no write, `acquired: false`,
|
|
124
|
-
* `owner: <foreign>`, `reason: 'held'`.
|
|
125
|
-
* - Foreign claim + `steal:true` → reassign operator, `acquired: true`,
|
|
126
|
-
* `reason: 'stolen'`.
|
|
127
|
-
* - Lost a write race → a foreign login co-assigned between our
|
|
128
|
-
* PATCH and the verify re-read; back the
|
|
129
|
-
* operator out, `acquired: false`,
|
|
130
|
-
* `owner: <foreign>`, `reason: 'lost-race'`.
|
|
131
|
-
*
|
|
132
|
-
* Every claiming write is verified: GitHub's assignee write is not a
|
|
133
|
-
* compare-and-set, so two runs that both read the ticket unassigned will both
|
|
134
|
-
* write themselves. {@link claimAndVerify} re-reads after the write and refuses
|
|
135
|
-
* (fail-closed) when a foreign login is present, so the loser of a simultaneous
|
|
136
|
-
* claim never proceeds as though it holds the lease. Story #5112 made the
|
|
137
|
-
* first claim **additive** so that verify can actually see the collision —
|
|
138
|
-
* see {@link claimAndVerify}.
|
|
67
|
+
* Every claiming write is verified by re-read, since assignee writes are not
|
|
68
|
+
* compare-and-set; a co-assigned foreign login yields `lost-race`.
|
|
139
69
|
*
|
|
140
70
|
* @param {object} opts
|
|
141
|
-
* @param {object} opts.provider
|
|
142
|
-
* @param {number} opts.ticketId
|
|
143
|
-
* @param {string} opts.operator
|
|
71
|
+
* @param {object} opts.provider
|
|
72
|
+
* @param {number} opts.ticketId
|
|
73
|
+
* @param {string} opts.operator
|
|
144
74
|
* @param {boolean} [opts.steal=false] Transfer a foreign claim.
|
|
145
75
|
* @returns {Promise<{
|
|
146
76
|
* acquired: boolean,
|
|
@@ -156,7 +86,6 @@ export async function acquireLease(opts) {
|
|
|
156
86
|
const ticket = await provider.getTicket(ticketId);
|
|
157
87
|
const owner = currentOwner(ticket?.assignees);
|
|
158
88
|
|
|
159
|
-
// Unclaimed → take it.
|
|
160
89
|
if (owner === null) {
|
|
161
90
|
return claimAndVerify({
|
|
162
91
|
provider,
|
|
@@ -167,7 +96,6 @@ export async function acquireLease(opts) {
|
|
|
167
96
|
});
|
|
168
97
|
}
|
|
169
98
|
|
|
170
|
-
// Already ours → no write needed.
|
|
171
99
|
if (owner === operator) {
|
|
172
100
|
return {
|
|
173
101
|
acquired: true,
|
|
@@ -177,7 +105,6 @@ export async function acquireLease(opts) {
|
|
|
177
105
|
};
|
|
178
106
|
}
|
|
179
107
|
|
|
180
|
-
// Foreign claim — refuse unless the operator explicitly steals it.
|
|
181
108
|
if (!steal) {
|
|
182
109
|
return {
|
|
183
110
|
acquired: false,
|
|
@@ -197,44 +124,21 @@ export async function acquireLease(opts) {
|
|
|
197
124
|
}
|
|
198
125
|
|
|
199
126
|
/**
|
|
200
|
-
* Write
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* The assignee write is not atomic — GitHub offers no compare-and-set on the
|
|
204
|
-
* assignees surface — so two runs that both observed the ticket unassigned (or
|
|
205
|
-
* a stale foreign claim) will both write themselves in. Without a check the
|
|
206
|
-
* loser of that race returns `acquired: true` and marches into the worktree
|
|
207
|
-
* the winner is already building. The verify closes that window: it re-reads
|
|
208
|
-
* with `fresh: true` (bypassing any provider cache so it sees the other run's
|
|
209
|
-
* write, not our own), and if a foreign login is present it concedes — removes
|
|
210
|
-
* the operator from the assignee set so no phantom co-owner lingers, and
|
|
211
|
-
* returns `acquired: false` / `reason: 'lost-race'` so the fail-closed caller
|
|
212
|
-
* refuses. A clean read (assignees exactly `[operator]`) confirms the claim.
|
|
213
|
-
*
|
|
214
|
-
* **The write must be additive for the verify to work (Story #5112).** With
|
|
215
|
-
* the replacing PATCH this used unconditionally, a simultaneous claim
|
|
216
|
-
* *evicted* the other operator rather than joining it, so the co-assignment
|
|
217
|
-
* the `lost-race` branch keys on was a state the PATCH could never produce:
|
|
218
|
-
* each run read a clean `[self]` on verify and both proceeded. Claiming an
|
|
219
|
-
* unowned ticket therefore goes through the additive assignees endpoint
|
|
220
|
-
* (`addAssignees`), which makes the collision observable and lets exactly one
|
|
221
|
-
* claimer survive. The replacing form stays for the two cases that genuinely
|
|
222
|
-
* mean "replace": the `--steal` transfer of a foreign claim, and the loser's
|
|
223
|
-
* own back-out below.
|
|
127
|
+
* Write, then re-read with `fresh: true`; on a foreign co-assignee, back out
|
|
128
|
+
* and report `lost-race` so the loser never builds the winner's worktree.
|
|
224
129
|
*
|
|
225
130
|
* @param {object} args
|
|
226
|
-
* @param {object} args.provider
|
|
227
|
-
* @param {number} args.ticketId
|
|
228
|
-
* @param {string} args.operator
|
|
229
|
-
* @param {string|null} args.previousOwner
|
|
131
|
+
* @param {object} args.provider
|
|
132
|
+
* @param {number} args.ticketId
|
|
133
|
+
* @param {string} args.operator
|
|
134
|
+
* @param {string|null} args.previousOwner
|
|
230
135
|
* @param {string} args.reason Success reason when the claim holds.
|
|
231
136
|
* @returns {Promise<{ acquired: boolean, owner: string, previousOwner: string|null, reason: string }>}
|
|
232
137
|
*/
|
|
233
138
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
* steal, where evicting the previous owner *is* the intent.
|
|
139
|
+
* Additive for an unowned ticket — a replacing PATCH would evict a
|
|
140
|
+
* simultaneous claimer, hiding the collision verify keys on. Replacing only
|
|
141
|
+
* for a steal.
|
|
238
142
|
*
|
|
239
143
|
* @param {string} operator
|
|
240
144
|
* @param {string|null} previousOwner
|
|
@@ -262,9 +166,7 @@ async function claimAndVerify({
|
|
|
262
166
|
return { acquired: true, owner: operator, previousOwner, reason };
|
|
263
167
|
}
|
|
264
168
|
|
|
265
|
-
//
|
|
266
|
-
// claim. Back ourselves out so the winner is the sole assignee, and report
|
|
267
|
-
// the loss so the fail-closed caller refuses rather than double-delivering.
|
|
169
|
+
// Lost the race: leave the winner as sole assignee.
|
|
268
170
|
await provider
|
|
269
171
|
.updateTicket(ticketId, { assignees: foreign })
|
|
270
172
|
.catch(() => undefined);
|
|
@@ -277,17 +179,12 @@ async function claimAndVerify({
|
|
|
277
179
|
}
|
|
278
180
|
|
|
279
181
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* Clears the ticket's assignees only when `operator` is still the recorded
|
|
283
|
-
* owner. If the ticket has since been reassigned (or was never held by this
|
|
284
|
-
* operator), the call is a no-op — a stale release must never yank a claim
|
|
285
|
-
* away from whoever legitimately holds it now.
|
|
182
|
+
* No-op unless `operator` still owns it — a stale release never yanks a claim.
|
|
286
183
|
*
|
|
287
184
|
* @param {object} opts
|
|
288
|
-
* @param {object} opts.provider
|
|
289
|
-
* @param {number} opts.ticketId
|
|
290
|
-
* @param {string} opts.operator
|
|
185
|
+
* @param {object} opts.provider
|
|
186
|
+
* @param {number} opts.ticketId
|
|
187
|
+
* @param {string} opts.operator
|
|
291
188
|
* @returns {Promise<{
|
|
292
189
|
* released: boolean,
|
|
293
190
|
* owner: string|null,
|