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
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
# Migrating to Session Orchestrator v4.0.0
|
|
2
|
+
|
|
3
|
+
v4.0.0 removes public surfaces. Nothing about the core loop changes — `/session`, `/go`,
|
|
4
|
+
`/close`, `/plan`, `/discovery`, `/evolve`, `/bootstrap` and the rest of the 25 commands
|
|
5
|
+
behave exactly as in 3.x — but five skills, three commands and eight top-level scripts are
|
|
6
|
+
gone, two files leave `agents/`, and two telemetry names are deprecated on a dated clock.
|
|
7
|
+
This guide is for someone running 3.x today: which invocations break, what replaces them,
|
|
8
|
+
what happens to your state, and how to go back.
|
|
9
|
+
|
|
10
|
+
The removals follow a two-signal rule measured over a 90-day window — **0 telemetry ∧ 0
|
|
11
|
+
fleet invocation ∧ no runtime consumer** — not a judgement call. Evidence:
|
|
12
|
+
[`docs/audits/2026-09-06-360-audit.md`](./audits/2026-09-06-360-audit.md), per-agent raw
|
|
13
|
+
reports under [`audits/2026-09-06-360-audit/w1/`](./audits/2026-09-06-360-audit/w1/). Full
|
|
14
|
+
change list: [CHANGELOG.md](../CHANGELOG.md).
|
|
15
|
+
|
|
16
|
+
## 1. What Changes
|
|
17
|
+
|
|
18
|
+
| Area | 3.x | 4.0.0 |
|
|
19
|
+
|------|-----|-------|
|
|
20
|
+
| Skills (`SKILL.md` files) | 49 | 43 — 5 removed, 1 merged into `architecture` |
|
|
21
|
+
| Commands | 28 | 25 — `/contract-version-bump`, `/journey-audit`, `/autopilot-multi` removed |
|
|
22
|
+
| Top-level scripts | 8 more than today | 8 removed (0 runtime callers each) |
|
|
23
|
+
| `agents/*.md` | 16 (2 of them not agents) | 14 — the two non-agents moved to `docs/` |
|
|
24
|
+
| `.claude/rules/` | 61 files (43 generated) | 26 files (43 generated → 8 thematic) |
|
|
25
|
+
| Turn-stop event | `orchestrator.session.stopped` | `orchestrator.turn.stopped` (both emitted until 2027-03-06) |
|
|
26
|
+
| Telemetry field | `fleet` | `fleet_self_declared` (both sent until 2027-03-06) |
|
|
27
|
+
| Cross-harness manifest | none | root `AGENTS.md` + root `plugin.json` + `.agents/skills/` |
|
|
28
|
+
| Session shapes | `housekeeping` / `feature` / `deep` | unchanged, plus the `ultradeep` PROFILE over `deep` |
|
|
29
|
+
| Runtime | Node 24+, npm | unchanged |
|
|
30
|
+
|
|
31
|
+
### 1a. Invocations that break
|
|
32
|
+
|
|
33
|
+
| You invoke | Status in 4.0.0 | What to do instead |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `/contract-version-bump` | **removed** | No replacement. Bump the contract's version literal by hand and note it in your CHANGELOG. |
|
|
36
|
+
| `/journey-audit` | **removed** | No replacement. It required a journey manifest; zero existed fleet-wide, so it was never runnable. |
|
|
37
|
+
| `/autopilot-multi` | **removed** | No replacement. `/autopilot` (single-story) is unaffected and stays. |
|
|
38
|
+
| the `daily` skill | **removed** | No replacement. A recurring daily note is a scheduled task / cloud Routine, not a session skill — see `.claude/rules/loop-and-monitor.md` § LM-004. |
|
|
39
|
+
| the `skill-creator` skill | **removed** | Anthropic's official `skill-creator` plugin, or `claude plugin init`. |
|
|
40
|
+
| the `ubiquitous-language` skill | **removed** | No replacement. |
|
|
41
|
+
| the `domain-model` skill | **merged** | `/architecture` — the material now lives at `skills/architecture/references/domain-model.md` (with `ADR-FORMAT.md` and `CONTEXT-FORMAT.md` beside it). |
|
|
42
|
+
| `node scripts/autopilot-multi.mjs` | **removed** | No replacement. | <!-- path-check: historical -->
|
|
43
|
+
| `node scripts/backfill-learnings.mjs`, `…-expires.mjs` | **removed** | No replacement — one-shot ledger repairs, already applied. | <!-- path-check: historical -->
|
|
44
|
+
| `node scripts/migrate-learnings-jsonl.mjs`, `migrate-subagents-jsonl.mjs` | **removed** | No replacement — one-shot format migrations; the target format has been canonical for several releases. | <!-- path-check: historical -->
|
|
45
|
+
| `node scripts/fleet-instruction-scan.mjs`, `lifecycle-sim-v6.mjs`, `upload-social-preview.mjs` | **removed** | No replacement. | <!-- path-check: historical -->
|
|
46
|
+
| dispatching `AGENTS.md` as an agent | **removed as a dispatch target** | It was never an agent — it is the authoring spec, now [`docs/agent-authoring.md`](./agent-authoring.md). Read it; do not dispatch it. |
|
|
47
|
+
| dispatching `memory-proposal-collector` as an agent | **removed as a dispatch target** | Now [`docs/memory-proposal-flow.md`](./memory-proposal-flow.md). |
|
|
48
|
+
| citing `skills/_shared/model-selection.md` | **removed** | No replacement; it had zero consumers. |
|
|
49
|
+
| Session Config `autopilot.bg-isolation` | **removed** | No replacement — delete the `autopilot:` block from your `CLAUDE.md`/`AGENTS.md`, it was the block's only field and is now inert (`scripts/parse-config.mjs` never parsed it). |
|
|
50
|
+
| Session Config `webhooks.<kind>.url` | **removed** (pre-4.0.0, `ce6a28aa`) | No replacement — `scripts/lib/webhook-url.mjs` had zero callers. The still-live Clank Event Bus webhook (`CLANK_EVENT_SECRET`/`CLANK_EVENT_URL`) is unrelated and unaffected. | <!-- path-check: historical -->
|
|
51
|
+
|
|
52
|
+
### 1b. Telemetry consumers (dated deprecations, nothing breaks yet)
|
|
53
|
+
|
|
54
|
+
If you read `.orchestrator/metrics/events.jsonl` or the ingest server, two names change and
|
|
55
|
+
**both old and new are emitted for one generation**, so no reader breaks on upgrade day:
|
|
56
|
+
|
|
57
|
+
- **`orchestrator.session.stopped` → `orchestrator.turn.stopped`.** The emitter always fired
|
|
58
|
+
per assistant TURN, not per session — measured 15,538 records against 2,016 distinct
|
|
59
|
+
`orchestrator.session.started` ids over 90 days, i.e. 7.7 per session, 184 for one id. Any
|
|
60
|
+
"sessions stopped" count you derived from it is a **turn count**, wrong by that factor. Both
|
|
61
|
+
names carry an identical payload from the same object, so they cannot disagree; every record
|
|
62
|
+
under the legacy name additionally carries `deprecated: true`. **Switch the name you match
|
|
63
|
+
on and change nothing else. Removal of the legacy name: 2027-03-06.** To count sessions,
|
|
64
|
+
count `session.started` ids; to count closes, count `sessions.jsonl` records with
|
|
65
|
+
`status: completed`. Unaffected: `orchestrator.agent.stopped`, whose per-agent cardinality
|
|
66
|
+
was always correct.
|
|
67
|
+
- **`fleet` → `fleet_self_declared`.** The old name claimed something the client cannot know.
|
|
68
|
+
The new name says what it is, and the authoritative classification is now server-side (an
|
|
69
|
+
anon-id allowlist). `fleet` keeps being sent with an identical value for the whole
|
|
70
|
+
generation so an existing column stays comparable. **Removal: 2027-03-06.** Contract:
|
|
71
|
+
[`docs/telemetry.md`](./telemetry.md).
|
|
72
|
+
|
|
73
|
+
## 2. Prerequisites
|
|
74
|
+
|
|
75
|
+
- **Node.js 24 or later** — unchanged from v3. `node --version`.
|
|
76
|
+
- **Git** — any recent version.
|
|
77
|
+
- **`npm install` after updating.** Still mandatory, and now slightly less punishing: in 3.x,
|
|
78
|
+
4 of 27 hooks died at module-load with `ERR_MODULE_NOT_FOUND: js-yaml` when `node_modules`
|
|
79
|
+
was absent. In 4.0.0 all 27 hooks exit 0 without `node_modules` — but they run degraded, so
|
|
80
|
+
install anyway.
|
|
81
|
+
- **`glab` / `gh`** — optional, unchanged.
|
|
82
|
+
|
|
83
|
+
Nothing new is required. There is no data migration, no schema bump, and no config key you
|
|
84
|
+
must add.
|
|
85
|
+
|
|
86
|
+
## 3. Upgrade Steps
|
|
87
|
+
|
|
88
|
+
### 3a. Claude Code
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# 1. Update the plugin — run this INSIDE Claude Code, not in a shell:
|
|
92
|
+
# /plugin update session-orchestrator@kanevry
|
|
93
|
+
# A marketplace-installed plugin lives in a managed cache, not a git checkout,
|
|
94
|
+
# so `git pull` does not apply to it.
|
|
95
|
+
|
|
96
|
+
# 2. Install Node dependencies in the cache copy:
|
|
97
|
+
SO_DIR="$(dirname "$(find ~/.claude/plugins/cache -path '*session-orchestrator*' -name package.json 2>/dev/null | head -1)")"
|
|
98
|
+
cd "$SO_DIR" && npm install
|
|
99
|
+
|
|
100
|
+
# 3. Restart Claude Code so hooks.json is re-read.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
From 4.0.0 on, session-start compares the version that is **running** against the npm
|
|
104
|
+
`dist-tags.latest` and prints a one-line banner when they differ. It fails silent: offline, a
|
|
105
|
+
non-2xx response, malformed JSON or a timeout each produce no statement — never a false "you
|
|
106
|
+
are up to date".
|
|
107
|
+
|
|
108
|
+
### 3b. Codex CLI
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
codex plugin marketplace upgrade kanevry # omit the name to refresh all marketplaces
|
|
112
|
+
codex plugin add session-orchestrator@kanevry
|
|
113
|
+
codex plugin list --available --json
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For the maintainer / local-clone path instead:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cd ~/Projects/session-orchestrator
|
|
120
|
+
git pull && npm install
|
|
121
|
+
node scripts/codex-install.mjs
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
New in 4.0.0 and relevant here: this repository now ships a **root `AGENTS.md`**
|
|
125
|
+
(byte-identical to `CLAUDE.md`). Before, a Codex-family harness resolving project
|
|
126
|
+
instructions from `AGENTS.md` found nothing in this repo. If you keep your own
|
|
127
|
+
`AGENTS.md`, nothing changes for you.
|
|
128
|
+
|
|
129
|
+
### 3c. Cursor IDE
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cd ~/Projects/session-orchestrator
|
|
133
|
+
git pull && npm install
|
|
134
|
+
node scripts/cursor-install.mjs /path/to/your-project # links NEW commands/rules/skills only
|
|
135
|
+
# Restart Cursor
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**The installer adds new files; it never overwrites or removes an existing one.** `linkPath()`
|
|
139
|
+
skips whenever the destination already exists as a symlink or a file
|
|
140
|
+
(`scripts/cursor-install.mjs:69-73`), and the `hooks.json` writer skips outright when one is
|
|
141
|
+
already there (`:139-140`). Two consequences on this upgrade: the malformed `argument-hint` fix
|
|
142
|
+
(the 3.x generator wrote it into 24 of 28 command files, GH#54) reaches you for free through
|
|
143
|
+
your existing symlinks the moment `git pull` updates this checkout — no re-run needed for that.
|
|
144
|
+
But the three retired commands do **not** disappear from `.cursor/commands/` on their own, and a
|
|
145
|
+
`hooks.json` written before 4.0.0 is never synchronised with a new hook event automatically.
|
|
146
|
+
Both need the manual step in § 5 ("Cursor still shows the removed commands") below.
|
|
147
|
+
|
|
148
|
+
A root `plugin.json` following the [agent-plugins.org](https://agent-plugins.org) 1.0.0
|
|
149
|
+
schema now ships as well, for Cursor's plugin system.
|
|
150
|
+
|
|
151
|
+
### 3d. Pi
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pi install npm:session-orchestrator
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Or against a local checkout:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cd ~/Projects/session-orchestrator
|
|
161
|
+
git pull && npm install
|
|
162
|
+
node scripts/pi-install.mjs /path/to/your-project --settings-only
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`pi/prompts/` drops from 28 to 25 files, matching `commands/`.
|
|
166
|
+
|
|
167
|
+
### 3e. Verify
|
|
168
|
+
|
|
169
|
+
Run `/session housekeeping` in any configured repo. You should see the session-start banner;
|
|
170
|
+
`/contract-version-bump`, `/journey-audit` and `/autopilot-multi` should no longer be offered.
|
|
171
|
+
Then:
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
node scripts/parse-config.mjs --json # now works — in 3.x this failed with "File not found: --json"
|
|
175
|
+
node scripts/validate-plugin.mjs
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 4. What Stays the Same
|
|
179
|
+
|
|
180
|
+
**Your state is untouched. There is no migration step and no format change.**
|
|
181
|
+
|
|
182
|
+
- **`.orchestrator/` in every repo** — `metrics/sessions.jsonl`, `metrics/learnings.jsonl`,
|
|
183
|
+
`metrics/events.jsonl`, `current-session.json`, `session.lock`, `state.lock`, filescopes and
|
|
184
|
+
wave-scope manifests are all read-write compatible in both directions. Nothing is rewritten
|
|
185
|
+
on upgrade, and nothing 4.0.0 writes is unreadable by 3.24.0.
|
|
186
|
+
- **`STATE.md`** — same frontmatter schema. 4.0.0 adds ONE optional scalar,
|
|
187
|
+
`session-profile`, and absent is not empty: a STATE.md without it behaves exactly as before.
|
|
188
|
+
A 3.x build reading a 4.0.0 STATE.md simply ignores the extra key.
|
|
189
|
+
- **Session Config in `CLAUDE.md` / `AGENTS.md` / Cursor rules** — no key you are likely using
|
|
190
|
+
is renamed or given a new default. Two keys ARE removed — `autopilot.bg-isolation` and
|
|
191
|
+
`webhooks.<kind>.url` — see § 1a above; everything else you configured in 3.x is still
|
|
192
|
+
correct as-is.
|
|
193
|
+
- **Session memory** (`~/.claude/projects/<project>/memory/`) — untouched.
|
|
194
|
+
- **`session-type`** — still the closed set `housekeeping` / `feature` / `deep`. `ultradeep`
|
|
195
|
+
is an argument ALIAS that resolves to `session-type: deep` plus
|
|
196
|
+
`session-profile: ultradeep`; it is deliberately not a fourth type, because a fourth member
|
|
197
|
+
would degrade silently in the telemetry mapper and the close-backfiller.
|
|
198
|
+
- **The whole core loop** — `/session`, `/go`, `/close`, `/plan`, `/discovery`, `/evolve`,
|
|
199
|
+
`/bootstrap`, `/debug`, `/autopilot` and the other remaining commands take the same
|
|
200
|
+
arguments and run the same flow.
|
|
201
|
+
- **VCS integration** — `glab` / `gh` commands, label taxonomy, issue and MR templates.
|
|
202
|
+
|
|
203
|
+
## 5. Known Issues & Workarounds
|
|
204
|
+
|
|
205
|
+
### Your CLAUDE.md cites a removed skill
|
|
206
|
+
|
|
207
|
+
**Nothing breaks at runtime.** A citation in a consumer repo's `CLAUDE.md` (or `AGENTS.md`) to
|
|
208
|
+
`daily`, `skill-creator`, `ubiquitous-language`, `contract-version-bump`, `journey-audit`,
|
|
209
|
+
`domain-model` or `skills/_shared/model-selection.md` is prose. No loader resolves it, no hook
|
|
210
|
+
reads it, and the session starts normally.
|
|
211
|
+
|
|
212
|
+
**But `claude-md-drift-check` may flag it** as a dangling citation, and if you run it with
|
|
213
|
+
`enforcement: strict` that finding is an error rather than a warning. Two ways out, both fine:
|
|
214
|
+
|
|
215
|
+
1. Delete or rewrite the citation. `domain-model` becomes
|
|
216
|
+
`skills/architecture/references/domain-model.md`; the other five have no successor, so the
|
|
217
|
+
sentence usually goes away with the skill.
|
|
218
|
+
2. Leave it and accept the warning until your next docs pass. It is a documentation-parity
|
|
219
|
+
finding, not a functional one.
|
|
220
|
+
|
|
221
|
+
Same story for a rule file or ADR that names one of the removed scripts.
|
|
222
|
+
|
|
223
|
+
### A wrapper script or Routine calls a removed top-level script
|
|
224
|
+
|
|
225
|
+
`node scripts/<name>.mjs` on any of the eight removed scripts now exits with a Node
|
|
226
|
+
`ERR_MODULE_NOT_FOUND`-class failure — a loud error, not a silent no-op. If a cron job,
|
|
227
|
+
Routine or CI step calls one, delete that step: the two `migrate-*` scripts had already
|
|
228
|
+
completed their one-shot migration, and the two `backfill-learnings*` scripts their one-shot
|
|
229
|
+
repair, before this release.
|
|
230
|
+
|
|
231
|
+
### A dashboard suddenly reports far fewer "sessions stopped"
|
|
232
|
+
|
|
233
|
+
Expected, and it was wrong before, not now. See § 1b — you were counting turns. Match on
|
|
234
|
+
`orchestrator.turn.stopped`, or better, count `session.started` ids for sessions and
|
|
235
|
+
`sessions.jsonl` records with `status: completed` for closes.
|
|
236
|
+
|
|
237
|
+
### `npm install` fails with `ERESOLVE` or peer-dep warnings
|
|
238
|
+
|
|
239
|
+
Use Node 24 or later, matching `engines.node: ">=24.0.0"`. If it persists:
|
|
240
|
+
`npm install --legacy-peer-deps`.
|
|
241
|
+
|
|
242
|
+
### Hooks silently no-op after the update
|
|
243
|
+
|
|
244
|
+
Node must be on `PATH` inside the **editor** process, not only in your terminal. Verify from
|
|
245
|
+
inside Claude Code with `!node --version`. This is unchanged from v3.
|
|
246
|
+
|
|
247
|
+
### Cursor still shows the removed commands
|
|
248
|
+
|
|
249
|
+
Re-running the installer does **not** fix this: `linkPath()` skips any destination that already
|
|
250
|
+
exists (`scripts/cursor-install.mjs:69-73`), including a stale symlink pointing at a command
|
|
251
|
+
that no longer exists in this repo. Remove only the three dead **symlinks** from your project —
|
|
252
|
+
never an unconditional `rm -f`, which would just as happily delete a regular file, including a
|
|
253
|
+
command you wrote yourself under one of these three names (the installer itself never overwrites
|
|
254
|
+
or deletes a regular file; this recipe must not either):
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
for f in autopilot-multi contract-version-bump journey-audit; do
|
|
258
|
+
p=/path/to/your-project/.cursor/commands/$f.md
|
|
259
|
+
[ -L "$p" ] && rm "$p" # -L: true only for a symlink, so a real file with this name survives
|
|
260
|
+
done
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Then restart Cursor. Same story for `.cursor/hooks.json`: the installer skips it outright once
|
|
264
|
+
it exists (`:139-140`), so a `hooks.json` written before 4.0.0 is never re-synced with a new hook
|
|
265
|
+
event automatically — re-check it by hand (diff it against a fresh `node scripts/cursor-install.mjs`
|
|
266
|
+
run in an empty scratch directory if you suspect drift).
|
|
267
|
+
|
|
268
|
+
## 6. Rollback
|
|
269
|
+
|
|
270
|
+
4.0.0 removes surfaces; it does not migrate data. **Rolling back is therefore a plain version
|
|
271
|
+
switch — no state has to be converted, and nothing you wrote under 4.0.0 becomes unreadable.**
|
|
272
|
+
|
|
273
|
+
**Claude Code / plugin cache.** A marketplace install tracks the marketplace's current
|
|
274
|
+
version; this repo documents no version-pin flag for `/plugin install`, so do not guess one.
|
|
275
|
+
Roll back by pointing Claude Code at a local clone parked on the old tag:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
git clone https://github.com/Kanevry/session-orchestrator ~/so-3.24.0
|
|
279
|
+
cd ~/so-3.24.0 && git checkout v3.24.0 && npm install
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Then, inside Claude Code, remove the marketplace-installed copy and add the clone as the
|
|
283
|
+
plugin source (`/plugin marketplace add ~/so-3.24.0`, then install from it) and restart the
|
|
284
|
+
editor. If you are unsure of the exact `/plugin` subcommands on your build, run `/plugin`
|
|
285
|
+
with no arguments — it lists them.
|
|
286
|
+
|
|
287
|
+
**Local checkout (Codex / Cursor / Pi / maintainer):**
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
cd /path/to/session-orchestrator
|
|
291
|
+
git fetch --tags
|
|
292
|
+
git checkout v3.24.0
|
|
293
|
+
npm install # the 3.24.0 lockfile, not the 4.0.0 one
|
|
294
|
+
node scripts/codex-install.mjs # Codex — no target-project argument
|
|
295
|
+
node scripts/cursor-install.mjs /path/to/your-project # Cursor — pass YOUR project, not this checkout
|
|
296
|
+
node scripts/pi-install.mjs /path/to/your-project --settings-only # Pi — same argument contract
|
|
297
|
+
# Restart your editor
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Run only the line for your platform. `cursor-install.mjs` and `pi-install.mjs` both default their
|
|
301
|
+
target to `process.cwd()` when no argument is given (`scripts/cursor-install.mjs:24-51`) — omit
|
|
302
|
+
the project path here and the installer links into `/path/to/session-orchestrator` itself, not
|
|
303
|
+
into your project.
|
|
304
|
+
|
|
305
|
+
**npm consumers:** `npm install session-orchestrator@3.24.0`.
|
|
306
|
+
|
|
307
|
+
What you get back, and what you do not:
|
|
308
|
+
|
|
309
|
+
- **Your state survives in both directions.** `sessions.jsonl`, `learnings.jsonl`,
|
|
310
|
+
`events.jsonl` and `STATE.md` written by 4.0.0 are readable by 3.24.0. The one 4.0.0
|
|
311
|
+
addition to STATE.md, `session-profile`, is an unknown key to 3.24.0 and is ignored, not
|
|
312
|
+
rejected.
|
|
313
|
+
- **`orchestrator.turn.stopped` records written under 4.0.0 stay in your `events.jsonl` after
|
|
314
|
+
a rollback.** 3.24.0 does not know the name and will not count them; the
|
|
315
|
+
`orchestrator.session.stopped` twin of every one of those records is right beside it, so no
|
|
316
|
+
data is lost — only a 3.x reader sees each turn once instead of twice.
|
|
317
|
+
- **The removed skills, commands and scripts come back with the checkout.** They were deleted
|
|
318
|
+
from the repository, not from your disk history.
|
|
319
|
+
- **What does NOT roll back automatically** is anything an installer wrote into YOUR project:
|
|
320
|
+
`.cursor/commands/`, `.cursor/hooks.json`, Pi settings. Both `cursor-install.mjs` and
|
|
321
|
+
`pi-install.mjs` skip any destination that already exists — a symlink or a file
|
|
322
|
+
(`scripts/cursor-install.mjs:69-73`; the `hooks.json` writer at `:139-140`) — so re-running
|
|
323
|
+
the installer from the 3.24.0 checkout only **adds** files missing from your project. It does
|
|
324
|
+
not restore a symlink you removed yourself, and it does not resync an existing `hooks.json` or
|
|
325
|
+
Pi settings file. To get those back: remove the stale file first (§ "Cursor still shows the
|
|
326
|
+
removed commands" has a safe, symlink-only removal recipe), then re-run the installer with
|
|
327
|
+
your project path, as shown above.
|
|
328
|
+
|
|
329
|
+
If 4.0.0 blocks you, please open an issue describing the blocker before rolling back — a
|
|
330
|
+
removal we got wrong is fixable in a 4.0.x patch.
|
|
331
|
+
|
|
332
|
+
## 7. Support
|
|
333
|
+
|
|
334
|
+
- **GitHub:** [Kanevry/session-orchestrator/issues](https://github.com/Kanevry/session-orchestrator/issues)
|
|
335
|
+
— preferred for bugs and feature requests.
|
|
336
|
+
- **Homepage:** [session-orchestrator.com](https://session-orchestrator.com)
|
|
337
|
+
|
|
338
|
+
When filing a bug, include `node --version`, your OS and arch, the harness (Claude Code /
|
|
339
|
+
Codex CLI / Cursor / Pi), the plugin version actually running (the session-start banner prints
|
|
340
|
+
it), and a minimal reproduction. For hook failures, attach the relevant entries from
|
|
341
|
+
`.orchestrator/metrics/events.jsonl`.
|
package/docs/pi-setup.md
CHANGED
|
@@ -18,7 +18,12 @@ pi install npm:session-orchestrator
|
|
|
18
18
|
|
|
19
19
|
This is the primary install path — the package is published to npm (since v3.16.0, 2026-07-19) and carries the `pi-package` keyword for the [Pi packages gallery](https://pi.dev/packages) index; no local checkout required. The dev-fallback options below remain available for working against a local checkout.
|
|
20
20
|
|
|
21
|
-
The short git form
|
|
21
|
+
The short git form for Pi packages is `pi install git:github.com/user/repo@ref`. Two separate questions were previously collapsed into one "unverified" verdict; they are split here because only one of them is still open (measured 2026-09-06, W1 d10):
|
|
22
|
+
|
|
23
|
+
- **Is the syntax real?** Yes — the `git:` short form, including the `@ref` suffix, is documented upstream. The 2026-08-28 line that called the *syntax* unverified was stale and is corrected here.
|
|
24
|
+
- **Does it work against THIS repo?** Still unverified. The `pi` CLI is not installed on the verifying host (`which pi` → not found), so no install attempt has been made against `github.com/Kanevry/session-orchestrator`. The npm form above remains the only *measured* install path.
|
|
25
|
+
|
|
26
|
+
Do not elevate the `git:` form to README as a recommended install line until it has been run against this repo and the result dated. Citing it as valid Pi syntax is fine; citing it as a verified install path for this package is not.
|
|
22
27
|
|
|
23
28
|
### Option 2: Project-local registration (dev fallback)
|
|
24
29
|
|
|
@@ -114,7 +114,7 @@ Under `scripts/lib/`. Each module is a focused concern and exports only what cal
|
|
|
114
114
|
| Module | 1-liner | Key exports |
|
|
115
115
|
|--------|---------|-------------|
|
|
116
116
|
| **`io.mjs`** | Hook stdin/stdout helpers matching the Claude Code contract | `readStdin`, `emitAllow`, `emitDeny`, `emitWarn`, `emitSystemMessage` |
|
|
117
|
-
| **`platform.mjs`** | OS + editor detection | `SO_OS`, `SO_IS_WINDOWS`, `SO_IS_WSL`, `SO_PATH_SEP`, `
|
|
117
|
+
| **`platform.mjs`** | OS + editor detection | `SO_OS`, `SO_IS_WINDOWS`, `SO_IS_WSL`, `SO_PATH_SEP`, `getStateDir()`, `detectPlatform()` |
|
|
118
118
|
| **`path-utils.mjs`** | CWE-23-safe path helpers (null-byte rejection, UNC block, cross-drive escape, locale-stable casing) | `normalizeForMatching`, `isWithin`, `CWE_23_ATTACK_PATTERNS` |
|
|
119
119
|
| **`config.mjs`** | CRLF-tolerant Session Config parser (originally parse-config.sh in v2; byte-exact parity preserved) | `parseSessionConfig`, `readConfigFile`, `getConfigValue` |
|
|
120
120
|
| **`config-schema.mjs`** | Plain-JS validator; validates the 7 mandatory Session Config fields (3 required strings + 4 typed fields) | `validateSessionConfig` (internal `REQUIRED_STRING_FIELDS` constant covers the 3 required strings — not exported) |
|
package/docs/rule-authoring.md
CHANGED
|
@@ -194,32 +194,33 @@ The `learning-key` field above links a rule to a learning record, but does not b
|
|
|
194
194
|
|
|
195
195
|
### The type-taxonomy + per-type TTL registry (single source of truth)
|
|
196
196
|
|
|
197
|
-
`LEARNING_TYPE_REGISTRY` in [`scripts/lib/learnings/schema.mjs`](../scripts/lib/learnings/schema.mjs) (~
|
|
197
|
+
`LEARNING_TYPE_REGISTRY` in [`scripts/lib/learnings/schema.mjs`](../scripts/lib/learnings/schema.mjs) (~L92–127) is the **single source of truth** for every learning `type`'s TTL policy and its three cross-module capability flags (`agentProposable`, `ruleConvertible`, `hostScoped` — four axes in total, counting `ttlDays`). Before this registry existed (pre-#733), three modules independently hand-maintained overlapping type lists that drifted out of sync. `LEARNING_TTL_DAYS` (this file), `PROPOSAL_TYPES` (`scripts/lib/memory-proposals/schema.mjs`), and `CONVERT_TYPES` (`scripts/lib/reconcile/eligibility.mjs`) are now all **derived** from this one registry — no hand-maintained duplicate lists remain.
|
|
198
198
|
|
|
199
199
|
Transcribed verbatim from `LEARNING_TYPE_REGISTRY` (16 types):
|
|
200
200
|
|
|
201
|
-
| Type | ttlDays | agentProposable | ruleConvertible |
|
|
202
|
-
|
|
203
|
-
| `mode-selector-accuracy` | 30 | true | false |
|
|
204
|
-
| `hardware-pattern` | 60 | true | false |
|
|
205
|
-
| `fragile-file` | 45 | true | true |
|
|
206
|
-
| `effective-sizing` | 45 | true | false |
|
|
207
|
-
| `recurring-issue` | 45 | true | true |
|
|
208
|
-
| `workflow-pattern` | 90 | true | true |
|
|
209
|
-
| `proven-pattern` | 90 | true | true |
|
|
210
|
-
| `anti-pattern` | 90 | true | true |
|
|
211
|
-
| `autopilot-effectiveness` | 90 | true | false |
|
|
212
|
-
| `autonomy-verdict` | 90 | false | false |
|
|
213
|
-
| `domain-regression` | 60 | true | false |
|
|
214
|
-
| `convention` | 90 | true | true |
|
|
215
|
-
| `architecture-pattern` | 90 | true | true |
|
|
216
|
-
| `design-pattern` | 90 | true | true |
|
|
217
|
-
| `fragile-pattern` | 45 | false | true |
|
|
218
|
-
| `stagnation-class-frequency` | 60 | false | true |
|
|
201
|
+
| Type | ttlDays | agentProposable | ruleConvertible | hostScoped |
|
|
202
|
+
|------|---------|------------------|------------------|------------|
|
|
203
|
+
| `mode-selector-accuracy` | 30 | true | false | false |
|
|
204
|
+
| `hardware-pattern` | 60 | true | false | true |
|
|
205
|
+
| `fragile-file` | 45 | true | true | false |
|
|
206
|
+
| `effective-sizing` | 45 | true | false | false |
|
|
207
|
+
| `recurring-issue` | 45 | true | true | false |
|
|
208
|
+
| `workflow-pattern` | 90 | true | true | false |
|
|
209
|
+
| `proven-pattern` | 90 | true | true | false |
|
|
210
|
+
| `anti-pattern` | 90 | true | true | false |
|
|
211
|
+
| `autopilot-effectiveness` | 90 | true | false | false |
|
|
212
|
+
| `autonomy-verdict` | 90 | false | false | false |
|
|
213
|
+
| `domain-regression` | 60 | true | false | false |
|
|
214
|
+
| `convention` | 90 | true | true | false |
|
|
215
|
+
| `architecture-pattern` | 90 | true | true | false |
|
|
216
|
+
| `design-pattern` | 90 | true | true | false |
|
|
217
|
+
| `fragile-pattern` | 45 | false | true | false |
|
|
218
|
+
| `stagnation-class-frequency` | 60 | false | true | false |
|
|
219
219
|
|
|
220
220
|
Capability axes:
|
|
221
221
|
- **`agentProposable`** — the type may appear in `PROPOSAL_TYPES` (a wave-agent may `memory.propose()` this type). `autonomy-verdict`, `fragile-pattern`, and `stagnation-class-frequency` are `false` — these are analyzer-synthesized classes, not agent-observed, so they are never agent-proposable.
|
|
222
222
|
- **`ruleConvertible`** — the type may appear in `CONVERT_TYPES` (the FA2 reconciliation engine may convert a learning of this type into a conditional `.claude/rules/*.md` proposal). `fragile-file`, `recurring-issue`, `anti-pattern`, `convention`, `architecture-pattern`, `design-pattern`, `fragile-pattern`, `stagnation-class-frequency`, `workflow-pattern`, and `proven-pattern` are the ten `ruleConvertible: true` types (issue #900 flipped the last two from `false` — the real corpus census showed a large volume of these records carrying usable `file_paths` scope that were structurally unconvertible before the flip).
|
|
223
|
+
- **`hostScoped`** — `reconcile/emitter.mjs` may copy the record's `host_class` through as the emitted rule's `host-class` activation axis (issue #1090; derived set: that module's `HOST_SPECIFIC_TYPES`). `hardware-pattern` is the ONLY `true` type today — its content IS the chip/OS, so gating the emitted rule by host-class is faithful rather than an accidental one-machine restriction. For every other type `host_class` merely records the machine the learning was authored on and must never gate the rule.
|
|
223
224
|
|
|
224
225
|
### Type aliasing (issue #900)
|
|
225
226
|
|
|
@@ -257,6 +258,71 @@ Field-by-field:
|
|
|
257
258
|
|
|
258
259
|
**Provenance is session-slug based, not issue-number based.** The only session-identity field the schema carries is `source_session` (a kebab-slug like `main-2026-07-03-session-1`) — there is currently no issue-number provenance field on a learning record or a generated rule. Adding issue-number provenance (linking a rule back to the GitHub/GitLab issue that motivated the learning) would require a schema addition to `scripts/lib/learnings/schema.mjs` — out of scope for this documentation pass.
|
|
259
260
|
|
|
261
|
+
### Consolidated rules: N provenance pairs in ONE file (the merge contract)
|
|
262
|
+
|
|
263
|
+
A rule file may ABSORB several generated rules. This is the supported way to
|
|
264
|
+
stop `.claude/rules/` growing one 2.6 kB file per learning — measured
|
|
265
|
+
2026-09-06 @ `e4674109`: 43 generated files / 112,443 B, 46.2 % of it pure
|
|
266
|
+
frontmatter + provenance overhead, consolidated to 8 thematic files (33
|
|
267
|
+
absorbed, 10 dropped). Four rules make a merge safe, and skipping any one of
|
|
268
|
+
them silently loses a learning or regenerates it:
|
|
269
|
+
|
|
270
|
+
1. **Frontmatter `learning-key:` is a SCALAR — so N−1 markers live in the
|
|
271
|
+
body.** `engine.mjs` reads BOTH forms: the frontmatter
|
|
272
|
+
`FRONTMATTER_LEARNING_KEY_RE` (`^learning-key: <value>`) and the body
|
|
273
|
+
bullets `BODY_LEARNING_KEY_RE` / `BODY_LEARNING_ID_RE`
|
|
274
|
+
(`` - learning-key: `<value>` `` / `` - learning-id: `<value>` ``). A merged
|
|
275
|
+
file therefore carries **one `- learning-key:` + `- learning-id:` bullet
|
|
276
|
+
PAIR per absorbed learning** in its `## Provenance` section, and may omit
|
|
277
|
+
the frontmatter scalar entirely. Removing a pair does not "tidy up" the
|
|
278
|
+
file — it makes that learning look unmaterialized, and the next
|
|
279
|
+
`/reconcile` regenerates it as a standalone rule.
|
|
280
|
+
|
|
281
|
+
2. **`expires-at` is the EARLIEST of the absorbed dates.** A merged file must
|
|
282
|
+
not outlive its shortest-lived content: one date now covers several
|
|
283
|
+
learnings, so it must expire when the FIRST of them is due for review, not
|
|
284
|
+
the last. (Taking the latest would silently extend every other learning's
|
|
285
|
+
TTL past what its type registry granted it.) State the rule in the file
|
|
286
|
+
itself, so the next editor does not "fix" it upward.
|
|
287
|
+
|
|
288
|
+
3. **Keep `globs:` only, and take the UNION.** The merged file loads for any
|
|
289
|
+
path any of its parts covered, so its `globs:` is the union of theirs.
|
|
290
|
+
`rule-loader.mjs` resolves `globs:` and `paths:` with `globs:` winning
|
|
291
|
+
SILENTLY when both are present (issue #795, `parseGlobsFrontmatter`) — so a
|
|
292
|
+
file carrying both duplicate keys ships the `paths:` block as dead bytes.
|
|
293
|
+
Write `globs:` alone.
|
|
294
|
+
|
|
295
|
+
4. **Substance in, boilerplate out.** Each absorbed learning becomes an `###`
|
|
296
|
+
heading carrying its original rule sentence, plus its evidence line. What is
|
|
297
|
+
dropped is only the per-file repetition (the `# Auto-generated rule:` title,
|
|
298
|
+
the untrusted-content wrapper repeated 43×, the `evidence-digest` /
|
|
299
|
+
`evidence-digest-input` / `source-session` fields). Never drop an evidence
|
|
300
|
+
line to hit a byte target — an insight with no measurement behind it is the
|
|
301
|
+
thing `.claude/rules/measurement-discipline.md` exists to forbid.
|
|
302
|
+
|
|
303
|
+
**Dropping a learning requires a stamp BEFORE the delete.** Deleting a
|
|
304
|
+
generated rule file whose insight is already carried verbatim by a hand-written
|
|
305
|
+
always-on rule is legitimate — but `rm` alone does not stick. `engine.mjs`
|
|
306
|
+
treats a learning as `alreadyMaterialized` if EITHER the idempotency sidecar
|
|
307
|
+
holds a terminal verdict for its `learning_key` (`isProcessed`) OR a
|
|
308
|
+
`.claude/rules/*.md` file still carries its marker. Delete the file without
|
|
309
|
+
stamping and both conditions go false, so the next `/reconcile` proposes it
|
|
310
|
+
again. Stamp it first, via the store's only sanctioned writer:
|
|
311
|
+
|
|
312
|
+
```js
|
|
313
|
+
import { markCandidateProcessed } from '../scripts/lib/reconcile/idempotency.mjs';
|
|
314
|
+
markCandidateProcessed({
|
|
315
|
+
learningKey: 'anti-pattern/<subject-slug>',
|
|
316
|
+
outcome: 'rejected', // or 'already-on-disk' when it lives elsewhere
|
|
317
|
+
fallbackSlug: '<the .claude/rules slug>',
|
|
318
|
+
repoRoot,
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
This writes `.orchestrator/runtime/reconcile-candidates.jsonl` (creating it if
|
|
323
|
+
absent). Verify with a dry run: `alreadyMaterialized` must equal
|
|
324
|
+
absorbed + dropped, not absorbed alone.
|
|
325
|
+
|
|
260
326
|
## Authoring Examples
|
|
261
327
|
|
|
262
328
|
### (a) Hand-authored always-on rule (no frontmatter)
|
|
@@ -41,22 +41,22 @@ The coordinator's **own** planned direct edits belong in `coordinator.json` in t
|
|
|
41
41
|
|
|
42
42
|
`wave-scope.json` is written into the WORKING COPY, not into the session — so until #1123 one session's manifest governed every session sharing that checkout. Measured 2026-08-22 (#1082): a Discovery wave's `allowedPaths: []` — which `wave-loop.md` prescribes for *every* Discovery wave — denied every write of an unrelated parallel session, with a deny reason that could only tell it to fix a wave plan it does not own.
|
|
43
43
|
|
|
44
|
-
Two OPTIONAL manifest fields close that: `
|
|
44
|
+
Two OPTIONAL manifest fields close that: `session_id` (the raw harness session id) and its human-readable twin `semantic_session_id` — the same spelling `.orchestrator/session.lock` and `current-session.json` use (renamed from `session` / `semantic_session` in #1153 P2; readers accept the legacy pair until the next minor release, see `MANIFEST_SESSION_KEYS` in `scripts/lib/session-identity/own-session.mjs`). Both come from ONE `attributionForRecord(repoRoot)` call (`scripts/lib/events.mjs`) in the same coordinator step that writes the rest of the manifest — `skills/wave-executor/wave-loop.md` § Scope Manifest 1. Unlike a raw lock read, `attributionForRecord()` reads `.orchestrator/session.lock` and then confirms the lock's raw `session_id` against `readProcessLocalSessionIds()` before returning anything — a mismatch (or no process-local id at all) yields `{}`, never a peer's ids (#1207).
|
|
45
45
|
|
|
46
|
-
The reader is `hooks/enforce-scope.mjs` **Gate 3b**, between the manifest parse (G3) and the path-guard gate (G4). It resolves identity via `
|
|
46
|
+
The reader is `hooks/enforce-scope.mjs` **Gate 3b**, between the manifest parse (G3) and the path-guard gate (G4). It resolves identity via `new Set(readProcessLocalSessionIds({ hookInput: input }))` and classifies via `classifyManifestSession(scope, ownIds)`, both from [`scripts/lib/session-identity/own-session.mjs`](../scripts/lib/session-identity/own-session.mjs):
|
|
47
47
|
|
|
48
48
|
| Manifest state | `classifyManifestSession` verdict | Gate 3b disposition |
|
|
49
49
|
|---|---|---|
|
|
50
|
-
| no `
|
|
50
|
+
| no `session_id` / `semantic_session_id` (and no legacy `session` / `semantic_session`; pre-#1123) | `unknown` | ENFORCE — falls through unchanged |
|
|
51
51
|
| an id present and matching one of our own | `own` | ENFORCE — falls through unchanged |
|
|
52
52
|
| ids present, none matching, own identity resolvable | `foreign` | **ALLOW** + one `orchestrator.scope.foreign_session_ignored` event |
|
|
53
53
|
| ids present, own identity unresolvable (empty id set) | `unknown` | ENFORCE |
|
|
54
54
|
|
|
55
55
|
Five properties are choices, not omissions — and every one of them points the fail-**closed** way, the deliberate inverse of § 4.1's posture for the dispatch hook:
|
|
56
56
|
|
|
57
|
-
- **Only what is PROVABLY foreign is foreign.** `
|
|
58
|
-
- **Union, not first-tier-wins.**
|
|
59
|
-
- **The writer
|
|
57
|
+
- **Only what is PROVABLY foreign is foreign.** `readProcessLocalSessionIds()` returns the ids that are PROCESS-LOCAL — hook input (`session_id`/`sessionId`/`parent_session_id`) and `CLAUDE_CODE_SESSION_ID` — and an EMPTY set when neither yields an id, which can only produce `unknown`. The repo-global `session.lock` is deliberately NOT a tier here (#1194): it is ONE file shared by every session in the checkout, so unioning it let a peer's manifest match a peer-written lock id, classify `own`, and have Gate 7 deny the second session's legitimate writes — the exact lockout G3b exists to end. A better signal REPLACES a worse one (`.claude/rules/host-resources.md` § HR-102). A gate that guessed would turn "cannot tell" into a silent enforcement-off on every harness exporting no session id. Every value is trimmed on the way in, so a whitespace-only env var cannot enter as a phantom id that matches nothing (`.claude/rules/development.md` § env-var whitespace trap).
|
|
58
|
+
- **Union across the process-local tiers, not first-tier-wins.** Both process-local tiers are read and merged; only an id in NEITHER is somebody else's. Gating them against each other made the READER's identity a strict subset of the WRITER's — the manifest's `session` comes from `sessionAttribution()` = the same repo-global lock — and two divergences inside these tiers produce the same silent failure, the OWN manifest read `foreign` and the write gate switched itself off for the whole wave, logging an event indistinguishable from correct behaviour: (a) a nested harness where payload `session_id` ≠ `CLAUDE_CODE_SESSION_ID` (measured in `hooks/pre-bash-issue-budget.mjs` `resolveSessionId`); (b) a sub-agent invocation, whose own id is the subagent's while the manifest names the coordinator. A third divergence — a session that lost the lock race and wrote a PEER's id into its own manifest — is NO longer covered here since #1194 dropped the lock tier; it is the accepted cost in limit 11, and its defense is the writer guard. The merge only ADDS ids the process actually carries, so the security direction is unchanged: a manifest whose id appears in neither tier still classifies `foreign`. Its cost is named in limit 11 below.
|
|
59
|
+
- **The writer's binding check is mechanical, not a prose comparison (#1207).** Because the lock is repo-global, `skills/wave-executor/wave-loop.md` § Scope Manifest 1 calls `attributionForRecord(repoRoot)`, which confirms the lock's raw `session_id` against `readProcessLocalSessionIds()` internally and returns `{}` on any mismatch or absent process-local id — the coordinator writes whatever comes back, with no further comparison to perform. STATE.md is deliberately not part of this check: it is a shared working-copy artefact written by whichever session holds the lock, so under a peer-owned lock STATE.md's `session` field would agree with the lock about the same peer and "confirm" exactly the wrong id. OMIT the `session_id`/`semantic_session_id` keys whenever `attributionForRecord()` returns `{}` — unbound = ENFORCE. The reader's union covers the case anyway; the writer guard keeps the manifest readable as an audit record instead of publishing a foreign name.
|
|
60
60
|
- **Gate 3b runs after the parse, never on the raw bytes.** A corrupt manifest yields `{}`, hence no ids, hence `unknown` — and keeps failing closed. A gate that peeked at the bytes first would let a truncated manifest disarm the guard.
|
|
61
61
|
- **The empty string is a validator ERROR, not a third flavour of absent.** `validateSession()` → `validateOptionalSessionId()` in `scripts/validate-wave-scope.mjs` rejects `"session": ""` with *"an empty id attributes to nothing; omit the key entirely to declare the manifest unbound"*. An empty id satisfies a truthiness check while matching nobody, so every reader would classify the manifest FOREIGN where the writer meant UNBOUND — opposite dispositions, not a cosmetic ambiguity. An ABSENT key only WARNS, because the § 3.3 pre-union skeleton is itself an unbound manifest and so is every manifest written before #1123.
|
|
62
62
|
|
|
@@ -89,7 +89,7 @@ false
|
|
|
89
89
|
true true
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
Both globs match `scripts/lib/x.mjs`, yet the direct comparison says `false`. For `assertFileScopeSubset()` that inexactness is *safe*: its glob branch reduces to verbatim presence plus literal-prefix coverage and therefore **over-approximates coverage**, which at worst accepts a union it could not fully prove. For a **collision** check the sign flips — the same over-approximation becomes a **false negative**, i.e. a missed collision, i.e. the incident. That is why the two exact stages decide first and stage 3 is reached only for pairs neither can settle.
|
|
92
|
+
Both globs match `scripts/lib/x.mjs`, yet the direct comparison says `false`. For `assertFileScopeSubset()` that inexactness is *safe*: its glob branch reduces to verbatim presence plus literal-prefix coverage and therefore **over-approximates coverage**, which at worst accepts a union it could not fully prove. For a **collision** check the sign flips — the same over-approximation becomes a **false negative**, i.e. a missed collision, i.e. the incident. That is why the two exact stages decide first and stage 3 is reached only for pairs neither can settle. <!-- path-check: example -->
|
|
93
93
|
|
|
94
94
|
## 4. The hook
|
|
95
95
|
|
|
@@ -174,7 +174,7 @@ Complete list of what this guard does **not** see, or sees only approximately:
|
|
|
174
174
|
8. **Lock loss reopens the race.** On lock timeout the cycle runs unlocked (row 14) — two dispatches starting together can then read the same ledger state and one record is lost. That is the pre-lock behaviour, chosen over denying on a lock-file problem.
|
|
175
175
|
9. **The session binding is self-declared** (§ 2.3). `session` is a plain field in a file any process in this working copy can write, so writing a foreign id into it turns the write gate off for that manifest. Named rather than hidden: it is the SAME power `enforcement: "off"` already grants in the same file, so Gate 3b adds no new authority — the manifest is the coordinator's own artefact either way.
|
|
176
176
|
10. **Only the WRITE gate is session-bound.** The dispatch ledger of § 4 takes its session component from the harness's own `input.session_id` (`waveKeyOf(projectDir, sessionId, …)`), and reads only `wave` and `role` out of `wave-scope.json` — the `session` field is not consulted there at all. So a peer session's manifest cannot bind this session's writes since #1123, but the two hooks reach that property by different routes, and a change to one does not carry to the other.
|
|
177
|
-
11. **A peer
|
|
177
|
+
11. **A session that published a peer's id reads its OWN manifest as `foreign` (#1194) — the writer's defense is now mechanical (#1207).** Dropping the lock tier (§ 2.3) moved the cost to the other side of the trade: with a raw `sessionAttribution()` read, a session that lost the `bootstrapLock()` race could get the peer's id and write it into its own manifest, and Gate 3b would then classify the manifest `foreign`, standing its own write guard down. Since #1207 the writer calls `attributionForRecord(repoRoot)` instead — `skills/wave-executor/wave-loop.md` § Scope Manifest 1 — which confirms the lock's raw `session_id` against `readProcessLocalSessionIds()` before returning anything and yields `{}` on any mismatch, so the coordinator performs no manual comparison and STATE.md plays no part in it (a shared working-copy artefact written by whichever session holds the lock, not a process-local witness). A filled binding is therefore provably this session's own; unbound (`{}`) = ENFORCE. CEILING (BV-004): on a harness that exports no session env var and puts no `session_id` in the hook payload (Codex CLI, Cursor today) both tiers are empty, so G3b is permanently `unknown` = enforce = pre-#1123 behaviour there. Revisit when Codex/Cursor hook payloads carry a session id.
|
|
178
178
|
|
|
179
179
|
## 7. Debugging
|
|
180
180
|
|