session-orchestrator 3.23.0 → 4.0.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/skills/architecture/SKILL.md +18 -0
- package/.agents/skills/autopilot/SKILL.md +17 -0
- package/.agents/skills/bootstrap/SKILL.md +20 -0
- package/.agents/skills/brainstorm/SKILL.md +22 -0
- package/.agents/skills/claude-md-drift-check/SKILL.md +15 -0
- package/.agents/skills/convergence-monitoring/SKILL.md +22 -0
- package/.agents/skills/debug/SKILL.md +22 -0
- package/.agents/skills/discovery/SKILL.md +20 -0
- package/.agents/skills/dispatcher/SKILL.md +15 -0
- package/.agents/skills/docs-orchestrator/SKILL.md +18 -0
- package/.agents/skills/ecosystem-health/SKILL.md +20 -0
- package/.agents/skills/eli5/SKILL.md +20 -0
- package/.agents/skills/eval/SKILL.md +21 -0
- package/.agents/skills/evolve/SKILL.md +21 -0
- package/.agents/skills/frontmatter-guard/SKILL.md +15 -0
- package/.agents/skills/gitlab-ops/SKILL.md +20 -0
- package/.agents/skills/gitlab-portfolio/SKILL.md +15 -0
- package/.agents/skills/grill/SKILL.md +22 -0
- package/.agents/skills/hook-development/SKILL.md +15 -0
- package/.agents/skills/mcp-builder/SKILL.md +15 -0
- package/.agents/skills/memory-cleanup/SKILL.md +21 -0
- package/.agents/skills/mode-selector/SKILL.md +17 -0
- package/.agents/skills/npm-publish/SKILL.md +16 -0
- package/.agents/skills/peekaboo-driver/SKILL.md +18 -0
- package/.agents/skills/persona-panel/SKILL.md +17 -0
- package/.agents/skills/plan/SKILL.md +20 -0
- package/.agents/skills/playwright-driver/SKILL.md +20 -0
- package/.agents/skills/quality-gates/SKILL.md +20 -0
- package/.agents/skills/reconcile/SKILL.md +21 -0
- package/.agents/skills/remote-offload/SKILL.md +20 -0
- package/.agents/skills/repo-audit/SKILL.md +16 -0
- package/.agents/skills/session-end/SKILL.md +20 -0
- package/.agents/skills/session-plan/SKILL.md +20 -0
- package/.agents/skills/session-start/SKILL.md +20 -0
- package/.agents/skills/spinout/SKILL.md +16 -0
- package/.agents/skills/sunset-review/SKILL.md +16 -0
- package/.agents/skills/test-runner/SKILL.md +20 -0
- package/.agents/skills/tmux-layout/SKILL.md +21 -0
- package/.agents/skills/using-orchestrator/SKILL.md +17 -0
- package/.agents/skills/vault-mirror/SKILL.md +15 -0
- package/.agents/skills/vault-sync/SKILL.md +15 -0
- package/.agents/skills/wave-executor/SKILL.md +20 -0
- package/.agents/skills/write-executable-plan/SKILL.md +22 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/commands/autopilot.md +2 -2
- package/.cursor/commands/bootstrap.md +1 -1
- package/.cursor/commands/brainstorm.md +1 -1
- package/.cursor/commands/debug.md +1 -1
- package/.cursor/commands/discovery.md +1 -1
- package/.cursor/commands/dispatcher.md +2 -2
- package/.cursor/commands/eli5.md +2 -2
- package/.cursor/commands/eval.md +2 -2
- package/.cursor/commands/evolve.md +1 -1
- package/.cursor/commands/go.md +1 -1
- package/.cursor/commands/grill.md +2 -2
- package/.cursor/commands/memory-cleanup.md +2 -2
- package/.cursor/commands/persona-panel.md +1 -1
- package/.cursor/commands/plan.md +1 -1
- package/.cursor/commands/portfolio.md +1 -1
- package/.cursor/commands/reconcile.md +2 -2
- package/.cursor/commands/release.md +2 -2
- package/.cursor/commands/session.md +2 -2
- package/.cursor/commands/spinout.md +2 -2
- package/.cursor/commands/sunset-review.md +2 -2
- package/.cursor/commands/templates-ack.md +2 -2
- package/.cursor/commands/test.md +2 -2
- package/.cursor/skills/brainstorm/SKILL.md +1 -1
- package/.cursor/skills/eval/SKILL.md +1 -1
- package/.cursor/skills/quality-gates/SKILL.md +1 -1
- package/.cursor/skills/remote-offload/SKILL.md +13 -0
- package/.orchestrator/policy/blocked-commands.json +121 -0
- package/.orchestrator/policy/ecosystem.schema.json +66 -0
- package/.orchestrator/policy/quality-gates.example.json +16 -0
- package/.orchestrator/policy/quality-gates.schema.json +38 -0
- package/.orchestrator/policy/templates-policy.json +27 -0
- package/.orchestrator/policy/test-profiles.json +47 -0
- package/AGENTS.md +225 -0
- package/CHANGELOG.md +1401 -0
- package/NOTICE +11 -6
- package/README.md +127 -92
- package/agents/db-specialist.md +0 -1
- package/agents/eval-judge.md +1 -1
- package/agents/skill-applied-judge.md +1 -1
- package/assets/wave-lifecycle.svg +98 -0
- package/commands/release.md +6 -3
- package/commands/session.md +18 -3
- package/docs/README.md +4 -0
- package/{agents/AGENTS.md → docs/agent-authoring.md} +19 -26
- package/docs/baseline.md +67 -0
- package/docs/ci-setup.md +249 -48
- package/docs/codex-setup.md +66 -22
- package/docs/components.md +37 -16
- package/docs/cursor-setup.md +6 -2
- package/docs/events-schema.md +51 -10
- package/docs/instruction-delivery.md +62 -0
- package/{agents/memory-proposal-collector.md → docs/memory-proposal-flow.md} +1 -8
- package/docs/migration-v4.md +341 -0
- package/docs/pi-setup.md +6 -1
- package/docs/plugin-architecture-v3.md +1 -1
- package/docs/rule-authoring.md +85 -19
- package/docs/scope-collision-guard.md +8 -8
- package/docs/session-config-reference.md +120 -61
- package/docs/session-config-template.md +40 -33
- package/docs/telemetry/telemetry-claims.md +11 -10
- package/docs/telemetry.md +187 -4
- package/docs/vault-docs-architecture.md +50 -11
- package/hooks/_lib/atomic-json.mjs +111 -0
- package/hooks/_lib/hook-import-set.json +1487 -0
- package/hooks/_lib/subagent-paths.mjs +143 -0
- package/hooks/_lib/subagent-transcript.mjs +562 -0
- package/hooks/config-protection.mjs +2 -2
- package/hooks/cwd-change-restore.mjs +11 -31
- package/hooks/enforce-commands.mjs +69 -0
- package/hooks/enforce-scope.mjs +35 -6
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +10 -0
- package/hooks/hooks-pi.json +5 -0
- package/hooks/hooks.json +6 -1
- package/hooks/loop-guard.mjs +3 -3
- package/hooks/on-session-end.mjs +280 -14
- package/hooks/on-session-start.mjs +153 -4
- package/hooks/on-stop.mjs +371 -17
- package/hooks/operator-steer.mjs +2 -2
- package/hooks/post-bash-write-verify.mjs +189 -4
- package/hooks/post-edit-import-probe.mjs +344 -0
- package/hooks/post-subagent-discovery-validator.mjs +278 -392
- package/hooks/post-tool-batch-wave-signal.mjs +272 -44
- package/hooks/post-tool-failure-corrective-context.mjs +11 -34
- package/hooks/post-tooluse-frontend-slop.mjs +3 -3
- package/hooks/pre-bash-destructive-guard.mjs +39 -13
- package/hooks/pre-bash-memory-propose-audit.mjs +13 -7
- package/hooks/skill-invocation-telemetry.mjs +17 -5
- package/hooks/subagent-telemetry.mjs +24 -30
- package/monitors/monitors.json +3 -3
- package/package.json +9 -1
- package/pi/prompts/session.md +2 -2
- package/plugin.json +27 -0
- package/scripts/autopilot.mjs +26 -12
- package/scripts/backfill-abandoned-sessions.mjs +130 -15
- package/scripts/backfill-learnings-from-vault.mjs +9 -3
- package/scripts/dialectic-deriver.mjs +73 -8
- package/scripts/emit-event.mjs +10 -2
- package/scripts/export-hw-learnings.mjs +113 -1
- package/scripts/generate-agents-skills.mjs +378 -0
- package/scripts/generate-cursor-adapter.mjs +45 -8
- package/scripts/generate-hook-import-set.mjs +249 -0
- package/scripts/lib/agent-status.mjs +13 -2
- package/scripts/lib/auq/parse.mjs +5 -29
- package/scripts/lib/auto-dialectic.mjs +68 -0
- package/scripts/lib/auto-dream.mjs +38 -36
- package/scripts/lib/autonomy/suitability.mjs +6 -0
- package/scripts/lib/autopilot/loop.mjs +2 -2
- package/scripts/lib/autopilot/worktree-pipeline.mjs +82 -6
- package/scripts/lib/build-live-signals.mjs +25 -22
- package/scripts/lib/ci-status-banner.mjs +220 -75
- package/scripts/lib/codex/plugin-contract.mjs +82 -6
- package/scripts/lib/cold-start-detector.mjs +23 -14
- package/scripts/lib/config/auto-dream.mjs +2 -1
- package/scripts/lib/config/block-header.mjs +63 -0
- package/scripts/lib/config/block-preprocess.mjs +177 -0
- package/scripts/lib/config/broken-window.mjs +2 -1
- package/scripts/lib/config/cold-start.mjs +2 -1
- package/scripts/lib/config/config-protection.mjs +22 -2
- package/scripts/lib/config/context-coverage.mjs +2 -1
- package/scripts/lib/config/cross-repo.mjs +2 -1
- package/scripts/lib/config/custom-phases.mjs +2 -1
- package/scripts/lib/config/dialectic.mjs +2 -1
- package/scripts/lib/config/discovery-validator.mjs +9 -3
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +24 -1
- package/scripts/lib/config/dispatcher-autonomy.mjs +2 -1
- package/scripts/lib/config/docs-orchestrator.mjs +2 -1
- package/scripts/lib/config/docs-staleness.mjs +2 -1
- package/scripts/lib/config/drift-check.mjs +2 -1
- package/scripts/lib/config/eval.mjs +2 -1
- package/scripts/lib/config/events-rotation.mjs +2 -1
- package/scripts/lib/config/evolve.mjs +8 -2
- package/scripts/lib/config/frontend-slop-hook.mjs +7 -3
- package/scripts/lib/config/gitlab-portfolio.mjs +2 -1
- package/scripts/lib/config/handover-gate.mjs +2 -1
- package/scripts/lib/config/health-endpoints.mjs +388 -0
- package/scripts/lib/config/issue-budget.mjs +2 -1
- package/scripts/lib/config/loop-guard.mjs +2 -1
- package/scripts/lib/config/memory.mjs +2 -1
- package/scripts/lib/config/moc-staleness.mjs +2 -1
- package/scripts/lib/config/persona-gate-wave.mjs +2 -1
- package/scripts/lib/config/private-config-dir.mjs +67 -0
- package/scripts/lib/config/reconcile.mjs +2 -1
- package/scripts/lib/config/remote-hosts.mjs +234 -0
- package/scripts/lib/config/section-extractor.mjs +7 -1
- package/scripts/lib/config/skill-evolution.mjs +2 -1
- package/scripts/lib/config/slopcheck.mjs +2 -1
- package/scripts/lib/config/state-md-lock.mjs +2 -1
- package/scripts/lib/config/templates-first.mjs +2 -1
- package/scripts/lib/config/test.mjs +2 -1
- package/scripts/lib/config/vault-integration.mjs +7 -1
- package/scripts/lib/config/vault-mirror-quality.mjs +2 -1
- package/scripts/lib/config/vault-staleness.mjs +2 -1
- package/scripts/lib/config/vault-sync.mjs +2 -1
- package/scripts/lib/config/verification-auto-fix.mjs +2 -1
- package/scripts/lib/config/wave-reviewers.mjs +2 -1
- package/scripts/lib/config/worktree-orphans.mjs +2 -1
- package/scripts/lib/config.mjs +31 -3
- package/scripts/lib/convergence-monitor.mjs +82 -16
- package/scripts/lib/dispatcher/enumerate.mjs +2 -17
- package/scripts/lib/dispatcher/rank.mjs +124 -48
- package/scripts/lib/ecosystem-health.mjs +16 -2
- package/scripts/lib/eval/engine.mjs +9 -1
- package/scripts/lib/eval/session-resolve.mjs +23 -4
- package/scripts/lib/events-schema.mjs +48 -0
- package/scripts/lib/events.mjs +256 -7
- package/scripts/lib/evolve/autonomy-verdict.mjs +9 -4
- package/scripts/lib/evolve/autopilot-effectiveness.mjs +18 -1
- package/scripts/lib/frontmatter-guard.mjs +131 -13
- package/scripts/lib/gates/gate-full.mjs +26 -0
- package/scripts/lib/gates/gate-helpers.mjs +76 -0
- package/scripts/lib/gitlab-portfolio/cli.mjs +3 -15
- package/scripts/lib/hardware-pattern-detector.mjs +18 -1
- package/scripts/lib/harness-audit/categories/category1.mjs +17 -6
- package/scripts/lib/harness-audit/categories/category4.mjs +31 -11
- package/scripts/lib/host-identity.mjs +50 -11
- package/scripts/lib/instruction-budget-guard.mjs +171 -5
- package/scripts/lib/learnings/evolve-telemetry.mjs +178 -0
- package/scripts/lib/learnings/io.mjs +60 -6
- package/scripts/lib/memory-banner.mjs +20 -8
- package/scripts/lib/memory-proposals/store.mjs +30 -22
- package/scripts/lib/owner-config-banner.mjs +43 -6
- package/scripts/lib/owner-config-loader.mjs +21 -10
- package/scripts/lib/owner-interview.mjs +3 -3
- package/scripts/lib/owner-yaml.mjs +207 -14
- package/scripts/lib/peer-discovery.mjs +20 -2
- package/scripts/lib/platform.mjs +108 -15
- package/scripts/lib/plugin-update-banner.mjs +406 -0
- package/scripts/lib/project-hygiene.mjs +38 -2
- package/scripts/lib/qg-command-drift-banner.mjs +50 -12
- package/scripts/lib/quality-gate.mjs +133 -44
- package/scripts/lib/reconcile/emitter.mjs +68 -6
- package/scripts/lib/reconcile/engine.mjs +249 -9
- package/scripts/lib/reconcile/idempotency.mjs +37 -4
- package/scripts/lib/reconcile/writer.mjs +40 -18
- package/scripts/lib/scope-gate.mjs +36 -0
- package/scripts/lib/session-close-backfill.mjs +125 -18
- package/scripts/lib/session-discovery.mjs +57 -3
- package/scripts/lib/session-end/phase-skip.mjs +2 -2
- package/scripts/lib/session-id.mjs +12 -23
- package/scripts/lib/session-identity/own-session.mjs +187 -11
- package/scripts/lib/session-lock-shape.mjs +43 -0
- package/scripts/lib/session-lock.mjs +5 -10
- package/scripts/lib/session-registry.mjs +25 -9
- package/scripts/lib/session-schema/constants.mjs +36 -2
- package/scripts/lib/session-schema/validator.mjs +38 -4
- package/scripts/lib/session-start-probes.mjs +18 -1
- package/scripts/lib/session-transition.mjs +1 -1
- package/scripts/lib/sessions-canonical.mjs +446 -0
- package/scripts/lib/sessions-staleness-banner.mjs +18 -11
- package/scripts/lib/skill-health/join.mjs +17 -4
- package/scripts/lib/state-md.mjs +78 -0
- package/scripts/lib/sunset/walker.mjs +6 -0
- package/scripts/lib/telemetry/schema.mjs +255 -17
- package/scripts/lib/telemetry/sync.mjs +417 -24
- package/scripts/lib/tmux-layout/telemetry.mjs +14 -2
- package/scripts/lib/validate/check-agents-skills.mjs +327 -0
- package/scripts/lib/validate/check-agents.mjs +3 -3
- package/scripts/lib/validate/check-cursor-adapter.mjs +234 -72
- package/scripts/lib/validate/check-doc-cli-commands.mjs +9 -33
- package/scripts/lib/validate/check-hooks-emit-event-guard.mjs +370 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +45 -16
- package/scripts/lib/validate/check-owner-leakage.mjs +281 -20
- package/scripts/lib/validate/check-skill-links.mjs +163 -0
- package/scripts/lib/validate/check-skill-script-paths.mjs +455 -0
- package/scripts/lib/validate/check-untracked-test-deps.mjs +10 -0
- package/scripts/lib/validate/check-unwired-features.mjs +0 -9
- package/scripts/lib/validate/check-validator-registration.mjs +254 -0
- package/scripts/lib/validate/check-vcs-repo-flag.mjs +6 -28
- package/scripts/lib/validate/enumerate-repo-files.mjs +317 -0
- package/scripts/lib/validate/markdown-fences.mjs +196 -0
- package/scripts/lib/vault-backfill/template.mjs +63 -6
- package/scripts/lib/vault-mirror/process.mjs +165 -42
- package/scripts/lib/vault-mirror/telemetry.mjs +2 -2
- package/scripts/lib/vault-status/board-lock.mjs +185 -0
- package/scripts/lib/vault-status/board-writer.mjs +174 -135
- package/scripts/lib/vault-status/narrative-mirror.mjs +129 -37
- package/scripts/lib/wave-executor/dispatch-common.mjs +164 -0
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +7 -142
- package/scripts/lib/wave-executor/remote-dispatch.mjs +502 -0
- package/scripts/lib/wave-resource-gate.mjs +133 -7
- package/scripts/lib/wave-sizing.mjs +4 -1
- package/scripts/lib/wave-transcript-tail.mjs +142 -8
- package/scripts/materialize-wave-scope.mjs +32 -9
- package/scripts/memory-propose.mjs +146 -8
- package/scripts/migrate-cold-start-seed.mjs +4 -1
- package/scripts/parse-config.mjs +60 -3
- package/scripts/promote-vault-strict.mjs +4 -15
- package/scripts/release.mjs +337 -29
- package/scripts/repair-invalid-sessions.mjs +3 -3
- package/scripts/run-quality-gate.mjs +128 -11
- package/scripts/site-numbers.mjs +36 -4
- package/scripts/sweep-expired-learnings.mjs +90 -0
- package/scripts/sync-vault-schema.mjs +3 -1
- package/scripts/telemetry.mjs +2 -2
- package/scripts/validate-plugin.mjs +187 -0
- package/scripts/validate-wave-scope.mjs +28 -8
- package/scripts/vault-consolidate.mjs +3 -11
- package/scripts/vault-integration-watcher.mjs +2 -4
- package/scripts/vault-mirror.mjs +111 -26
- package/scripts/wave-scope-binding.mjs +215 -0
- package/skills/_shared/instruction-file-resolution.md +10 -0
- package/skills/_shared/parallel-aware-auq.md +31 -2
- package/skills/_shared/parallel-aware-preamble.md +18 -4
- package/skills/_shared/platform-tools.md +1 -1
- package/skills/_shared/state-ownership.md +1 -1
- package/skills/architecture/SKILL.md +7 -5
- package/skills/{domain-model/SKILL.md → architecture/references/domain-model.md} +9 -9
- package/skills/autopilot/SKILL.md +4 -18
- package/skills/claude-md-drift-check/SKILL.md +5 -1
- package/skills/claude-md-drift-check/checker.mjs +62 -2
- package/skills/convergence-monitoring/SIGNALS.md +55 -0
- package/skills/discovery/probes/vault-staleness.mjs +37 -13
- package/skills/discovery/probes-arch.md +20 -18
- package/skills/dispatcher/SKILL.md +3 -2
- package/skills/ecosystem-health/SKILL.md +4 -1
- package/skills/ecosystem-health/wizard.md +5 -0
- package/skills/evolve/SKILL.md +87 -11
- package/skills/frontmatter-guard/SKILL.md +11 -5
- package/skills/npm-publish/SKILL.md +1 -1
- package/skills/reconcile/SKILL.md +38 -2
- package/skills/remote-offload/SKILL.md +89 -0
- package/skills/session-end/SKILL.md +18 -905
- package/skills/session-end/phase-3-6-tail.md +19 -9
- package/skills/session-end/plan-verification.md +221 -155
- package/skills/session-end/references/phase-2-quality-gate.md +93 -0
- package/skills/session-end/references/phase-3-documentation-updates.md +229 -0
- package/skills/session-end/references/phase-4a-worktree-cleanup.md +120 -0
- package/skills/session-end/references/phase-4b-worktree-orphan-sweep.md +58 -0
- package/skills/session-end/references/phase-5-issue-cleanup.md +104 -0
- package/skills/session-end/references/session-summary-template.md +62 -0
- package/skills/session-plan/SKILL.md +49 -0
- package/skills/session-start/SKILL.md +41 -900
- package/skills/session-start/phase-8-5-express-path.md +1 -1
- package/skills/session-start/references/phase-1-1-dispatcher-autonomy-capture.md +55 -0
- package/skills/session-start/references/phase-1-2-session-lock.md +140 -0
- package/skills/session-start/references/phase-1-5-session-continuity.md +254 -0
- package/skills/session-start/references/phase-1-7-vault-status-board.md +53 -0
- package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +75 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +155 -0
- package/skills/session-start/references/phase-6-5-forced-reads.md +75 -0
- package/skills/session-start/references/phase-6-6-project-intelligence.md +81 -0
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +103 -0
- package/skills/vault-sync/validator.mjs +21 -27
- package/skills/wave-executor/SKILL.md +16 -2
- package/skills/wave-executor/references/wave-loop-dispatch.md +612 -0
- package/skills/wave-executor/references/wave-loop-review.md +570 -0
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +162 -0
- package/skills/wave-executor/wave-loop.md +14 -1271
- package/templates/_shared/journey-manifest.md +10 -6
- package/.cursor/commands/autopilot-multi.md +0 -14
- package/.cursor/commands/contract-version-bump.md +0 -14
- package/.cursor/commands/journey-audit.md +0 -14
- package/.cursor/skills/contract-version-bump/SKILL.md +0 -12
- package/.cursor/skills/daily/SKILL.md +0 -12
- package/.cursor/skills/domain-model/SKILL.md +0 -13
- package/.cursor/skills/journey-audit/SKILL.md +0 -13
- package/.cursor/skills/skill-creator/SKILL.md +0 -13
- package/.cursor/skills/ubiquitous-language/SKILL.md +0 -13
- package/commands/autopilot-multi.md +0 -74
- package/commands/contract-version-bump.md +0 -28
- package/commands/journey-audit.md +0 -43
- package/pi/prompts/autopilot-multi.md +0 -12
- package/pi/prompts/contract-version-bump.md +0 -12
- package/pi/prompts/journey-audit.md +0 -12
- package/scripts/autopilot-multi.mjs +0 -885
- package/scripts/backfill-learnings-expires.mjs +0 -196
- package/scripts/backfill-learnings.mjs +0 -203
- package/scripts/fleet-instruction-scan.mjs +0 -141
- package/scripts/lib/autopilot/dep-graph.mjs +0 -417
- package/scripts/lib/autopilot/multi-killswitch.mjs +0 -184
- package/scripts/lib/webhook-url.mjs +0 -105
- package/scripts/lifecycle-sim-v6.mjs +0 -347
- package/scripts/migrate-learnings-jsonl.mjs +0 -189
- package/scripts/migrate-subagents-jsonl.mjs +0 -196
- package/scripts/upload-social-preview.mjs +0 -316
- package/skills/_shared/model-selection.md +0 -64
- package/skills/contract-version-bump/SKILL.md +0 -219
- package/skills/daily/SKILL.md +0 -222
- package/skills/daily/generate.sh +0 -92
- package/skills/daily/templates/daily.md.tpl +0 -36
- package/skills/journey-audit/SKILL.md +0 -269
- package/skills/skill-creator/SKILL.md +0 -168
- package/skills/ubiquitous-language/SKILL.md +0 -97
- package/skills/vault-sync/package-lock.json +0 -40
- /package/skills/{domain-model → architecture/references}/ADR-FORMAT.md +0 -0
- /package/skills/{domain-model → architecture/references}/CONTEXT-FORMAT.md +0 -0
|
@@ -61,6 +61,8 @@ Bypass via `SO_SKIP_CONFIG_VALIDATION=1`. Missing fields can be patched into an
|
|
|
61
61
|
|
|
62
62
|
**Stale-citation note:** an older code comment on the `custom-phases:` key in this repo's own `CLAUDE.md` cites a per-key regex (`/^custom-phases:\s*$/`) as the mechanism. That citation predates the #830 generalisation — `custom-phases.mjs` (like all 37 consumers) now delegates to the shared `matchBlockHeader(line, 'custom-phases')`, which is strictly MORE tolerant than the old per-key regex (it additionally accepts the dash-bullet and bold-bullet renderings). The no-inline-comment failure mode is unchanged; only the underlying mechanism moved from a bespoke regex to the shared helper. Treat any remaining per-key regex citation in prose (including in this file, prior to this section's introduction) as documentation of the OLD mechanism — the general contract above is current.
|
|
63
63
|
|
|
64
|
+
**A second, orthogonal gotcha shares this section: a multi-line `<!-- … -->` comment (#1162).** Every block-shaped parser now strips commented-out lines before matching, via `scripts/lib/config/block-preprocess.mjs` — so a block commented out to disable it can no longer be read as live config, and a bold-bullet sub-key rendering (`- **enabled:** true`) is normalised before parsing instead of silently missing its regex. The one failure mode that still exists is an **unterminated** `<!--` — a stray opener with no matching `-->` anywhere in the rest of the document. `scripts/parse-config.mjs` detects this ONCE per session (not once per parser) and prints a single stderr WARN: `⚠ <file>: unterminated <!-- at line N — comment stripping disabled for the whole document`. The fail-closed direction differs by consumer: a block PARSER gets its lines back UNFILTERED (nothing may silently vanish), while the two destructive-bypass scanners (`allow-config-weakening`, `allow-destructive-ops`) treat an unterminated comment as the bypass being **NOT ARMED** — an ambiguous document must never grant an opt-in it cannot read cleanly.
|
|
65
|
+
|
|
64
66
|
## Policy Files
|
|
65
67
|
|
|
66
68
|
Some sub-configs live in dedicated policy files under `.orchestrator/policy/`:
|
|
@@ -74,12 +76,46 @@ Some sub-configs live in dedicated policy files under `.orchestrator/policy/`:
|
|
|
74
76
|
|
|
75
77
|
| Field | Type | Default | Description |
|
|
76
78
|
|-------|------|---------|-------------|
|
|
77
|
-
| `agents-per-wave` | integer or integer with overrides | `6` | Maximum parallel subagents per wave. Supports session-type overrides: `6 (deep: 18)` outputs `{"default": 6, "deep": 18}`. Plain integers remain plain. The override key names a session type but does **not** create one: there is no `session-type:` Session Config key — `parseSessionConfig()` emits none, so writing one into a repo's `## Session Config` block is inert prose. The session type comes from the `/session` argument (default `deep`, see `commands/session.md`) and is persisted to STATE.md frontmatter as `session-type:`, which is the only live read (`scripts/print-applicable-rules.mjs` rule mode-gating). |
|
|
79
|
+
| `agents-per-wave` | integer or integer with overrides | `6` | Maximum parallel subagents per wave. Supports session-type overrides: `6 (deep: 18)` outputs `{"default": 6, "deep": 18}`. The override key set is OPEN — `_coerceInteger` (`scripts/lib/config/coercers.mjs`) parses whatever keys the parentheses contain, so `6 (deep: 18, ultradeep: 18)` outputs `{"default": 6, "deep": 18, "ultradeep": 18}` with no code change (see § Session Profile below). Plain integers remain plain. The override key names a session type but does **not** create one: there is no `session-type:` Session Config key — `parseSessionConfig()` emits none, so writing one into a repo's `## Session Config` block is inert prose. The session type comes from the `/session` argument (default `deep`, see `commands/session.md`) and is persisted to STATE.md frontmatter as `session-type:`, which is the only live read (`scripts/print-applicable-rules.mjs` rule mode-gating). |
|
|
78
80
|
| `agent-mapping` | object | null | Optional mapping of role keys to agent names for explicit agent binding. Keys: `impl`, `test`, `db`, `ui`, `security`, `compliance`, `docs`, `perf`. Example: `{ impl: code-editor, test: test-specialist }`. Overrides auto-discovery when present. Values may carry a channel prefix — see § `agent-mapping` values below. |
|
|
79
81
|
| `waves` | integer | `5` | Number of execution waves for feature and deep sessions. |
|
|
80
82
|
| `recent-commits` | integer | `20` | Number of recent commits to display during session start git analysis. |
|
|
81
83
|
| `special` | string | none | Repo-specific instructions. Freeform text that the orchestrator reads and follows during sessions. |
|
|
82
84
|
|
|
85
|
+
### Session Profile — `session-profile` (NOT a Session Config key)
|
|
86
|
+
|
|
87
|
+
`session-profile` names a WAVE-SHAPE variant on top of an unchanged `session-type`. It is listed here because it is easy to look for in the wrong place: **it is not a Session Config key and `parseSessionConfig()` does not emit one.** Writing `session-profile:` into a repo's `## Session Config` block is inert prose, exactly like `session-type:` (see the `agents-per-wave` row above).
|
|
88
|
+
|
|
89
|
+
| Aspect | Value |
|
|
90
|
+
|---|---|
|
|
91
|
+
| Where it lives | STATE.md frontmatter (`session-profile: ultradeep`), written per session |
|
|
92
|
+
| Who writes it | The `/session ultradeep` argument alias — `commands/session.md` |
|
|
93
|
+
| Read/write API | `readSessionProfile` / `setSessionProfile` / `SESSION_PROFILE_FIELD` in `scripts/lib/state-md.mjs` |
|
|
94
|
+
| Absent means | No profile. Never an empty string, never `none` — `readSessionProfile` returns `null` |
|
|
95
|
+
| Session record | Optional `session_profile` field (`scripts/lib/session-schema/constants.mjs` `OPTIONAL_FIELDS`); records without it validate unchanged |
|
|
96
|
+
| Defined values | `ultradeep` (7 waves, coordinator-direct Synthesis-Gate at wave 2) — spec: `docs/prd/2026-09-06-ultradeep-session-profile.md` |
|
|
97
|
+
|
|
98
|
+
`session-type` NEVER becomes `ultradeep`: that value is a closed set in `scripts/lib/session-schema/constants.mjs`, `scripts/lib/wave-sizing.mjs` and `scripts/lib/session-close-backfill.mjs`, and an unknown member degrades SILENTLY there (telemetry maps it to `"other"`, the close-backfill labels it `housekeeping`). The profile field exists so no closed set has to change.
|
|
99
|
+
|
|
100
|
+
**Sizing an ultradeep session** uses the open override key set:
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
agents-per-wave: 6 (deep: 18, ultradeep: 18)
|
|
104
|
+
waves: 5 # must be >= 7 for the ultradeep wave shape
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Verified against the parser (2026-09-06, `scripts/lib/config/coercers.mjs`):
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
$ node -e "import('./scripts/lib/config/coercers.mjs').then(m => console.log(JSON.stringify(
|
|
111
|
+
m._coerceInteger(new Map([['agents-per-wave','6 (deep: 18, ultradeep: 18)']]), 'agents-per-wave', 6))))"
|
|
112
|
+
{"default":6,"deep":18,"ultradeep":18}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Two consumers resolve that object to `.default` rather than to a mode key — `scripts/lib/resource-probe/evaluate.mjs` and `scripts/lib/wave-resource-gate.mjs` (see `heavy-repo` in § Environment Awareness) — so an `ultradeep: 18` override does NOT raise the resource gate's cap.
|
|
116
|
+
|
|
117
|
+
**Budgets are deliberately absent.** The PRD's `ultradeep.max-agents-total` / `max-wall-clock-hours` / `max-output-tokens` / `on-breach` block (§ 7) is NOT implemented and no key of that name is read anywhere. It stays deferred until three ultradeep runs have been measured, per `.claude/rules/host-resources.md` HR-105 — a threshold whose firing rate nothing records is unfalsifiable. Do not add one ahead of the measurement.
|
|
118
|
+
|
|
83
119
|
### `agent-mapping` values — channel prefixes (#1150)
|
|
84
120
|
|
|
85
121
|
A mapping value has three forms, distinguished by the colon:
|
|
@@ -98,7 +134,7 @@ agent-mapping: { impl: cursor:composer-2.5, test: cursor:cursor-grok-4.6-high, s
|
|
|
98
134
|
|
|
99
135
|
**Where the rest of the contract lives** — deliberately not here, so one place owns it:
|
|
100
136
|
|
|
101
|
-
- **Model selection** (which model for which role, and why): the
|
|
137
|
+
- **Model selection** (which model for which role, and why): the operator's model-routing SSOT (ADR-002). Working defaults are `composer-2.5` for foreign impl and `cursor-grok-4.6-high` for review / test-writing / judgment roles.
|
|
102
138
|
- **Dispatch contract** (detached worktree, the `never_foreign` role lock, the filesystem-measured verdict, the MANDATORY Claude semantic diff-review before merge-back, wall-clock timeout instead of `maxTurns`, and the `orchestrator.foreign_dispatch.completed` event that replaces the hook-chain telemetry a foreign run cannot emit): `skills/wave-executor/wave-loop.md` § Third branch: foreign-model dispatch.
|
|
103
139
|
|
|
104
140
|
## VCS & Infrastructure
|
|
@@ -111,8 +147,34 @@ agent-mapping: { impl: cursor:composer-2.5, test: cursor:cursor-grok-4.6-high, s
|
|
|
111
147
|
| `cross-repos` | list | none | Related repositories under `~/Projects/`. The orchestrator checks their git state and critical issues during session start. |
|
|
112
148
|
| `cross-repo.projects` | list | `[]` | Repos to process when running cross-repo maintenance scripts (`run-migrate-v2-cross-repo.mjs`, `vault-integration-watcher.mjs`, `promote-vault-strict.mjs`). Each entry is a path (absolute, `~`-prefixed, or bare name resolved under `~/Projects/`). When this list is empty or absent, those scripts emit a one-line notice and exit 0 — they never error on an empty list. Example: `[~/Projects/my-app, ~/Projects/another-app]`. |
|
|
113
149
|
| `pencil` | string | none | Path to a `.pen` design file (relative to project root). Enables design-code alignment reviews after Impl-Core and Impl-Polish waves. |
|
|
114
|
-
| `ecosystem-health` | boolean | `false` | Enable service health checks at session start. Requires `health-endpoints` to be configured. |
|
|
115
|
-
| `health-endpoints` | list | none | Service URLs to check health. Each entry is an object with `name` and `url` fields. |
|
|
150
|
+
| `ecosystem-health` | boolean | `false` | Enable service health checks at session start. Requires `health-endpoints` to be configured. Accepts the SCALAR form (`ecosystem-health: true`) read off the flat key/value map, or a BLOCK form (`ecosystem-health:` with no value, followed by an indented body — the wizard's output) read via `_parseEcosystemHealthBlockEnabled()`; the scalar wins when both are present (#1174). |
|
|
151
|
+
| `health-endpoints` | list | none | Service URLs to check health. Each entry is an object with `name` and `url` fields. Parsed by `scripts/lib/config/health-endpoints.mjs`, which accepts THREE forms (#1174) — see below. |
|
|
152
|
+
|
|
153
|
+
**`health-endpoints` accepted forms.** Before #1174 the parser read this key off the flat KV map,
|
|
154
|
+
which bails to `null` the instant a value contains `{` and cannot see a nested YAML block at all;
|
|
155
|
+
the wizard's own output (Form B) silently failed to parse. All three forms below are parsed
|
|
156
|
+
content-scoped, independent of the flat KV map:
|
|
157
|
+
|
|
158
|
+
```yaml
|
|
159
|
+
# Form A — inline object array
|
|
160
|
+
health-endpoints: [{name: "API", url: "https://a/health"}, {name: "W", url: "http://w:8080/z"}]
|
|
161
|
+
|
|
162
|
+
# Form B — nested block (top-level, or one level under `ecosystem-health:`); the wizard's output.
|
|
163
|
+
# Block items may also be inline objects, `- { name: API, url: … }` (the form this file's own
|
|
164
|
+
# example above uses).
|
|
165
|
+
health-endpoints:
|
|
166
|
+
- name: API
|
|
167
|
+
url: https://api.example.com/health
|
|
168
|
+
|
|
169
|
+
# Form C — bare bracket list of URLs; each URL becomes its own name ({ name: <url>, url: <url> })
|
|
170
|
+
health-endpoints: [https://a/health, https://b/health]
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The `name=url` shorthand (Form D) is **not** supported — an entry containing `=` is treated
|
|
174
|
+
verbatim as a Form-C URL, never split on `=`. A malformed entry (missing `name` or `url`, an
|
|
175
|
+
unmatched brace) resolves to `null` for the whole key and prints exactly one
|
|
176
|
+
`config: health-endpoints:` WARN to stderr — it never throws, so a broken config key cannot take
|
|
177
|
+
down session-start.
|
|
116
178
|
| `issue-limit` | integer | `50` | Maximum issues to fetch when querying VCS during session start. |
|
|
117
179
|
| `stale-branch-days` | integer | `7` | Days of inactivity before a branch is flagged as stale. |
|
|
118
180
|
| `stale-issue-days` | integer | `30` | Days without progress before an issue is flagged for triage. |
|
|
@@ -255,7 +317,7 @@ slopcheck:
|
|
|
255
317
|
| `grounding-injection-max-files` | integer | `3` | Max files with recent `edit-format-friction` stagnation history to inject as line-numbered GROUNDING blocks into each agent's prompt before dispatch (wave-executor pre-dispatch step). Per-agent scope; selects top N by recency. `0` disables the feature. Gated on `persistence: true`. (#85) |
|
|
256
318
|
| `isolation` | string | `auto` | Agent isolation mode: `worktree`, `none`, or `auto`. `auto` resolves per-wave via the graduated default (#194): ≤2 agents → `none`, 3–4 agents on feature/deep → `worktree`, ≥5 agents → `worktree`, housekeeping 3–4 → `none`. Explicit `worktree` or `none` overrides the graduation. See [isolation graduation](#isolation-graduation) below. |
|
|
257
319
|
| `max-turns` | integer or string | `auto` | Maximum agent turns before PARTIAL. Auto: housekeeping=8, feature=15, deep=25. |
|
|
258
|
-
| `auto-commit-per-wave` | boolean | `false` | Automatically commit each wave's work after the Quality-Lite gate passes. Checkpoint commits per wave reduce the risk of data loss from `git stash` collisions in parallel sessions (V3.3 RESCUE incident — see GitLab #214). When `false`, all work is committed at session-end via `/close`. Requires `persistence: true`; the flag is silently ignored when `persistence: false`. Trade-off: each wave produces an additional commit; git log shows N+1 commits instead of 1. Use `/simplify` or `git rebase -i --autosquash` before final close to squash if a clean history is desired. **Implementation note:** the procedural commit sequence (`scripts/lib/auto-commit.mjs`) is deferred to V3.6. Until then, setting this flag to `true` triggers a session-start warning that auto-commits are not yet active — the flag is a no-op but is validated so projects can opt in early. |
|
|
320
|
+
| `auto-commit-per-wave` | boolean | `false` | Automatically commit each wave's work after the Quality-Lite gate passes. Checkpoint commits per wave reduce the risk of data loss from `git stash` collisions in parallel sessions (V3.3 RESCUE incident — see GitLab #214). When `false`, all work is committed at session-end via `/close`. Requires `persistence: true`; the flag is silently ignored when `persistence: false`. Trade-off: each wave produces an additional commit; git log shows N+1 commits instead of 1. Use `/simplify` or `git rebase -i --autosquash` before final close to squash if a clean history is desired. **Implementation note:** the procedural commit sequence (`scripts/lib/auto-commit.mjs`) is deferred to V3.6. Until then, setting this flag to `true` triggers a session-start warning that auto-commits are not yet active — the flag is a no-op but is validated so projects can opt in early. <!-- path-check: historical --> |
|
|
259
321
|
|
|
260
322
|
### enforcement-gates: the five gate keys (#800/#915)
|
|
261
323
|
|
|
@@ -385,18 +447,18 @@ state-md-lock:
|
|
|
385
447
|
|
|
386
448
|
## Discovery-Validator (PSA-006 Enforcement, #567)
|
|
387
449
|
|
|
388
|
-
Non-blocking `SubagentStop` hook that mechanically enforces PSA-006: distributional claims ("N of M", "100% of", "all N", "no remaining", "every X", "none of") appearing in a subagent's transcript tail must carry an adjacent fenced grep/rg/find transcript. When a claim lacks one, the hook records a `discovery_validator_violation` event in `.orchestrator/metrics/events.jsonl` and emits a stderr WARN. v1 is log + warn only — exit 0 always, never blocks the agent; a blocking hard-gate is reserved for a future iteration. Default
|
|
450
|
+
Non-blocking `SubagentStop` hook that mechanically enforces PSA-006: distributional claims ("N of M", "100% of", "all N", "no remaining", "every X", "none of") appearing in a subagent's transcript tail must carry an adjacent fenced grep/rg/find transcript. When a claim lacks one, the hook records a `discovery_validator_violation` event in `.orchestrator/metrics/events.jsonl` and emits a stderr WARN. v1 is log + warn only — exit 0 always, never blocks the agent; a blocking hard-gate is reserved for a future iteration. Default OFF (opt-in) — the #690 flip to ON was reverted 2026-09-02 (#1191) after fleet measurement showed 6,946 violation events accumulating in 18 repos that never declared the block.
|
|
389
451
|
|
|
390
452
|
All fields live under a top-level `discovery-validator` object in your Session Config host file (`CLAUDE.md` or `AGENTS.md`), for example:
|
|
391
453
|
|
|
392
454
|
```yaml
|
|
393
455
|
discovery-validator:
|
|
394
|
-
enabled: true #
|
|
456
|
+
enabled: true # off by default; opt in per repo — log+warn-only, exit-0-always
|
|
395
457
|
```
|
|
396
458
|
|
|
397
459
|
| Field | Type | Default | Description |
|
|
398
460
|
|-------|------|---------|-------------|
|
|
399
|
-
| `discovery-validator.enabled` | boolean | `
|
|
461
|
+
| `discovery-validator.enabled` | boolean | `false` | Master toggle. When `false` (or when the block is absent), the `SubagentStop` hook is bypassed entirely — no transcript scanning, no `discovery_validator_violation` events. Note: when the `discovery-validator:` block is present but omits the `enabled:` line, the parser conservatively resolves to `false` — only a literal `true` enables the hook. Always set `enabled` explicitly when adding this block. |
|
|
400
462
|
|
|
401
463
|
**Used by:** `hooks/post-subagent-discovery-validator.mjs`, `scripts/lib/config/discovery-validator.mjs` (`_parseDiscoveryValidator`). See `.claude/rules/parallel-sessions.md` § PSA-006.
|
|
402
464
|
|
|
@@ -678,6 +740,8 @@ vault-integration:
|
|
|
678
740
|
|
|
679
741
|
> **Host-local override (#653; extended #819).** `vault-dir` resolves host-locally with precedence: env-var (`SO_VAULT_DIR`) > `owner.yaml` `paths.vault-dir` > the committed default. `plan-baseline-path` resolves with an extra per-context tier in between: `SO_BASELINE_PATH` env > `owner.yaml` `baselines:` directory-prefix match against cwd > `owner.yaml` `paths.baseline-path` (legacy scalar) > the committed default. This keeps maintainer-specific absolute paths out of version control. Resolvers: `scripts/lib/config/host-paths.mjs` (both keys) and `scripts/lib/named-baseline-resolver.mjs` (the `baselines:` match tier).
|
|
680
742
|
|
|
743
|
+
> **`SO_CONFIG_HOME` — the host-private config directory itself.** A sibling override, one layer below `owner.yaml`'s own contents rather than a key inside it: `scripts/lib/host-identity.mjs` `_privateDir()` resolves the directory holding `owner.yaml`, `host-private.json`, and the host-alias ledger (`SO_HOST_ALIASES_FILE`, see `host-identity.mjs`) with precedence env-var (`SO_CONFIG_HOME`, names the private dir ITSELF) > `XDG_CONFIG_HOME` (names its PARENT — `owner-config-loader.mjs` uses the same variable the same way) > the homedir default `~/.config/session-orchestrator`. Both env vars are read with `.trim() || fallback`, not a bare `||` (`.claude/rules/development.md` § Error Handling env-var-fallback-whitespace trap).
|
|
744
|
+
|
|
681
745
|
> **Parser accepts three key-line renderings (#823).** The `vault-integration:` key line is recognized in plain form (`vault-integration:`), dash-bullet form (`- vault-integration:`), and bold-bullet form (`- **vault-integration:**`) — each paired with either the inline-object shape (`{ enabled: true, ... }` on the same line) or the indented block shape shown above. Parser: `scripts/lib/config/vault-integration.mjs` (`_parseVaultIntegration`).
|
|
682
746
|
|
|
683
747
|
| Field | Type | Default | Description |
|
|
@@ -818,7 +882,7 @@ Memory proposals are one of five Epic #498 Phase 2 features that share the same
|
|
|
818
882
|
|
|
819
883
|
Together: F2.1 captures fresh insight mid-flight, F2.2 consolidates old insight at scale, F2.3 surfaces it at the start, F2.4/F2.5 distill it into the durable peer-card profiles.
|
|
820
884
|
|
|
821
|
-
**Used by:** `scripts/lib/memory-proposals/{schema,store,collector,sink}.mjs`, `scripts/memory-propose.mjs`, `
|
|
885
|
+
**Used by:** `scripts/lib/memory-proposals/{schema,store,collector,sink}.mjs`, `scripts/memory-propose.mjs`, `docs/memory-proposal-flow.md`, `hooks/pre-bash-memory-propose-audit.mjs`, `skills/session-end/SKILL.md` Phase 3.6.3.
|
|
822
886
|
|
|
823
887
|
**Cross-reference:** issue #501, PRD F2.1 in the Learning-Memory Modernization PRD; issue #741.3 (`--dry-run` flag + `dry-run-ok` status). Sibling features: `memory.banner` (above, F2.3 / #505), `dialectic.cadence` (F2.5 / #506), Auto-Dream (F2.2 / #502, surfaced via `memory-cleanup-soft-limit`).
|
|
824
888
|
|
|
@@ -1190,6 +1254,38 @@ Read by: `scripts/lib/config/custom-phases.mjs` (parser), `skills/session-end/SK
|
|
|
1190
1254
|
- `archive-closed-prds` (#782, Epic #774) — `node scripts/archive-closed-prds.mjs --apply` — archives `docs/prd/` PRDs (defaults).
|
|
1191
1255
|
- `archive-closed-plans` (#786) — `… --apply --prd-dir docs/plans --vault-subdir 01-projects/session-orchestrator/plans` — archives `docs/plans/` executable-plan artefacts of closed features/Epics. The plan's tracking `#NNN` (inline in the plan's `Source:` header, see `skills/write-executable-plan/`) is the anchor this phase reads; a plan with no `#NNN` is never archived (fail-closed `no-epic-ref`).
|
|
1192
1256
|
|
|
1257
|
+
## Remote Hosts (#1160)
|
|
1258
|
+
|
|
1259
|
+
Opt-in declaration of ssh-reachable hosts a heavy wave role may be OFFLOADED to instead of shrinking the wave under local resource pressure. This key only DECLARES: it never probes a host, never dispatches, and never changes a wave by itself. Absent/empty ⇒ `[]` ⇒ every wave stays local, exactly as before.
|
|
1260
|
+
|
|
1261
|
+
**Parser gotcha:** like every other block-shaped Session Config key, the `remote-hosts:` key-line itself MUST NOT carry an inline comment — see § Parser Gotcha: No-Inline-Comment Block Headers (top of this file). A trailing `# comment` on that exact line means the parser never enters the block and `remote-hosts` silently resolves to `[]`.
|
|
1262
|
+
|
|
1263
|
+
```yaml
|
|
1264
|
+
remote-hosts:
|
|
1265
|
+
- alias: m5 # required, SAFE slug; reaches argv as `-H <alias>`
|
|
1266
|
+
roles-allowed: [test, ui, perf] # subset of test|ui|perf (default: all three)
|
|
1267
|
+
repo-path: ~/Projects/Alice # optional; SAFE path; default null
|
|
1268
|
+
claude-path: ~/.local/bin/claude # optional; SAFE path; default null
|
|
1269
|
+
```
|
|
1270
|
+
|
|
1271
|
+
| Field | Type | Default | Description |
|
|
1272
|
+
|-------|------|---------|-------------|
|
|
1273
|
+
| `remote-hosts` | list | `[]` | The declared hosts, in preference order — the gate takes the FIRST host that accepts the role and is witnessed ready. |
|
|
1274
|
+
| `alias` | string | — (required) | ssh destination as configured on this host. Must match `^[A-Za-z0-9._-]+$`; it reaches argv as `-H <alias>`. A record missing or failing this is dropped with a stderr WARN. |
|
|
1275
|
+
| `roles-allowed` | string[] | `[test, ui, perf]` | The `agent-mapping` roles this host accepts. Entries outside `test` / `ui` / `perf` are filtered with a WARN; a record whose list is empty after filtering is dropped. `impl`, `db`, `security`, `compliance` and `docs` work never leaves the local host. |
|
|
1276
|
+
| `repo-path` | string \| null | `null` | Checkout location on the remote host. SAFE-path validated (`^[A-Za-z0-9._~/-]+$`); an unsafe value drops the whole record with a WARN. |
|
|
1277
|
+
| `claude-path` | string \| null | `null` | `claude` binary location on the remote host. Same validation as `repo-path`. |
|
|
1278
|
+
|
|
1279
|
+
**Two enums, never conflated.** `roles-allowed` holds `agent-mapping` roles (`test`, `ui`, `perf`) — NOT wave roles (`Impl-Core`, `Quality`, …). The wave→role translation is `OFFLOADABLE_WAVE_ROLES` in `scripts/lib/wave-resource-gate.mjs`; a wave role absent from that map is local-only by default.
|
|
1280
|
+
|
|
1281
|
+
**Placement contract.** The gate applies its offload arm only after the HR-004 heavy-repo cap, and only when the resource verdict was `reduce` or `coordinator-direct`. It does NOT probe the network: the coordinator supplies a readiness witness (`remoteReady: { m5: true }`, or an async `probeFn`). With no witness, no host counts as ready and the decision stays local — the gate fails toward local, never toward an unverified host. A role in `NEVER_FOREIGN_ROLES` (`scripts/lib/wave-executor/dispatch-common.mjs`) is never offloaded regardless.
|
|
1282
|
+
|
|
1283
|
+
**agent-mapping interaction.** A declared alias is what an `agent-mapping` value of the form `<role>: ssh:<alias>` validates against; naming an undeclared host throws at parse time, naming the `ssh` channel with no target throws as for any other channel.
|
|
1284
|
+
|
|
1285
|
+
Read by: `scripts/lib/config/remote-hosts.mjs` (parser), `scripts/lib/config.mjs` (`ssh:` channel validation), `scripts/lib/wave-resource-gate.mjs` (placement).
|
|
1286
|
+
|
|
1287
|
+
See `skills/remote-offload/SKILL.md` for the wave-executor-side decision rule, the three offload channels, and how a declared alias here is what an `agent-mapping` `ssh:<alias>` value validates against.
|
|
1288
|
+
|
|
1193
1289
|
## Evolve Extra Sources (#638)
|
|
1194
1290
|
|
|
1195
1291
|
Opt-in EXTRA learning sources for `/evolve`. A domain measurement (e.g. an eval-learn regression harness) runs OUT-OF-BAND and writes a sidecar JSON of regression flags; `/evolve` then READS each declared sidecar and emits a `domain-regression` learning candidate per flag that has persisted across ≥2 consecutive sessions. This is a strict **read-only consumption contract**: `/evolve` never runs the domain measurement — it only consumes the sidecar output. Absent/empty ⇒ `[]` ⇒ no extra sources are read; existing `/evolve` runs are unaffected.
|
|
@@ -1484,43 +1580,7 @@ SO_DISABLED_HOOKS=enforce-scope,enforce-commands claude ...
|
|
|
1484
1580
|
|
|
1485
1581
|
Each hook handler imports `shouldRunHook` from `hooks/_lib/profile-gate.mjs` at the top level and calls `process.exit(0)` immediately when gated off. The exit is silent (no stdout, no stderr), so Claude Code sees an allow as if the hook had never run.
|
|
1486
1582
|
|
|
1487
|
-
##
|
|
1488
|
-
|
|
1489
|
-
Opt-in webhook notifications delivered by `scripts/lib/webhook-url.mjs`. The helper centralizes URL resolution so no personal-domain default ever silently fires — callers must supply a URL explicitly.
|
|
1490
|
-
|
|
1491
|
-
### Resolution order
|
|
1492
|
-
|
|
1493
|
-
For every supported kind the resolver checks sources in this order; the first non-empty string wins:
|
|
1494
|
-
|
|
1495
|
-
1. **Environment variable** `SO_WEBHOOK_<KIND>_URL` — uppercase kind, hyphens → underscores
|
|
1496
|
-
e.g. `SO_WEBHOOK_SLACK_URL`, `SO_WEBHOOK_GITLAB_PIPELINE_STATUS_URL`
|
|
1497
|
-
2. **Session Config** `webhooks.<kind>.url`
|
|
1498
|
-
3. **Error** — `WebhookConfigError` is thrown. No silent personal-domain fallback.
|
|
1499
|
-
|
|
1500
|
-
### Supported kinds
|
|
1501
|
-
|
|
1502
|
-
| Kind | Env variable | Config key |
|
|
1503
|
-
|------|-------------|------------|
|
|
1504
|
-
| `slack` | `SO_WEBHOOK_SLACK_URL` | `webhooks.slack.url` |
|
|
1505
|
-
| `discord` | `SO_WEBHOOK_DISCORD_URL` | `webhooks.discord.url` |
|
|
1506
|
-
| `generic` | `SO_WEBHOOK_GENERIC_URL` | `webhooks.generic.url` |
|
|
1507
|
-
| `gitlab-pipeline-status` | `SO_WEBHOOK_GITLAB_PIPELINE_STATUS_URL` | `webhooks.gitlab-pipeline-status.url` |
|
|
1508
|
-
|
|
1509
|
-
### Session Config example
|
|
1510
|
-
|
|
1511
|
-
```yaml
|
|
1512
|
-
webhooks:
|
|
1513
|
-
slack:
|
|
1514
|
-
url: https://hooks.slack.com/services/REDACTED/REDACTED/REDACTED
|
|
1515
|
-
discord:
|
|
1516
|
-
url: https://discord.com/api/webhooks/REDACTED/REDACTED
|
|
1517
|
-
generic:
|
|
1518
|
-
url: https://example.com/hooks/session-events
|
|
1519
|
-
gitlab-pipeline-status:
|
|
1520
|
-
url: https://gitlab.example.com/hooks/pipeline
|
|
1521
|
-
```
|
|
1522
|
-
|
|
1523
|
-
### Clank Event Bus (events.mjs / on-stop.mjs)
|
|
1583
|
+
## Clank Event Bus (events.mjs / on-stop.mjs)
|
|
1524
1584
|
|
|
1525
1585
|
The internal Clank Event Bus webhook is controlled by two environment variables:
|
|
1526
1586
|
|
|
@@ -1589,24 +1649,23 @@ Set `express-path.enabled: false` when:
|
|
|
1589
1649
|
- `skills/session-plan/SKILL.md` — Express Path Short-Circuit section (1-wave plan emission)
|
|
1590
1650
|
- GitLab issue `#214` (foundation and codification)
|
|
1591
1651
|
|
|
1592
|
-
## Autopilot Multi-Story (#431)
|
|
1593
|
-
|
|
1594
|
-
Opt-in configuration for `autopilot --multi-story` (`scripts/autopilot-multi.mjs`). Controls how parallel story pipelines are isolated when N stories run concurrently. Projects that do not use `--multi-story` leave this block unset and are unaffected.
|
|
1652
|
+
## Autopilot Multi-Story (#431) — removed
|
|
1595
1653
|
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
bg-isolation: worktree # worktree | none (default: worktree)
|
|
1601
|
-
```
|
|
1602
|
-
|
|
1603
|
-
| Field | Type | Default | Description |
|
|
1604
|
-
|-------|------|---------|-------------|
|
|
1605
|
-
| `autopilot.bg-isolation` | `worktree` \| `none` | `worktree` | Isolation mode for concurrent story pipelines. `worktree` (default): each story creates its own git worktree — safe for parallel writes, costs disk space and EnterWorktree latency. `none`: no worktrees; sub-sessions spawn directly in the main working tree — faster for monorepos with heavy build state but requires explicit file-scope deconfliction (see below). |
|
|
1654
|
+
The `autopilot` block and its single field `autopilot.bg-isolation` are **gone**, not
|
|
1655
|
+
deprecated. Their only reader was `scripts/autopilot-multi.mjs`, retired together with <!-- path-check: historical -->
|
|
1656
|
+
`commands/autopilot-multi.md` by the 2026-09-06 360°-Audit (§ 5A: 0 telemetry, 0 fleet
|
|
1657
|
+
invocations in 90 days, no runtime consumer).
|
|
1606
1658
|
|
|
1607
|
-
|
|
1659
|
+
Verified 2026-09-06 at `e4674109`:
|
|
1660
|
+
`rg -n "bg-isolation|bgIsolation|deconflict-paths" scripts hooks tests` returns nothing;
|
|
1661
|
+
`scripts/parse-config.mjs` never parsed an `autopilot` key at all; `scripts/autopilot.mjs`
|
|
1662
|
+
has no `--multi-story` mode. Documenting the field as functional would therefore have been
|
|
1663
|
+
the exact failure the audit found elsewhere — a key an operator can set and no code can
|
|
1664
|
+
read. <!-- path-check: historical -->
|
|
1608
1665
|
|
|
1609
|
-
**
|
|
1666
|
+
**If your Session Config still carries an `autopilot:` block, delete it.** It is inert: no
|
|
1667
|
+
parser reads it, so removing it changes no behaviour. Single-story `/autopilot` is
|
|
1668
|
+
unaffected and takes no Session Config block.
|
|
1610
1669
|
|
|
1611
1670
|
## Wave Reviewers
|
|
1612
1671
|
|
|
@@ -57,6 +57,10 @@ special: "any repo-specific instructions" # freeform — orchestrator reads +
|
|
|
57
57
|
|
|
58
58
|
Read by: `skills/session-start/SKILL.md` (Phase 4.5), `skills/session-plan/SKILL.md`, `skills/wave-executor/wave-loop.md`.
|
|
59
59
|
|
|
60
|
+
**The override key set is open.** `_coerceInteger` (`scripts/lib/config/coercers.mjs`) parses whatever keys stand inside the parentheses, so `agents-per-wave: 6 (deep: 18, ultradeep: 18)` is valid today with no code change — it yields `{"default": 6, "deep": 18, "ultradeep": 18}`.
|
|
61
|
+
|
|
62
|
+
**`session-profile` is NOT a Session Config key — do not add one here.** The wave-shape profile (`ultradeep`) lives in STATE.md frontmatter, written per session by the `/session ultradeep` argument alias, and is absent by default. `parseSessionConfig()` emits no such key, so writing one into a repo's `## Session Config` block is inert prose — the same trap as `session-type:`. Full contract: [`session-config-reference.md` § Session Profile](./session-config-reference.md). The PRD's `ultradeep.max-*` budget block is deliberately NOT implemented and no key of that name is read anywhere (deferred until measured, HR-105).
|
|
63
|
+
|
|
60
64
|
## VCS & Infrastructure
|
|
61
65
|
|
|
62
66
|
```yaml
|
|
@@ -66,7 +70,7 @@ mirror: github # auto-push to mirror after every commit
|
|
|
66
70
|
cross-repos: [related-repo-1] # repos under ~/Projects/ to snapshot at session-start
|
|
67
71
|
pencil: path/to/design.pen # design-code alignment input
|
|
68
72
|
ecosystem-health: true # toggle health-endpoint probes
|
|
69
|
-
health-endpoints:
|
|
73
|
+
health-endpoints: # nested block form — content-scoped parse, see reference doc (#1174)
|
|
70
74
|
- { name: API, url: https://api.example.com/health }
|
|
71
75
|
issue-limit: 50 # max issues fetched at session-start
|
|
72
76
|
stale-branch-days: 7 # branch-age threshold for stale flag
|
|
@@ -274,7 +278,7 @@ memory:
|
|
|
274
278
|
|
|
275
279
|
Agents invoke via `SO_WAVE_AGENT=1 node scripts/memory-propose.mjs …`. The `SO_WAVE_AGENT=1` env-var is set automatically by the wave-executor boilerplate; direct CLI calls without it exit `3` (`rejected-wrong-context`).
|
|
276
280
|
|
|
277
|
-
Read by: `scripts/lib/memory-proposals/{schema,store,collector,sink}.mjs`, `scripts/memory-propose.mjs`, `
|
|
281
|
+
Read by: `scripts/lib/memory-proposals/{schema,store,collector,sink}.mjs`, `scripts/memory-propose.mjs`, `docs/memory-proposal-flow.md`, `hooks/pre-bash-memory-propose-audit.mjs`, `skills/session-end/SKILL.md` Phase 3.6.3.
|
|
278
282
|
|
|
279
283
|
## Auto-Dream Proposal Filter (#566)
|
|
280
284
|
|
|
@@ -381,6 +385,29 @@ Security: `command` and `review` reject shell metacharacters; records failing va
|
|
|
381
385
|
|
|
382
386
|
Read by: `scripts/lib/config/custom-phases.mjs`, `skills/session-end/SKILL.md` Phase 2.5.
|
|
383
387
|
|
|
388
|
+
## Remote Hosts (#1160)
|
|
389
|
+
|
|
390
|
+
Opt-in declaration of ssh-reachable hosts that heavy wave roles may be OFFLOADED to instead of shrinking the wave under local resource pressure. Declaring a host does not enable anything by itself: the wave resource gate only routes a wave to a host when the wave role is offloadable AND the coordinator supplies a readiness witness. Absent/empty ⇒ `[]` ⇒ everything runs locally, exactly as before.
|
|
391
|
+
|
|
392
|
+
```yaml
|
|
393
|
+
remote-hosts:
|
|
394
|
+
- alias: m5 # required, SAFE slug ([A-Za-z0-9._-]); reaches argv as `-H <alias>`
|
|
395
|
+
roles-allowed: [test, ui, perf] # subset of test|ui|perf (default: all three)
|
|
396
|
+
repo-path: ~/Projects/Alice # optional SAFE path (default: null)
|
|
397
|
+
claude-path: ~/.local/bin/claude # optional SAFE path (default: null)
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Field semantics:
|
|
401
|
+
- **`alias`** — the ssh destination as configured on this host. Required; a record without it is dropped with a stderr WARN.
|
|
402
|
+
- **`roles-allowed`** — the `agent-mapping` roles this host accepts. `test`, `ui` and `perf` only — impl, db, security, compliance and docs work never leaves the local host. Unknown entries are filtered with a WARN; a record left with an empty list is dropped.
|
|
403
|
+
- **`repo-path` / `claude-path`** — where the checkout and the `claude` binary live on the remote host, when they differ from the defaults the dispatch adapter assumes.
|
|
404
|
+
|
|
405
|
+
A declared alias is also what an `agent-mapping` value of the form `<role>: ssh:<alias>` is validated against — naming an undeclared host is a parse error, not a runtime surprise.
|
|
406
|
+
|
|
407
|
+
The gate never probes the network. Without a readiness witness no host counts as ready and the decision stays local (fail toward local).
|
|
408
|
+
|
|
409
|
+
Read by: `scripts/lib/config/remote-hosts.mjs`, `scripts/lib/wave-resource-gate.mjs`.
|
|
410
|
+
|
|
384
411
|
## Evolve Extra Sources (#638)
|
|
385
412
|
|
|
386
413
|
Opt-in EXTRA learning sources for `/evolve`. A `domain-regression` measurement (e.g. an eval-learn harness) runs OUT-OF-BAND and writes a sidecar JSON; `/evolve` then READS each declared sidecar and emits a `domain-regression` learning candidate per persistent regression flag. `/evolve` NEVER runs the measurement itself — this is a strict read-only consumption contract. Absent/empty ⇒ `[]` ⇒ no extra sources are read.
|
|
@@ -431,11 +458,11 @@ Read by: `scripts/lib/config/reconcile.mjs` (parser), `skills/session-end/SKILL.
|
|
|
431
458
|
|
|
432
459
|
## Discovery-Validator (PSA-006 Enforcement)
|
|
433
460
|
|
|
434
|
-
Non-blocking `SubagentStop` hook that mechanically enforces PSA-006: distributional claims ("N of M", "100% of", "all N", "no remaining", "every X", "none of") in a subagent's transcript tail must carry an adjacent fenced grep/rg/find transcript. When a claim lacks one, the hook records a `discovery_validator_violation` event in `.orchestrator/metrics/events.jsonl` and emits a stderr WARN. v1 is log + warn only (exit 0 always — never blocks an agent) — a blocking hard-gate is reserved for a future iteration.
|
|
461
|
+
Non-blocking `SubagentStop` hook that mechanically enforces PSA-006: distributional claims ("N of M", "100% of", "all N", "no remaining", "every X", "none of") in a subagent's transcript tail must carry an adjacent fenced grep/rg/find transcript. When a claim lacks one, the hook records a `discovery_validator_violation` event in `.orchestrator/metrics/events.jsonl` and emits a stderr WARN. v1 is log + warn only (exit 0 always — never blocks an agent) — a blocking hard-gate is reserved for a future iteration. OFF by default (opt-in). Issue #567; #690 flip reverted 2026-09-02 after fleet measurement.
|
|
435
462
|
|
|
436
463
|
```yaml
|
|
437
464
|
discovery-validator:
|
|
438
|
-
enabled: true #
|
|
465
|
+
enabled: true # opt-in; hook is off unless this block sets it
|
|
439
466
|
```
|
|
440
467
|
|
|
441
468
|
Read by: `scripts/lib/config/discovery-validator.mjs`, `hooks/post-subagent-discovery-validator.mjs`.
|
|
@@ -589,26 +616,6 @@ express-path:
|
|
|
589
616
|
|
|
590
617
|
Read by: `skills/session-start/phase-8-5-express-path.md`, `skills/session-plan/SKILL.md` (express-path short-circuit).
|
|
591
618
|
|
|
592
|
-
## Webhooks
|
|
593
|
-
|
|
594
|
-
Opt-in webhook notifications. The `scripts/lib/webhook-url.mjs` resolver checks env first (`SO_WEBHOOK_<KIND>_URL`), then this Session Config block. **No personal-domain default** — callers must supply a URL or the resolver throws.
|
|
595
|
-
|
|
596
|
-
```yaml
|
|
597
|
-
webhooks:
|
|
598
|
-
slack:
|
|
599
|
-
url: https://hooks.slack.com/services/REDACTED/REDACTED/REDACTED
|
|
600
|
-
discord:
|
|
601
|
-
url: https://discord.com/api/webhooks/REDACTED/REDACTED
|
|
602
|
-
generic:
|
|
603
|
-
url: https://example.com/hooks/session-events
|
|
604
|
-
gitlab-pipeline-status:
|
|
605
|
-
url: https://gitlab.example.com/hooks/pipeline
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
Measured: `scripts/lib/webhook-url.mjs` (`resolveWebhookUrl`) is the only reader of this `webhooks:` block, and it currently has **zero callers repo-wide** (`grep -rn "webhook-url" scripts/ hooks/` outside itself and one exemption comment in `check-unwired-features.mjs`) — the block is unreachable at HEAD; follow-up issue pending.
|
|
609
|
-
|
|
610
|
-
What actually fires a webhook today is a **separate** mechanism: `scripts/lib/events.mjs`'s `emitEvent()` reads `CLANK_EVENT_SECRET` + `CLANK_EVENT_URL` directly from the environment (never from this Session Config block) and, when both are set, fire-and-forget POSTs every emitted event to the internal Clank Event Bus. Every hook that calls `emitEvent()` — which is most of `hooks/` — participates in that path; none of them reads `webhooks:` here.
|
|
611
|
-
|
|
612
619
|
## Hook Runtime Profile (env-only, not config)
|
|
613
620
|
|
|
614
621
|
`SO_HOOK_PROFILE` and `SO_DISABLED_HOOKS` are environment variables, **not Session Config fields**. They control hook execution at runtime without editing `hooks.json`.
|
|
@@ -659,7 +666,7 @@ That's enough for `/session feature` → `/go` → `/close` to work end-to-end.
|
|
|
659
666
|
|
|
660
667
|
## Full opt-in baseline (copy-paste)
|
|
661
668
|
|
|
662
|
-
Everything turned on for a project that wants the full feature surface (vault, docs, drift checks, env-aware sizing
|
|
669
|
+
Everything turned on for a project that wants the full feature surface (vault, docs, drift checks, env-aware sizing). Trim to taste:
|
|
663
670
|
|
|
664
671
|
```yaml
|
|
665
672
|
## Session Config
|
|
@@ -817,6 +824,13 @@ custom-phases:
|
|
|
817
824
|
mode: hard # warn | hard | off (default: warn)
|
|
818
825
|
review: docs/eval/last-run.md # optional SAFE path read after the command (default: null)
|
|
819
826
|
|
|
827
|
+
# Remote hosts — ssh-reachable offload targets for heavy roles (#1160)
|
|
828
|
+
remote-hosts:
|
|
829
|
+
- alias: m5 # required, SAFE slug; reaches argv as `-H <alias>`
|
|
830
|
+
roles-allowed: [test, ui, perf] # subset of test|ui|perf (default: all three)
|
|
831
|
+
repo-path: ~/Projects/Alice # optional SAFE path (default: null)
|
|
832
|
+
claude-path: ~/.local/bin/claude # optional SAFE path (default: null)
|
|
833
|
+
|
|
820
834
|
# Evolve extra-sources — opt-in EXTRA /evolve learning sources (#638)
|
|
821
835
|
evolve:
|
|
822
836
|
extra-sources:
|
|
@@ -836,7 +850,7 @@ reconcile:
|
|
|
836
850
|
|
|
837
851
|
# Discovery-validator — PSA-006 enforcement (#567)
|
|
838
852
|
discovery-validator:
|
|
839
|
-
enabled: true
|
|
853
|
+
enabled: true # opt-in; hook is off unless this block sets it
|
|
840
854
|
|
|
841
855
|
# Dialectic-Deriver (#506)
|
|
842
856
|
dialectic:
|
|
@@ -939,13 +953,6 @@ config-protection:
|
|
|
939
953
|
mode: warn # warn | strict (strict blocks loosening, exit 2)
|
|
940
954
|
allow-config-weakening: false # per-session bypass (mirrors allow-destructive-ops)
|
|
941
955
|
|
|
942
|
-
# Webhooks (URLs are required when used — no defaults)
|
|
943
|
-
# webhooks:
|
|
944
|
-
# slack:
|
|
945
|
-
# url: https://hooks.slack.com/services/...
|
|
946
|
-
# gitlab-pipeline-status:
|
|
947
|
-
# url: https://gitlab.example.com/hooks/pipeline
|
|
948
|
-
|
|
949
956
|
# Agent mapping
|
|
950
957
|
agent-mapping:
|
|
951
958
|
impl: code-implementer
|
|
@@ -58,29 +58,30 @@ the measurement recipe — see [Reproduce it yourself](#reproduce-it-yourself).
|
|
|
58
58
|
|
|
59
59
|
---
|
|
60
60
|
|
|
61
|
-
## In-repo test suite — the "
|
|
61
|
+
## In-repo test suite — the "15,000+ tests" badge
|
|
62
62
|
|
|
63
63
|
Distinct from the private-corpus figures above, the README **Tests** badge and the
|
|
64
|
-
"
|
|
64
|
+
"15,000+ vitest tests run on every commit" line count **this repository's own test
|
|
65
65
|
suite** — a **public, CI-verifiable** number, not a maintainer-reported aggregate.
|
|
66
66
|
|
|
67
67
|
| Claim | What it counts | How measured | As-of |
|
|
68
68
|
| --- | --- | --- | --- |
|
|
69
|
-
|
|
|
69
|
+
| 15,000+ vitest tests | executed test cases across `tests/**/*.test.mjs` | `npm test` prints the exact runtime total; the static floor is countable without running the suite (below) | 2026-09 |
|
|
70
70
|
|
|
71
71
|
Both numbers reproduce in a fresh checkout:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
find tests -name '*.test.mjs' | wc -l # test files ->
|
|
75
|
-
grep -rohE '\b(it|test)\(' tests | wc -l # static test defs -> ~
|
|
76
|
-
grep -rohE '\b(it|test|describe)\.each\b' tests | wc -l # parameterized blocks ->
|
|
74
|
+
find tests -name '*.test.mjs' | wc -l # test files -> 637
|
|
75
|
+
grep -rohE '\b(it|test)\(' tests | wc -l # static test defs -> ~13,361
|
|
76
|
+
grep -rohE '\b(it|test|describe)\.each\b' tests | wc -l # parameterized blocks -> 440
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
The static `it(` / `test(` count (~
|
|
79
|
+
The static `it(` / `test(` count (~13,361 across 637 files) is a **floor**: the 440
|
|
80
80
|
`it.each` / `test.each` parameterized blocks each expand to multiple executed cases
|
|
81
|
-
at runtime, so the **case count vitest reports on `npm test` is
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
at runtime, so the **case count vitest reports on `npm test` is 15,000+** (measured
|
|
82
|
+
15,869/0 on the local Full Gate at HEAD, 2026-09-02). Unlike the private-corpus
|
|
83
|
+
figures above, this one is fully auditable — run `npm test` in this checkout and
|
|
84
|
+
read vitest's summary line.
|
|
84
85
|
|
|
85
86
|
## Methodology
|
|
86
87
|
|