mandrel 2.59.0 → 2.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/README.md +21 -19
- package/.agents/agents/acceptance-critic.md +24 -43
- package/.agents/agents/story-worker.md +20 -21
- package/.agents/docs/agentrc-reference.json +5 -84
- package/.agents/docs/configuration.md +48 -132
- package/.agents/docs/workflows.md +2 -2
- package/.agents/instructions.md +5 -8
- package/.agents/rules/ci-remediation.md +41 -8
- package/.agents/rules/gherkin-standards.md +4 -0
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +16 -496
- package/.agents/schemas/story-deliver-terminal.schema.json +13 -3
- package/.agents/schemas/validation-evidence.schema.json +2 -1
- package/.agents/scripts/README.md +23 -13
- package/.agents/scripts/acceptance-eval.js +35 -169
- package/.agents/scripts/agents-bootstrap-github.js +27 -129
- package/.agents/scripts/apply-quality-bootstrap.js +4 -40
- package/.agents/scripts/audit-baselines.js +6 -27
- package/.agents/scripts/audit-labels-bootstrap.js +5 -29
- package/.agents/scripts/audit-to-stories.js +91 -361
- package/.agents/scripts/boot-sweep.js +19 -72
- package/.agents/scripts/bootstrap.js +74 -395
- package/.agents/scripts/ceremony-derive.js +10 -41
- package/.agents/scripts/check-arch-cycles.js +14 -64
- package/.agents/scripts/check-baselines.js +8 -48
- package/.agents/scripts/check-context-budget.js +105 -311
- package/.agents/scripts/check-cyclomatic.js +12 -44
- package/.agents/scripts/check-dead-exports.js +13 -64
- package/.agents/scripts/check-doc-links.js +38 -186
- package/.agents/scripts/check-gherkin-corpus.js +24 -127
- package/.agents/scripts/check-test-temp-hygiene.js +28 -169
- package/.agents/scripts/coverage-capture.js +34 -98
- package/.agents/scripts/deliver-light.js +25 -171
- package/.agents/scripts/deliver-recover.js +6 -42
- package/.agents/scripts/deliver-run.js +534 -0
- package/.agents/scripts/diagnose-friction.js +24 -116
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +23 -85
- package/.agents/scripts/file-ci-gap.js +57 -49
- package/.agents/scripts/generate-config-docs.js +30 -170
- package/.agents/scripts/generate-lens-checklists.js +8 -52
- package/.agents/scripts/generate-skills-index.js +14 -112
- package/.agents/scripts/generate-workflows-doc.js +10 -70
- package/.agents/scripts/git-cleanup.js +2 -34
- package/.agents/scripts/lib/Graph.js +24 -81
- package/.agents/scripts/lib/ITicketingProvider.js +47 -143
- package/.agents/scripts/lib/Logger.js +14 -76
- package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
- package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
- package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
- package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
- package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
- package/.agents/scripts/lib/audit-baselines/read.js +3 -16
- package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
- package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
- package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
- package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
- package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
- package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
- package/.agents/scripts/lib/audit-suite/findings.js +12 -52
- package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
- package/.agents/scripts/lib/audit-suite/index.js +1 -15
- package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
- package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
- package/.agents/scripts/lib/audit-suite/runner.js +13 -43
- package/.agents/scripts/lib/audit-suite/selector.js +49 -349
- package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
- package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
- package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
- package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
- package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
- package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
- package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
- package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
- package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
- package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
- package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
- package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
- package/.agents/scripts/lib/baseline-loader.js +12 -51
- package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
- package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
- package/.agents/scripts/lib/baselines/components.js +10 -61
- package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
- package/.agents/scripts/lib/baselines/crap-preview-incremental.js +7 -19
- package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
- package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
- package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
- package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
- package/.agents/scripts/lib/baselines/envelope.js +13 -129
- package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
- package/.agents/scripts/lib/baselines/git-base.js +23 -142
- package/.agents/scripts/lib/baselines/kernel.js +11 -111
- package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
- package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
- package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
- package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
- package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
- package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
- package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
- package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
- package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
- package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
- package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
- package/.agents/scripts/lib/baselines/path-canon.js +19 -128
- package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
- package/.agents/scripts/lib/baselines/reader.js +14 -107
- package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
- package/.agents/scripts/lib/baselines/scope.js +11 -135
- package/.agents/scripts/lib/baselines/writer.js +16 -149
- package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
- package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
- package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
- package/.agents/scripts/lib/bdd-step-index.js +26 -100
- package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
- package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
- package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
- package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
- package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
- package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
- package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
- package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
- package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
- package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
- package/.agents/scripts/lib/bootstrap/summary.js +1 -8
- package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
- package/.agents/scripts/lib/branch-name-guard.js +4 -23
- package/.agents/scripts/lib/changed-files.js +39 -121
- package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
- package/.agents/scripts/lib/checks/index.js +18 -101
- package/.agents/scripts/lib/checks/loop-health.js +11 -53
- package/.agents/scripts/lib/checks/state.js +16 -91
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
- package/.agents/scripts/lib/child-exec.js +39 -108
- package/.agents/scripts/lib/cli/standard-args.js +9 -116
- package/.agents/scripts/lib/cli-args.js +31 -146
- package/.agents/scripts/lib/cli-usage.js +5 -27
- package/.agents/scripts/lib/cli-utils.js +2 -12
- package/.agents/scripts/lib/close-validation/commands.js +13 -76
- package/.agents/scripts/lib/close-validation/gates.js +92 -331
- package/.agents/scripts/lib/close-validation/process.js +121 -151
- package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
- package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
- package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
- package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
- package/.agents/scripts/lib/close-validation/runner.js +53 -110
- package/.agents/scripts/lib/command-header.js +6 -28
- package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
- package/.agents/scripts/lib/config/baselines.js +3 -14
- package/.agents/scripts/lib/config/ci.js +8 -38
- package/.agents/scripts/lib/config/commands.js +1 -15
- package/.agents/scripts/lib/config/defaults.js +4 -33
- package/.agents/scripts/lib/config/delivery-routing.js +6 -34
- package/.agents/scripts/lib/config/explain.js +10 -83
- package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
- package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +3 -31
- package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
- package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
- package/.agents/scripts/lib/config/gates/index.js +2 -17
- package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
- package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
- package/.agents/scripts/lib/config/gates/shared.js +4 -64
- package/.agents/scripts/lib/config/github.js +4 -22
- package/.agents/scripts/lib/config/limits.js +4 -57
- package/.agents/scripts/lib/config/paths.js +2 -21
- package/.agents/scripts/lib/config/qa.js +4 -38
- package/.agents/scripts/lib/config/quality.js +76 -432
- package/.agents/scripts/lib/config/runners.js +12 -56
- package/.agents/scripts/lib/config/runtime.js +13 -57
- package/.agents/scripts/lib/config/shared.js +2 -16
- package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
- package/.agents/scripts/lib/config/temp-paths.js +40 -280
- package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
- package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
- package/.agents/scripts/lib/config-resolver.js +11 -52
- package/.agents/scripts/lib/config-schema-shared.js +1 -4
- package/.agents/scripts/lib/config-settings-schema-delivery.js +16 -291
- package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
- package/.agents/scripts/lib/config-settings-schema.js +37 -274
- package/.agents/scripts/lib/coverage-baseline.js +20 -110
- package/.agents/scripts/lib/coverage-capture-fullscope.js +18 -35
- package/.agents/scripts/lib/coverage-capture-incremental.js +15 -45
- package/.agents/scripts/lib/coverage-capture-usage.js +8 -25
- package/.agents/scripts/lib/coverage-capture.js +99 -224
- package/.agents/scripts/lib/coverage-utils.js +14 -79
- package/.agents/scripts/lib/cpu-pool.js +17 -123
- package/.agents/scripts/lib/crap-baseline-join.js +16 -88
- package/.agents/scripts/lib/crap-coordinates.js +6 -25
- package/.agents/scripts/lib/crap-engine.js +40 -153
- package/.agents/scripts/lib/crap-method-identity.js +16 -78
- package/.agents/scripts/lib/crap-utils.js +31 -155
- package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
- package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
- package/.agents/scripts/lib/dead-exports-knip.js +18 -56
- package/.agents/scripts/lib/dead-exports-mode.js +5 -24
- package/.agents/scripts/lib/degraded-mode.js +3 -26
- package/.agents/scripts/lib/dependency-parser.js +8 -40
- package/.agents/scripts/lib/dependency-version.js +13 -35
- package/.agents/scripts/lib/detect-package-manager.js +6 -36
- package/.agents/scripts/lib/doc-tiers.js +22 -124
- package/.agents/scripts/lib/duplicate-search.js +8 -72
- package/.agents/scripts/lib/env-loader.js +5 -27
- package/.agents/scripts/lib/error-redactor.js +6 -31
- package/.agents/scripts/lib/errors/index.js +2 -22
- package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
- package/.agents/scripts/lib/escomplex-kernel.js +21 -123
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +94 -419
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -149
- package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
- package/.agents/scripts/lib/findings/classify-finding.js +14 -69
- package/.agents/scripts/lib/findings/promote-finding.js +14 -112
- package/.agents/scripts/lib/findings/provenance-field.js +11 -52
- package/.agents/scripts/lib/findings/route-finding.js +37 -255
- package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
- package/.agents/scripts/lib/findings/severity.js +18 -104
- package/.agents/scripts/lib/format-generated-json.js +12 -44
- package/.agents/scripts/lib/full-suite-lock.js +160 -429
- package/.agents/scripts/lib/full-suite-queue.js +213 -0
- package/.agents/scripts/lib/gates/baseline-store.js +5 -9
- package/.agents/scripts/lib/gates/friction.js +1 -3
- package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
- package/.agents/scripts/lib/gh-exec.js +123 -191
- package/.agents/scripts/lib/git/cached-fetch.js +9 -52
- package/.agents/scripts/lib/git/sync-from-base.js +15 -107
- package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
- package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
- package/.agents/scripts/lib/git-utils.js +37 -161
- package/.agents/scripts/lib/github/framework-repo.js +8 -71
- package/.agents/scripts/lib/github-url.js +2 -17
- package/.agents/scripts/lib/import-graph.js +11 -38
- package/.agents/scripts/lib/install-cmd-parser.js +4 -13
- package/.agents/scripts/lib/json-utils.js +3 -18
- package/.agents/scripts/lib/label-constants.js +16 -111
- package/.agents/scripts/lib/label-taxonomy.js +4 -30
- package/.agents/scripts/lib/maintainability-engine.js +12 -80
- package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
- package/.agents/scripts/lib/maintainability-utils.js +16 -92
- package/.agents/scripts/lib/mandrel-catalog.js +12 -70
- package/.agents/scripts/lib/notifications/notifier.js +13 -38
- package/.agents/scripts/lib/npm-scripts.js +4 -23
- package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
- package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
- package/.agents/scripts/lib/observability/signal-validator.js +5 -37
- package/.agents/scripts/lib/observability/signals-writer.js +11 -121
- package/.agents/scripts/lib/observability/source-classifier.js +22 -203
- package/.agents/scripts/lib/observability/terse-result.js +14 -47
- package/.agents/scripts/lib/onboard/init-tail.js +13 -74
- package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
- package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
- package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +28 -156
- package/.agents/scripts/lib/orchestration/change-set.js +7 -36
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
- package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
- package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
- package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
- package/.agents/scripts/lib/orchestration/check-state.js +92 -0
- package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +121 -157
- package/.agents/scripts/lib/orchestration/code-review.js +24 -128
- package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
- package/.agents/scripts/lib/orchestration/complexity-gate.js +118 -462
- package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
- package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
- package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
- package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
- package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
- package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
- package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
- package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
- package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
- package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
- package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
- package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
- package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
- package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
- package/.agents/scripts/lib/orchestration/light-suitability.js +37 -307
- package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
- package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
- package/.agents/scripts/lib/orchestration/plan-context.js +55 -318
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
- package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
- package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
- package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
- package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
- package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +16 -78
- package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
- package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
- package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
- package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +71 -289
- package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +96 -362
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +9 -39
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +60 -186
- package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
- package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
- package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
- package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
- package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
- package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
- package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
- package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
- package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
- package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
- package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
- package/.agents/scripts/lib/orchestration/review-depth.js +12 -91
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
- package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
- package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
- package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
- package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
- package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
- package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
- package/.agents/scripts/lib/orchestration/run-epilogue.js +245 -326
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +55 -159
- package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
- package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
- package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +83 -239
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +20 -82
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +136 -486
- package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
- package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +96 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +180 -273
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
- package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
- package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
- package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
- package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -200
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +167 -252
- package/.agents/scripts/lib/orchestration/story-init-envelope.js +52 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
- package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
- package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -135
- package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
- package/.agents/scripts/lib/orchestration/ticket-validator.js +63 -344
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -261
- package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
- package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
- package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
- package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
- package/.agents/scripts/lib/path-security.js +3 -6
- package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
- package/.agents/scripts/lib/preflight-runner.js +13 -69
- package/.agents/scripts/lib/process-group.js +143 -0
- package/.agents/scripts/lib/project-root.js +2 -8
- package/.agents/scripts/lib/provider-factory.js +2 -25
- package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
- package/.agents/scripts/lib/qa/qa-session.js +15 -69
- package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
- package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
- package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
- package/.agents/scripts/lib/reserved-test-ids.js +9 -47
- package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
- package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
- package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
- package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
- package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
- package/.agents/scripts/lib/signals/detectors/common.js +12 -38
- package/.agents/scripts/lib/signals/index.js +2 -19
- package/.agents/scripts/lib/signals/schema.js +14 -109
- package/.agents/scripts/lib/signals/write.js +2 -11
- package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
- package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
- package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
- package/.agents/scripts/lib/single-story-sweep.js +14 -97
- package/.agents/scripts/lib/skills/parse-skill.js +13 -59
- package/.agents/scripts/lib/skills/skills-index.js +8 -29
- package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
- package/.agents/scripts/lib/source-extensions.js +11 -42
- package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
- package/.agents/scripts/lib/stdio-flush.js +9 -36
- package/.agents/scripts/lib/story-adjacency.js +8 -40
- package/.agents/scripts/lib/story-body/body-format-lints.js +51 -66
- package/.agents/scripts/lib/story-body/footer-block.js +11 -44
- package/.agents/scripts/lib/story-body/story-body.js +123 -344
- package/.agents/scripts/lib/temp-retention.js +42 -143
- package/.agents/scripts/lib/templates/decomposer-prompts.js +18 -80
- package/.agents/scripts/lib/test-env.js +12 -65
- package/.agents/scripts/lib/test-run-credit.js +10 -65
- package/.agents/scripts/lib/test-runner-contract.js +19 -74
- package/.agents/scripts/lib/test-temp.js +38 -184
- package/.agents/scripts/lib/test-tiers.js +12 -96
- package/.agents/scripts/lib/ticket-body-sections.js +21 -96
- package/.agents/scripts/lib/transpile.js +15 -74
- package/.agents/scripts/lib/util/concurrent-map.js +6 -25
- package/.agents/scripts/lib/util/parse-id-list.js +8 -34
- package/.agents/scripts/lib/util/poll-loop.js +8 -28
- package/.agents/scripts/lib/util/with-timeout.js +2 -11
- package/.agents/scripts/lib/validation-evidence.js +21 -96
- package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
- package/.agents/scripts/lib/wave-runner/live-probe.js +67 -209
- package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
- package/.agents/scripts/lib/workers/crap-worker.js +11 -64
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
- package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
- package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
- package/.agents/scripts/lib/workflow-closure.js +22 -105
- package/.agents/scripts/lib/workspace-provisioner.js +16 -54
- package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
- package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
- package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
- package/.agents/scripts/lib/worktree-manager.js +15 -40
- package/.agents/scripts/lint-issue-body.js +12 -68
- package/.agents/scripts/mandrel-update-preflight.js +10 -70
- package/.agents/scripts/merge-baseline.js +30 -105
- package/.agents/scripts/nav-registry-diff.js +22 -108
- package/.agents/scripts/notify.js +12 -69
- package/.agents/scripts/plan-context.js +97 -92
- package/.agents/scripts/plan-critics.js +12 -66
- package/.agents/scripts/plan-persist.js +71 -137
- package/.agents/scripts/plan-run-epilogue.js +20 -43
- package/.agents/scripts/pr-watch-with-update.js +79 -263
- package/.agents/scripts/providers/github/auth.js +3 -8
- package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
- package/.agents/scripts/providers/github/board-add.js +5 -21
- package/.agents/scripts/providers/github/branch-protection.js +11 -43
- package/.agents/scripts/providers/github/cache.js +2 -14
- package/.agents/scripts/providers/github/comments.js +7 -40
- package/.agents/scripts/providers/github/compose.js +3 -19
- package/.agents/scripts/providers/github/errors.js +22 -125
- package/.agents/scripts/providers/github/issues.js +31 -123
- package/.agents/scripts/providers/github/labels.js +24 -124
- package/.agents/scripts/providers/github/mappers.js +5 -27
- package/.agents/scripts/providers/github/merge-methods.js +3 -22
- package/.agents/scripts/providers/github/project-board.js +2 -17
- package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
- package/.agents/scripts/providers/github/request-helpers.js +5 -32
- package/.agents/scripts/providers/github/search-budget.js +9 -39
- package/.agents/scripts/providers/github/search-query.js +5 -26
- package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
- package/.agents/scripts/providers/github/sub-issues.js +7 -36
- package/.agents/scripts/providers/github/tickets.js +32 -134
- package/.agents/scripts/providers/github.js +18 -59
- package/.agents/scripts/prune-plan-run-labels.js +12 -46
- package/.agents/scripts/quality-preview.js +35 -220
- package/.agents/scripts/resolve-doc-tiers.js +3 -26
- package/.agents/scripts/resolve-stories.js +16 -67
- package/.agents/scripts/resync-status-column.js +6 -25
- package/.agents/scripts/run-tests.js +29 -104
- package/.agents/scripts/single-story-close.js +23 -135
- package/.agents/scripts/single-story-confirm-merge.js +32 -139
- package/.agents/scripts/single-story-init.js +47 -259
- package/.agents/scripts/stories-wave-tick.js +179 -415
- package/.agents/scripts/sync-agentrc.js +3 -21
- package/.agents/scripts/sync-claude-agents.js +9 -55
- package/.agents/scripts/sync-claude-commands.js +20 -110
- package/.agents/scripts/test-wrapper.js +6 -43
- package/.agents/scripts/update-coverage-baseline.js +5 -22
- package/.agents/scripts/update-crap-baseline.js +7 -30
- package/.agents/scripts/update-duplication-baseline.js +16 -92
- package/.agents/scripts/update-maintainability-baseline.js +8 -62
- package/.agents/scripts/update-ticket-state.js +1 -7
- package/.agents/scripts/validate-skills.js +6 -26
- package/.agents/skills/core/gates-and-baselines/reference.md +0 -1
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/skills/stack/qa/playwright/SKILL.md +26 -0
- package/.agents/templates/agent-protocol.md +2 -2
- package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
- package/.agents/workflows/audit-accessibility.md +4 -7
- package/.agents/workflows/audit-adrs.md +3 -6
- package/.agents/workflows/audit-architecture.md +3 -11
- package/.agents/workflows/audit-baselines.md +6 -9
- package/.agents/workflows/audit-clean-code.md +8 -12
- package/.agents/workflows/audit-data-model.md +3 -7
- package/.agents/workflows/audit-dependencies.md +4 -7
- package/.agents/workflows/audit-devops.md +4 -8
- package/.agents/workflows/audit-documentation.md +1 -4
- package/.agents/workflows/audit-mobile.md +4 -7
- package/.agents/workflows/audit-navigability.md +3 -6
- package/.agents/workflows/audit-performance.md +2 -4
- package/.agents/workflows/audit-privacy.md +4 -7
- package/.agents/workflows/audit-quality.md +4 -7
- package/.agents/workflows/audit-security.md +4 -7
- package/.agents/workflows/audit-seo.md +4 -7
- package/.agents/workflows/audit-sre.md +4 -7
- package/.agents/workflows/audit-to-stories.md +17 -30
- package/.agents/workflows/audit-ux-ui.md +4 -7
- package/.agents/workflows/helpers/acceptance-self-eval.md +84 -157
- package/.agents/workflows/helpers/audit-lens-core.md +1 -1
- package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
- package/.agents/workflows/helpers/code-review.md +4 -2
- package/.agents/workflows/helpers/deliver-digest.md +37 -28
- package/.agents/workflows/helpers/deliver-light.md +92 -101
- package/.agents/workflows/helpers/deliver-reference.md +162 -220
- package/.agents/workflows/helpers/deliver-story-reference.md +197 -607
- package/.agents/workflows/helpers/deliver-story.md +17 -18
- package/.agents/workflows/helpers/plan-reference.md +125 -167
- package/.agents/workflows/helpers/qa-core.md +12 -0
- package/.agents/workflows/mandrel-deliver.md +47 -31
- package/.agents/workflows/mandrel-plan.md +22 -21
- package/.agents/workflows/mandrel-update.md +36 -21
- package/.agents/workflows/memory-consolidate.md +1 -1
- package/.agents/workflows/qa-assist.md +27 -71
- package/.agents/workflows/qa-explore.md +19 -59
- package/.agents/workflows/qa-run.md +11 -33
- package/README.md +1 -1
- package/bin/mandrel.js +5 -46
- package/bin/postinstall.js +18 -107
- package/docs/CHANGELOG.md +60 -0
- package/lib/cli/doctor.js +11 -71
- package/lib/cli/init.js +26 -165
- package/lib/cli/migrate.js +5 -64
- package/lib/cli/registry.js +84 -467
- package/lib/cli/sync-agents.js +4 -64
- package/lib/cli/sync-commands.js +11 -64
- package/lib/cli/sync.js +34 -213
- package/lib/cli/uninstall.js +40 -219
- package/lib/cli/update.js +326 -523
- package/lib/cli/version-check.js +8 -72
- package/lib/cli/version-helpers.js +14 -87
- package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
- package/lib/migrations/index.js +17 -92
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
- package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
- package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
- package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
- package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +21 -0
- package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
- package/package.json +17 -14
- package/.agents/docs/SDLC.md +0 -590
- package/.agents/docs/quality-gates.md +0 -1179
- package/.agents/rules/known-tooling-behavior.md +0 -150
- package/.agents/rules/orchestration-error-handling.md +0 -61
- package/.agents/rules/test-seams.md +0 -59
- package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
- package/.agents/schemas/baselines/lint.schema.json +0 -47
- package/.agents/schemas/model-attribution.schema.json +0 -53
- package/.agents/scripts/check-action-pinning.js +0 -260
- package/.agents/scripts/check-audit-attribution.js +0 -302
- package/.agents/scripts/check-baseline-drift.js +0 -211
- package/.agents/scripts/check-baseline-scope.js +0 -362
- package/.agents/scripts/check-generated-validator.js +0 -202
- package/.agents/scripts/check-knip-entries.js +0 -159
- package/.agents/scripts/check-lifecycle-lint.js +0 -294
- package/.agents/scripts/check-pinned-override-notes.js +0 -102
- package/.agents/scripts/check-schema-references.js +0 -366
- package/.agents/scripts/check-test-portability.js +0 -512
- package/.agents/scripts/check-workflow-citations.js +0 -332
- package/.agents/scripts/check-workflow-cli-lint.js +0 -299
- package/.agents/scripts/check-workflow-timeouts.js +0 -291
- package/.agents/scripts/install-matrix-assert.js +0 -326
- package/.agents/scripts/lib/audit-advisories.js +0 -195
- package/.agents/scripts/lib/audit-attribution.js +0 -134
- package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
- package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
- package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
- package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
- package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
- package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
- package/.agents/scripts/lib/c8-cli-path.js +0 -21
- package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
- package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
- package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
- package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
- package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
- package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
- package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
- package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
- package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
- package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
- package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
- package/.agents/scripts/lib/fs-walk.js +0 -52
- package/.agents/scripts/lib/knip-config-resolver.js +0 -181
- package/.agents/scripts/lib/knip-entry-sync.js +0 -452
- package/.agents/scripts/lib/orchestration/model-attribution.js +0 -418
- package/.agents/scripts/lib/orchestration/story-plan-state.js +0 -33
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +0 -67
- package/.agents/scripts/lib/pinned-override-notes.js +0 -88
- package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
- package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
- package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
- package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
- package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
- package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
- package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
- package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
- package/.agents/scripts/lib/test-isolate/runner.js +0 -483
- package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
- package/.agents/scripts/lib/test-profile/render-report.js +0 -45
- package/.agents/scripts/lint-label-vocabulary.js +0 -214
- package/.agents/scripts/post-structured-comment.js +0 -127
- package/.agents/scripts/provision-git-hooks.js +0 -85
- package/.agents/scripts/prune-baseline-orphans.js +0 -181
- package/.agents/scripts/run-coverage.js +0 -197
- package/.agents/scripts/run-lint.js +0 -133
- package/.agents/scripts/run-test-profile.js +0 -129
- package/.agents/scripts/run-verify.js +0 -118
- package/.agents/scripts/test-isolate.js +0 -55
- package/.agents/scripts/update-dead-exports-baseline.js +0 -321
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI: GitHub Actions job-timeout gate.
|
|
3
|
-
*
|
|
4
|
-
* Story #4936. Every job in this repository inherited GitHub's 360-minute
|
|
5
|
-
* default because not one of the four workflow files set `timeout-minutes`.
|
|
6
|
-
* That is not a theoretical cost: a deadlocked `Windows Smoke` job burned 44
|
|
7
|
-
* minutes of a `windows-latest` runner, and — because the run stayed
|
|
8
|
-
* `in_progress` — GitHub withheld the logs of the *required* check that had
|
|
9
|
-
* already failed on the same run, so the real merge blocker could not be
|
|
10
|
-
* diagnosed until the run was cancelled by hand. An unbounded job costs
|
|
11
|
-
* runner time and diagnosability at once.
|
|
12
|
-
*
|
|
13
|
-
* A ceiling only helps if it is bounded on both ends, so this gate fails on
|
|
14
|
-
* two shapes:
|
|
15
|
-
*
|
|
16
|
-
* - a job with no `timeout-minutes` at all (unbounded, 360-minute default);
|
|
17
|
-
* - a job whose `timeout-minutes` exceeds `MAX_TIMEOUT_MINUTES`, i.e. a
|
|
18
|
-
* number generous enough to be useless as a deadlock detector.
|
|
19
|
-
*
|
|
20
|
-
* `MIN_TIMEOUT_MINUTES` is the floor a value must clear to be plausible
|
|
21
|
-
* headroom over a job that takes a couple of minutes today; below it, a
|
|
22
|
-
* transient slow runner reds the build for no defect.
|
|
23
|
-
*
|
|
24
|
-
* Contract:
|
|
25
|
-
* - Scans the workflows directory (default `.github/workflows`, override
|
|
26
|
-
* with `--dir <path>`), parsing each `*.yml` / `*.yaml` with js-yaml and
|
|
27
|
-
* enumerating every `jobs.<id>` key.
|
|
28
|
-
* - Prints `<file> job <id> — <reason>` per violation, then a one-line
|
|
29
|
-
* summary even on a clean scan so the "ok" signal is visible in CI.
|
|
30
|
-
* - With `--json`: writes a structured envelope to stdout and skips the
|
|
31
|
-
* human summary.
|
|
32
|
-
* - Exit codes: 0 = every job bounded in range; 1 = at least one violation.
|
|
33
|
-
* A missing / empty workflows directory exits 0 (nothing to gate).
|
|
34
|
-
*/
|
|
35
|
-
|
|
36
|
-
import fs from 'node:fs';
|
|
37
|
-
import path from 'node:path';
|
|
38
|
-
import process from 'node:process';
|
|
39
|
-
import yaml from 'js-yaml';
|
|
40
|
-
import { runAsCli } from './lib/cli-utils.js';
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Inclusive bounds every job's `timeout-minutes` must sit within.
|
|
44
|
-
*
|
|
45
|
-
* The ceiling is the load-bearing half — it is what turns a deadlock into a
|
|
46
|
-
* bounded loss instead of a six-hour one. The floor keeps a well-meaning
|
|
47
|
-
* `timeout-minutes: 2` from reddening the build on a slow runner.
|
|
48
|
-
*/
|
|
49
|
-
export const MIN_TIMEOUT_MINUTES = 10;
|
|
50
|
-
export const MAX_TIMEOUT_MINUTES = 30;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Enumerate workflow files (`*.yml` / `*.yaml`) directly under `dir`.
|
|
54
|
-
* Returns absolute paths sorted for deterministic output. A missing directory
|
|
55
|
-
* yields an empty list.
|
|
56
|
-
*
|
|
57
|
-
* @param {string} dir Absolute workflows directory.
|
|
58
|
-
* @param {typeof fs} [fsLike]
|
|
59
|
-
* @returns {string[]}
|
|
60
|
-
*/
|
|
61
|
-
export function listWorkflowFiles(dir, fsLike = fs) {
|
|
62
|
-
let entries;
|
|
63
|
-
try {
|
|
64
|
-
entries = fsLike.readdirSync(dir, { withFileTypes: true });
|
|
65
|
-
} catch {
|
|
66
|
-
return [];
|
|
67
|
-
}
|
|
68
|
-
return entries
|
|
69
|
-
.filter((e) => e.isFile() && /\.ya?ml$/i.test(e.name))
|
|
70
|
-
.map((e) => path.join(dir, e.name))
|
|
71
|
-
.sort();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Read the `jobs` mapping out of one workflow document.
|
|
76
|
-
*
|
|
77
|
-
* The single parse point for both the violation scan and the job count, so
|
|
78
|
-
* the two can never disagree about what a workflow's job set is.
|
|
79
|
-
*
|
|
80
|
-
* @param {string} text The file contents.
|
|
81
|
-
* @param {(s: string) => unknown} parse YAML parser; injected in tests.
|
|
82
|
-
* @returns {{ jobs: Record<string, unknown> | null, error: Error | null }}
|
|
83
|
-
*/
|
|
84
|
-
function readJobs(text, parse) {
|
|
85
|
-
let doc;
|
|
86
|
-
try {
|
|
87
|
-
doc = parse(text);
|
|
88
|
-
} catch (err) {
|
|
89
|
-
return { jobs: null, error: err };
|
|
90
|
-
}
|
|
91
|
-
const jobs = doc && typeof doc === 'object' ? doc.jobs : null;
|
|
92
|
-
return {
|
|
93
|
-
jobs: jobs && typeof jobs === 'object' ? jobs : null,
|
|
94
|
-
error: null,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Judge one job body's `timeout-minutes`, returning the violation shape or
|
|
100
|
-
* `null` when the job is bounded in range.
|
|
101
|
-
*
|
|
102
|
-
* Reusable-workflow calls (`jobs.<id>.uses:`) are exempt: `timeout-minutes`
|
|
103
|
-
* is not a valid key on a job that delegates to another workflow — the
|
|
104
|
-
* callee's own jobs carry their timeouts, and setting one here is a schema
|
|
105
|
-
* error rather than a fix.
|
|
106
|
-
*
|
|
107
|
-
* @param {unknown} body The `jobs.<id>` value.
|
|
108
|
-
* @returns {{ timeout: number | null, reason: string } | null}
|
|
109
|
-
*/
|
|
110
|
-
function judgeJobTimeout(body) {
|
|
111
|
-
if (!body || typeof body !== 'object') return null;
|
|
112
|
-
if (typeof body.uses === 'string') return null;
|
|
113
|
-
|
|
114
|
-
const timeout = body['timeout-minutes'];
|
|
115
|
-
if (timeout === undefined || timeout === null) {
|
|
116
|
-
return {
|
|
117
|
-
timeout: null,
|
|
118
|
-
reason: `no timeout-minutes — the job inherits GitHub's 360-minute default`,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
if (typeof timeout !== 'number' || !Number.isFinite(timeout)) {
|
|
122
|
-
return {
|
|
123
|
-
timeout: null,
|
|
124
|
-
reason: `timeout-minutes is not a number (${JSON.stringify(timeout)})`,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
if (timeout > MAX_TIMEOUT_MINUTES) {
|
|
128
|
-
return {
|
|
129
|
-
timeout,
|
|
130
|
-
reason: `timeout-minutes ${timeout} exceeds the ${MAX_TIMEOUT_MINUTES}-minute ceiling`,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
if (timeout < MIN_TIMEOUT_MINUTES) {
|
|
134
|
-
return {
|
|
135
|
-
timeout,
|
|
136
|
-
reason: `timeout-minutes ${timeout} is below the ${MIN_TIMEOUT_MINUTES}-minute floor`,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Pure helper: enumerate every `jobs.<id>` key in one workflow document and
|
|
144
|
-
* return the violations.
|
|
145
|
-
*
|
|
146
|
-
* An unparseable document is itself a violation: a workflow whose jobs cannot
|
|
147
|
-
* be enumerated cannot be certified as bounded, and failing open would let
|
|
148
|
-
* the very drift this gate exists to catch through.
|
|
149
|
-
*
|
|
150
|
-
* @param {string} file Relative file label used in violation rows.
|
|
151
|
-
* @param {string} text The file contents.
|
|
152
|
-
* @param {(s: string) => unknown} [parse] YAML parser; injected in tests.
|
|
153
|
-
* @returns {Array<{ file: string, job: string, timeout: number | null, reason: string }>}
|
|
154
|
-
*/
|
|
155
|
-
export function scanWorkflowText(file, text, parse = yaml.load) {
|
|
156
|
-
const { jobs, error } = readJobs(text, parse);
|
|
157
|
-
if (error) {
|
|
158
|
-
return [
|
|
159
|
-
{
|
|
160
|
-
file,
|
|
161
|
-
job: '(document)',
|
|
162
|
-
timeout: null,
|
|
163
|
-
reason: `workflow could not be parsed as YAML: ${error.message}`,
|
|
164
|
-
},
|
|
165
|
-
];
|
|
166
|
-
}
|
|
167
|
-
if (!jobs) return [];
|
|
168
|
-
|
|
169
|
-
const violations = [];
|
|
170
|
-
for (const [job, body] of Object.entries(jobs)) {
|
|
171
|
-
const verdict = judgeJobTimeout(body);
|
|
172
|
-
if (verdict) violations.push({ file, job, ...verdict });
|
|
173
|
-
}
|
|
174
|
-
return violations;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Pure helper: render the human-readable report. One line per violation
|
|
179
|
-
* followed by a one-line summary carrying a `(gate fail)` / `(ok)` marker.
|
|
180
|
-
*
|
|
181
|
-
* @param {Array<{ file: string, job: string, timeout: number | null, reason: string }>} violations
|
|
182
|
-
* @param {number} jobsScanned
|
|
183
|
-
* @returns {string}
|
|
184
|
-
*/
|
|
185
|
-
export function renderReport(violations, jobsScanned) {
|
|
186
|
-
const lines = violations.map((v) => `${v.file} job ${v.job} — ${v.reason}`);
|
|
187
|
-
const tag = violations.length > 0 ? '(gate fail)' : '(ok)';
|
|
188
|
-
lines.push(
|
|
189
|
-
`[workflow-timeouts] jobs=${jobsScanned} violations=${violations.length} ${tag}`,
|
|
190
|
-
);
|
|
191
|
-
return lines.join('\n');
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Count every `jobs.<id>` key in a parsed workflow document, including the
|
|
196
|
-
* reusable-workflow calls the violation scan exempts — the summary reports
|
|
197
|
-
* how many jobs were enumerated, not how many were eligible.
|
|
198
|
-
*
|
|
199
|
-
* @param {string} text
|
|
200
|
-
* @param {(s: string) => unknown} [parse]
|
|
201
|
-
* @returns {number}
|
|
202
|
-
*/
|
|
203
|
-
export function countJobs(text, parse = yaml.load) {
|
|
204
|
-
const { jobs } = readJobs(text, parse);
|
|
205
|
-
return jobs ? Object.keys(jobs).length : 0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Top-level CLI entry. Exported so tests can drive the full pipeline against
|
|
210
|
-
* a fixture workflows directory without touching the repo's real workflows.
|
|
211
|
-
*
|
|
212
|
-
* @param {{
|
|
213
|
-
* argv?: string[],
|
|
214
|
-
* cwd?: string,
|
|
215
|
-
* stdout?: { write: (s: string) => void },
|
|
216
|
-
* stderr?: { write: (s: string) => void },
|
|
217
|
-
* }} [opts]
|
|
218
|
-
* @returns {Promise<number>} exit code: 0 = every job bounded; 1 = violation
|
|
219
|
-
*/
|
|
220
|
-
export async function runCli({
|
|
221
|
-
argv = process.argv.slice(2),
|
|
222
|
-
cwd = process.cwd(),
|
|
223
|
-
stdout = process.stdout,
|
|
224
|
-
stderr = process.stderr,
|
|
225
|
-
} = {}) {
|
|
226
|
-
const dirIdx = argv.indexOf('--dir');
|
|
227
|
-
const dir =
|
|
228
|
-
dirIdx !== -1 && argv[dirIdx + 1] && !argv[dirIdx + 1].startsWith('--')
|
|
229
|
-
? argv[dirIdx + 1]
|
|
230
|
-
: null;
|
|
231
|
-
const json = argv.includes('--json');
|
|
232
|
-
const resolvedDir = path.resolve(
|
|
233
|
-
cwd,
|
|
234
|
-
dir ?? path.join('.github', 'workflows'),
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
const files = listWorkflowFiles(resolvedDir);
|
|
238
|
-
const violations = [];
|
|
239
|
-
let jobsScanned = 0;
|
|
240
|
-
for (const file of files) {
|
|
241
|
-
let text;
|
|
242
|
-
try {
|
|
243
|
-
text = fs.readFileSync(file, 'utf-8');
|
|
244
|
-
} catch {
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
const label = path.relative(cwd, file);
|
|
248
|
-
jobsScanned += countJobs(text);
|
|
249
|
-
violations.push(...scanWorkflowText(label, text));
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const exitCode = violations.length > 0 ? 1 : 0;
|
|
253
|
-
|
|
254
|
-
if (json) {
|
|
255
|
-
stdout.write(
|
|
256
|
-
`${JSON.stringify(
|
|
257
|
-
{
|
|
258
|
-
kind: 'workflow-timeouts-report',
|
|
259
|
-
dir: resolvedDir,
|
|
260
|
-
filesScanned: files.length,
|
|
261
|
-
jobsScanned,
|
|
262
|
-
minTimeoutMinutes: MIN_TIMEOUT_MINUTES,
|
|
263
|
-
maxTimeoutMinutes: MAX_TIMEOUT_MINUTES,
|
|
264
|
-
violations,
|
|
265
|
-
exitCode,
|
|
266
|
-
},
|
|
267
|
-
null,
|
|
268
|
-
2,
|
|
269
|
-
)}\n`,
|
|
270
|
-
);
|
|
271
|
-
} else {
|
|
272
|
-
if (files.length === 0) {
|
|
273
|
-
stderr.write(
|
|
274
|
-
`[workflow-timeouts] ⚠ no workflow files found under ${resolvedDir}\n`,
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
stdout.write(`${renderReport(violations, jobsScanned)}\n`);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return exitCode;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
async function main() {
|
|
284
|
-
return runCli();
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
runAsCli(import.meta.url, main, {
|
|
288
|
-
source: 'workflow-timeouts',
|
|
289
|
-
propagateExitCode: true,
|
|
290
|
-
errorPrefix: '[workflow-timeouts] ❌ Fatal error',
|
|
291
|
-
});
|
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// .agents/scripts/install-matrix-assert.js
|
|
3
|
-
/**
|
|
4
|
-
* Golden-path install assertions for the install matrix (Story #3472).
|
|
5
|
-
*
|
|
6
|
-
* The `.github/workflows/install-matrix.yml` workflow exercises the published
|
|
7
|
-
* package contract — install `mandrel`, run `mandrel sync`, run
|
|
8
|
-
* `mandrel doctor` — across {npm, pnpm, yarn} x {ubuntu-latest,
|
|
9
|
-
* windows-latest}. Rather than spread the per-leg invariants across
|
|
10
|
-
* PowerShell-vs-bash shell snippets (which diverge on quoting, `$?`, and
|
|
11
|
-
* path separators), every leg shells out to this single Node script so the
|
|
12
|
-
* checks run identically on every OS.
|
|
13
|
-
*
|
|
14
|
-
* It asserts three invariants against a consumer project directory:
|
|
15
|
-
*
|
|
16
|
-
* 1. `materialized` — `<consumer>/.agents/instructions.md` exists, i.e. the
|
|
17
|
-
* `.agents/` payload was materialized into the consumer working copy by
|
|
18
|
-
* `mandrel sync` (or the best-effort postinstall hook).
|
|
19
|
-
*
|
|
20
|
-
* 2. `manifest-clean` — the consumer's `package.json` was NOT mutated with
|
|
21
|
-
* the framework's internal runtime dependencies. Installing
|
|
22
|
-
* `mandrel` is expected to add exactly that one package to the
|
|
23
|
-
* consumer manifest (npm/pnpm/yarn all record the installed dep); what
|
|
24
|
-
* MUST NOT happen is the framework's own runtime deps (ajv, js-yaml,
|
|
25
|
-
* minimatch, …) leaking into the consumer's declared dependencies. Those
|
|
26
|
-
* packages are declared inside `.agents/runtime-deps.json` and the
|
|
27
|
-
* framework scripts free-ride on the consumer's node_modules — they are
|
|
28
|
-
* never written into the consumer's package.json.
|
|
29
|
-
*
|
|
30
|
-
* 3. `doctor-ready` — `mandrel doctor` exited 0 and printed the
|
|
31
|
-
* "✅ Ready" verdict line. This is asserted by the workflow step that
|
|
32
|
-
* runs doctor and pipes its output here via `--doctor-output <file>`.
|
|
33
|
-
*
|
|
34
|
-
* Each invariant can be run independently (`--check <name>`) or all at once
|
|
35
|
-
* (default). The script exits 0 when every requested check passes and 1 (with
|
|
36
|
-
* an actionable message on stderr) when any fails — so a CI step that invokes
|
|
37
|
-
* it fails the leg loudly rather than silently.
|
|
38
|
-
*
|
|
39
|
-
* Usage:
|
|
40
|
-
* node .agents/scripts/install-matrix-assert.js \
|
|
41
|
-
* --consumer <dir> [--check materialized|manifest-clean|doctor-ready] \
|
|
42
|
-
* [--doctor-output <file>] [--package-name <name>]
|
|
43
|
-
*
|
|
44
|
-
* Security: pure local filesystem reads. No network, no shell, no secrets
|
|
45
|
-
* logged. The doctor-output file is read as plain text and only scanned for
|
|
46
|
-
* the verdict marker.
|
|
47
|
-
*
|
|
48
|
-
* Injectable seams (used by tests):
|
|
49
|
-
* - `fs` — replaces the node:fs surface
|
|
50
|
-
* - `write` — replaces process.stdout.write
|
|
51
|
-
* - `writeErr` — replaces process.stderr.write
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
import nodeFs from 'node:fs';
|
|
55
|
-
import path from 'node:path';
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* The framework's internal runtime dependencies. These are declared in
|
|
59
|
-
* `.agents/runtime-deps.json` and provided by the consumer's install of
|
|
60
|
-
* `mandrel` (npm hoists them into node_modules), but they MUST NOT
|
|
61
|
-
* appear in the consumer's *declared* package.json dependencies. Kept in sync
|
|
62
|
-
* with `.agents/runtime-deps.json` `dependencies` keys — the whole set, so
|
|
63
|
-
* this list documents the closure; {@link SHAREABLE_RUNTIME_DEPS} carries the
|
|
64
|
-
* policy about which of them a consumer may also declare.
|
|
65
|
-
*/
|
|
66
|
-
const FRAMEWORK_RUNTIME_DEPS = [
|
|
67
|
-
'@babel/parser',
|
|
68
|
-
'ajv',
|
|
69
|
-
'ajv-formats',
|
|
70
|
-
'babel-runtime',
|
|
71
|
-
'escomplex-plugin-metrics-module',
|
|
72
|
-
'escomplex-plugin-syntax-babylon',
|
|
73
|
-
'js-yaml',
|
|
74
|
-
'minimatch',
|
|
75
|
-
'picomatch',
|
|
76
|
-
'typhonjs-ast-walker',
|
|
77
|
-
'typhonjs-escomplex-commons',
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Runtime dependencies the framework declares but does **not** claim
|
|
82
|
-
* exclusively, so a consumer declaring one is not evidence of a mutated
|
|
83
|
-
* manifest.
|
|
84
|
-
*
|
|
85
|
-
* This check exists to catch a consumer's `package.json` being written into
|
|
86
|
-
* with framework-internal packages. That inference only holds for packages
|
|
87
|
-
* nobody else would plausibly declare. `@babel/parser` and `babel-runtime`
|
|
88
|
-
* fail that test completely: a repository with its own Babel pipeline, AST
|
|
89
|
-
* tooling or legacy transpile output declares them for its own reasons, and
|
|
90
|
-
* failing `manifest-clean` for that would be a false positive on an ordinary
|
|
91
|
-
* consumer rather than a caught mutation.
|
|
92
|
-
*
|
|
93
|
-
* Kept as an explicit list rather than a heuristic: adding a widely-used
|
|
94
|
-
* package to the framework's runtime closure should be a deliberate decision
|
|
95
|
-
* to stop policing it, recorded here.
|
|
96
|
-
*/
|
|
97
|
-
const SHAREABLE_RUNTIME_DEPS = ['@babel/parser', 'babel-runtime'];
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Is this framework dependency's presence in a consumer manifest evidence of a
|
|
101
|
-
* mutated manifest?
|
|
102
|
-
*
|
|
103
|
-
* Only for packages the framework claims exclusively. A shareable one is
|
|
104
|
-
* declared by ordinary repositories for their own reasons.
|
|
105
|
-
*
|
|
106
|
-
* @param {string} dep
|
|
107
|
-
* @param {Record<string, string>} declared Consumer's merged declared deps.
|
|
108
|
-
* @returns {boolean}
|
|
109
|
-
*/
|
|
110
|
-
function isLeak(dep, declared) {
|
|
111
|
-
if (!(dep in declared)) return false;
|
|
112
|
-
return !SHAREABLE_RUNTIME_DEPS.includes(dep);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/** Exported for the manifest-mirror drift assertion. */
|
|
116
|
-
export { FRAMEWORK_RUNTIME_DEPS, SHAREABLE_RUNTIME_DEPS };
|
|
117
|
-
|
|
118
|
-
/** The verdict marker `mandrel doctor` prints when every check passes. */
|
|
119
|
-
const DOCTOR_READY_MARKER = '✅ Ready';
|
|
120
|
-
|
|
121
|
-
const ALL_CHECKS = ['materialized', 'manifest-clean', 'doctor-ready'];
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Parse `--flag value` / `--flag=value` argv into an options object. Repeated
|
|
125
|
-
* `--check` flags accumulate into an array.
|
|
126
|
-
*
|
|
127
|
-
* @param {string[]} argv
|
|
128
|
-
* @returns {{ consumer?: string, checks: string[], doctorOutput?: string, packageName: string }}
|
|
129
|
-
*/
|
|
130
|
-
export function parseArgs(argv) {
|
|
131
|
-
const opts = { checks: [], packageName: 'mandrel' };
|
|
132
|
-
for (let i = 0; i < argv.length; i++) {
|
|
133
|
-
const token = argv[i];
|
|
134
|
-
const eq = token.indexOf('=');
|
|
135
|
-
const flag = eq === -1 ? token : token.slice(0, eq);
|
|
136
|
-
const inlineValue = eq === -1 ? undefined : token.slice(eq + 1);
|
|
137
|
-
const next = () => inlineValue ?? argv[++i];
|
|
138
|
-
switch (flag) {
|
|
139
|
-
case '--consumer':
|
|
140
|
-
opts.consumer = next();
|
|
141
|
-
break;
|
|
142
|
-
case '--check':
|
|
143
|
-
opts.checks.push(next());
|
|
144
|
-
break;
|
|
145
|
-
case '--doctor-output':
|
|
146
|
-
opts.doctorOutput = next();
|
|
147
|
-
break;
|
|
148
|
-
case '--package-name':
|
|
149
|
-
opts.packageName = next();
|
|
150
|
-
break;
|
|
151
|
-
default:
|
|
152
|
-
// Ignore unknown flags so the script is forward-compatible with
|
|
153
|
-
// additional workflow plumbing.
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (opts.checks.length === 0) opts.checks = [...ALL_CHECKS];
|
|
158
|
-
return opts;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Assert the `.agents/` payload was materialized into the consumer project.
|
|
163
|
-
*
|
|
164
|
-
* @param {{ consumer: string, fs?: typeof nodeFs }} opts
|
|
165
|
-
* @returns {{ ok: boolean, detail: string }}
|
|
166
|
-
*/
|
|
167
|
-
export function checkMaterialized({ consumer, fs = nodeFs }) {
|
|
168
|
-
const target = path.join(consumer, '.agents', 'instructions.md');
|
|
169
|
-
if (fs.existsSync(target)) {
|
|
170
|
-
return { ok: true, detail: `.agents/ materialized (${target})` };
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
ok: false,
|
|
174
|
-
detail: `./.agents/instructions.md not found at ${target} — \`mandrel sync\` did not materialize the payload.`,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Assert the consumer's package.json was not mutated with framework runtime
|
|
180
|
-
* deps. Installing `mandrel` itself is expected; the framework's
|
|
181
|
-
* internal runtime packages are not.
|
|
182
|
-
*
|
|
183
|
-
* @param {{ consumer: string, packageName: string, fs?: typeof nodeFs }} opts
|
|
184
|
-
* @returns {{ ok: boolean, detail: string }}
|
|
185
|
-
*/
|
|
186
|
-
export function checkManifestClean({ consumer, packageName, fs = nodeFs }) {
|
|
187
|
-
const manifestPath = path.join(consumer, 'package.json');
|
|
188
|
-
let manifest;
|
|
189
|
-
try {
|
|
190
|
-
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
191
|
-
} catch (err) {
|
|
192
|
-
return {
|
|
193
|
-
ok: false,
|
|
194
|
-
detail: `could not read consumer package.json at ${manifestPath}: ${err.message}`,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const declared = {
|
|
199
|
-
...(manifest.dependencies ?? {}),
|
|
200
|
-
...(manifest.devDependencies ?? {}),
|
|
201
|
-
...(manifest.optionalDependencies ?? {}),
|
|
202
|
-
...(manifest.peerDependencies ?? {}),
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
const leaked = FRAMEWORK_RUNTIME_DEPS.filter((dep) => isLeak(dep, declared));
|
|
206
|
-
if (leaked.length > 0) {
|
|
207
|
-
return {
|
|
208
|
-
ok: false,
|
|
209
|
-
detail: `consumer package.json was mutated with framework runtime deps: ${leaked.join(', ')}`,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// The framework package itself MAY be present (that is the intended install)
|
|
214
|
-
// but its absence is also fine — the workflow installs it separately and the
|
|
215
|
-
// assertion only guards against *unexpected* framework-internal deps.
|
|
216
|
-
const hasFrameworkPkg = packageName in declared;
|
|
217
|
-
return {
|
|
218
|
-
ok: true,
|
|
219
|
-
detail: hasFrameworkPkg
|
|
220
|
-
? `manifest clean: only '${packageName}' added, no framework runtime deps leaked`
|
|
221
|
-
: 'manifest clean: no framework runtime deps leaked',
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Assert `mandrel doctor` printed the ready verdict. The workflow captures
|
|
227
|
-
* doctor's stdout to a file and passes it via `--doctor-output`.
|
|
228
|
-
*
|
|
229
|
-
* @param {{ doctorOutput?: string, fs?: typeof nodeFs }} opts
|
|
230
|
-
* @returns {{ ok: boolean, detail: string }}
|
|
231
|
-
*/
|
|
232
|
-
export function checkDoctorReady({ doctorOutput, fs = nodeFs }) {
|
|
233
|
-
if (!doctorOutput) {
|
|
234
|
-
return {
|
|
235
|
-
ok: false,
|
|
236
|
-
detail:
|
|
237
|
-
'--doctor-output <file> is required for the doctor-ready check (capture `mandrel doctor` stdout to it first).',
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
let text;
|
|
241
|
-
try {
|
|
242
|
-
text = fs.readFileSync(doctorOutput, 'utf8');
|
|
243
|
-
} catch (err) {
|
|
244
|
-
return {
|
|
245
|
-
ok: false,
|
|
246
|
-
detail: `could not read doctor output at ${doctorOutput}: ${err.message}`,
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
if (text.includes(DOCTOR_READY_MARKER)) {
|
|
250
|
-
return { ok: true, detail: 'mandrel doctor reported a ready verdict' };
|
|
251
|
-
}
|
|
252
|
-
return {
|
|
253
|
-
ok: false,
|
|
254
|
-
detail:
|
|
255
|
-
'mandrel doctor did not report a ready verdict (no "✅ Ready" line in captured output).',
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Run the requested checks and report a per-check result. Exits non-zero when
|
|
261
|
-
* any requested check fails.
|
|
262
|
-
*
|
|
263
|
-
* @param {{
|
|
264
|
-
* argv?: string[],
|
|
265
|
-
* fs?: typeof nodeFs,
|
|
266
|
-
* write?: (s: string) => void,
|
|
267
|
-
* writeErr?: (s: string) => void,
|
|
268
|
-
* }} [opts]
|
|
269
|
-
* @returns {{ ok: boolean, results: Array<{ name: string, ok: boolean, detail: string }> }}
|
|
270
|
-
*/
|
|
271
|
-
export function runAssertions({
|
|
272
|
-
argv = process.argv.slice(2),
|
|
273
|
-
fs = nodeFs,
|
|
274
|
-
write = (s) => process.stdout.write(s),
|
|
275
|
-
writeErr = (s) => process.stderr.write(s),
|
|
276
|
-
} = {}) {
|
|
277
|
-
const opts = parseArgs(argv);
|
|
278
|
-
|
|
279
|
-
if (!opts.consumer) {
|
|
280
|
-
writeErr('install-matrix-assert: --consumer <dir> is required.\n');
|
|
281
|
-
return { ok: false, results: [] };
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const results = [];
|
|
285
|
-
for (const name of opts.checks) {
|
|
286
|
-
let result;
|
|
287
|
-
switch (name) {
|
|
288
|
-
case 'materialized':
|
|
289
|
-
result = checkMaterialized({ consumer: opts.consumer, fs });
|
|
290
|
-
break;
|
|
291
|
-
case 'manifest-clean':
|
|
292
|
-
result = checkManifestClean({
|
|
293
|
-
consumer: opts.consumer,
|
|
294
|
-
packageName: opts.packageName,
|
|
295
|
-
fs,
|
|
296
|
-
});
|
|
297
|
-
break;
|
|
298
|
-
case 'doctor-ready':
|
|
299
|
-
result = checkDoctorReady({ doctorOutput: opts.doctorOutput, fs });
|
|
300
|
-
break;
|
|
301
|
-
default:
|
|
302
|
-
result = { ok: false, detail: `unknown check '${name}'` };
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
results.push({ name, ...result });
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
for (const r of results) {
|
|
309
|
-
const icon = r.ok ? 'PASS' : 'FAIL';
|
|
310
|
-
const sink = r.ok ? write : writeErr;
|
|
311
|
-
sink(`[${icon}] ${r.name}: ${r.detail}\n`);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const ok = results.every((r) => r.ok);
|
|
315
|
-
return { ok, results };
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
// cli-opt-out: synchronous CLI whose bespoke main-guard forwards an explicit
|
|
319
|
-
// 0/1 exit code from runAssertions(); runAsCli's async-main signature does not
|
|
320
|
-
// preserve that result code (same rationale as coverage-capture.js).
|
|
321
|
-
// Run when invoked directly (not when imported by tests).
|
|
322
|
-
const invokedDirectly = process.argv[1]?.endsWith('install-matrix-assert.js');
|
|
323
|
-
if (invokedDirectly) {
|
|
324
|
-
const { ok } = runAssertions();
|
|
325
|
-
process.exit(ok ? 0 : 1);
|
|
326
|
-
}
|