session-orchestrator 3.24.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.
Files changed (350) hide show
  1. package/.agents/skills/architecture/SKILL.md +18 -0
  2. package/.agents/skills/autopilot/SKILL.md +17 -0
  3. package/.agents/skills/bootstrap/SKILL.md +20 -0
  4. package/.agents/skills/brainstorm/SKILL.md +22 -0
  5. package/.agents/skills/claude-md-drift-check/SKILL.md +15 -0
  6. package/.agents/skills/convergence-monitoring/SKILL.md +22 -0
  7. package/.agents/skills/debug/SKILL.md +22 -0
  8. package/.agents/skills/discovery/SKILL.md +20 -0
  9. package/.agents/skills/dispatcher/SKILL.md +15 -0
  10. package/.agents/skills/docs-orchestrator/SKILL.md +18 -0
  11. package/.agents/skills/ecosystem-health/SKILL.md +20 -0
  12. package/.agents/skills/eli5/SKILL.md +20 -0
  13. package/.agents/skills/eval/SKILL.md +21 -0
  14. package/.agents/skills/evolve/SKILL.md +21 -0
  15. package/.agents/skills/frontmatter-guard/SKILL.md +15 -0
  16. package/.agents/skills/gitlab-ops/SKILL.md +20 -0
  17. package/.agents/skills/gitlab-portfolio/SKILL.md +15 -0
  18. package/.agents/skills/grill/SKILL.md +22 -0
  19. package/.agents/skills/hook-development/SKILL.md +15 -0
  20. package/.agents/skills/mcp-builder/SKILL.md +15 -0
  21. package/.agents/skills/memory-cleanup/SKILL.md +21 -0
  22. package/.agents/skills/mode-selector/SKILL.md +17 -0
  23. package/.agents/skills/npm-publish/SKILL.md +16 -0
  24. package/.agents/skills/peekaboo-driver/SKILL.md +18 -0
  25. package/.agents/skills/persona-panel/SKILL.md +17 -0
  26. package/.agents/skills/plan/SKILL.md +20 -0
  27. package/.agents/skills/playwright-driver/SKILL.md +20 -0
  28. package/.agents/skills/quality-gates/SKILL.md +20 -0
  29. package/.agents/skills/reconcile/SKILL.md +21 -0
  30. package/.agents/skills/remote-offload/SKILL.md +20 -0
  31. package/.agents/skills/repo-audit/SKILL.md +16 -0
  32. package/.agents/skills/session-end/SKILL.md +20 -0
  33. package/.agents/skills/session-plan/SKILL.md +20 -0
  34. package/.agents/skills/session-start/SKILL.md +20 -0
  35. package/.agents/skills/spinout/SKILL.md +16 -0
  36. package/.agents/skills/sunset-review/SKILL.md +16 -0
  37. package/.agents/skills/test-runner/SKILL.md +20 -0
  38. package/.agents/skills/tmux-layout/SKILL.md +21 -0
  39. package/.agents/skills/using-orchestrator/SKILL.md +17 -0
  40. package/.agents/skills/vault-mirror/SKILL.md +15 -0
  41. package/.agents/skills/vault-sync/SKILL.md +15 -0
  42. package/.agents/skills/wave-executor/SKILL.md +20 -0
  43. package/.agents/skills/write-executable-plan/SKILL.md +22 -0
  44. package/.claude-plugin/marketplace.json +1 -1
  45. package/.claude-plugin/plugin.json +1 -1
  46. package/.codex-plugin/plugin.json +1 -1
  47. package/.cursor/commands/autopilot.md +2 -2
  48. package/.cursor/commands/bootstrap.md +1 -1
  49. package/.cursor/commands/brainstorm.md +1 -1
  50. package/.cursor/commands/debug.md +1 -1
  51. package/.cursor/commands/discovery.md +1 -1
  52. package/.cursor/commands/dispatcher.md +2 -2
  53. package/.cursor/commands/eli5.md +2 -2
  54. package/.cursor/commands/eval.md +2 -2
  55. package/.cursor/commands/evolve.md +1 -1
  56. package/.cursor/commands/go.md +1 -1
  57. package/.cursor/commands/grill.md +2 -2
  58. package/.cursor/commands/memory-cleanup.md +2 -2
  59. package/.cursor/commands/persona-panel.md +1 -1
  60. package/.cursor/commands/plan.md +1 -1
  61. package/.cursor/commands/portfolio.md +1 -1
  62. package/.cursor/commands/reconcile.md +2 -2
  63. package/.cursor/commands/release.md +2 -2
  64. package/.cursor/commands/session.md +2 -2
  65. package/.cursor/commands/spinout.md +2 -2
  66. package/.cursor/commands/sunset-review.md +2 -2
  67. package/.cursor/commands/templates-ack.md +2 -2
  68. package/.cursor/commands/test.md +2 -2
  69. package/.cursor/skills/brainstorm/SKILL.md +1 -1
  70. package/.cursor/skills/eval/SKILL.md +1 -1
  71. package/.cursor/skills/quality-gates/SKILL.md +1 -1
  72. package/.cursor/skills/remote-offload/SKILL.md +1 -1
  73. package/.orchestrator/policy/blocked-commands.json +121 -0
  74. package/.orchestrator/policy/ecosystem.schema.json +66 -0
  75. package/.orchestrator/policy/quality-gates.example.json +16 -0
  76. package/.orchestrator/policy/quality-gates.schema.json +38 -0
  77. package/.orchestrator/policy/templates-policy.json +27 -0
  78. package/.orchestrator/policy/test-profiles.json +47 -0
  79. package/AGENTS.md +225 -0
  80. package/CHANGELOG.md +1125 -2
  81. package/NOTICE +11 -6
  82. package/README.md +127 -94
  83. package/agents/eval-judge.md +1 -1
  84. package/agents/skill-applied-judge.md +1 -1
  85. package/assets/wave-lifecycle.svg +98 -0
  86. package/commands/release.md +6 -3
  87. package/commands/session.md +18 -3
  88. package/docs/README.md +4 -0
  89. package/{agents/AGENTS.md → docs/agent-authoring.md} +19 -26
  90. package/docs/baseline.md +67 -0
  91. package/docs/ci-setup.md +108 -62
  92. package/docs/codex-setup.md +65 -21
  93. package/docs/components.md +36 -15
  94. package/docs/cursor-setup.md +6 -2
  95. package/docs/events-schema.md +9 -6
  96. package/docs/instruction-delivery.md +62 -0
  97. package/{agents/memory-proposal-collector.md → docs/memory-proposal-flow.md} +1 -8
  98. package/docs/migration-v4.md +341 -0
  99. package/docs/pi-setup.md +6 -1
  100. package/docs/plugin-architecture-v3.md +1 -1
  101. package/docs/rule-authoring.md +85 -19
  102. package/docs/scope-collision-guard.md +5 -5
  103. package/docs/session-config-reference.md +57 -56
  104. package/docs/session-config-template.md +6 -29
  105. package/docs/telemetry.md +157 -3
  106. package/docs/vault-docs-architecture.md +50 -11
  107. package/hooks/_lib/hook-import-set.json +1487 -0
  108. package/hooks/_lib/subagent-transcript.mjs +562 -0
  109. package/hooks/config-protection.mjs +2 -2
  110. package/hooks/cwd-change-restore.mjs +2 -2
  111. package/hooks/enforce-commands.mjs +69 -0
  112. package/hooks/hooks-codex.json +1 -1
  113. package/hooks/hooks-cursor.json +10 -0
  114. package/hooks/hooks-pi.json +5 -0
  115. package/hooks/hooks.json +6 -1
  116. package/hooks/loop-guard.mjs +3 -3
  117. package/hooks/on-session-end.mjs +2 -2
  118. package/hooks/on-session-start.mjs +103 -2
  119. package/hooks/on-stop.mjs +36 -11
  120. package/hooks/operator-steer.mjs +2 -2
  121. package/hooks/post-bash-write-verify.mjs +85 -0
  122. package/hooks/post-edit-import-probe.mjs +344 -0
  123. package/hooks/post-subagent-discovery-validator.mjs +187 -431
  124. package/hooks/post-tool-batch-wave-signal.mjs +118 -4
  125. package/hooks/post-tool-failure-corrective-context.mjs +2 -2
  126. package/hooks/post-tooluse-frontend-slop.mjs +3 -3
  127. package/hooks/pre-bash-destructive-guard.mjs +39 -13
  128. package/hooks/skill-invocation-telemetry.mjs +17 -5
  129. package/hooks/subagent-telemetry.mjs +13 -4
  130. package/monitors/monitors.json +3 -3
  131. package/package.json +9 -1
  132. package/pi/prompts/session.md +2 -2
  133. package/plugin.json +27 -0
  134. package/scripts/backfill-abandoned-sessions.mjs +50 -4
  135. package/scripts/backfill-learnings-from-vault.mjs +9 -3
  136. package/scripts/dialectic-deriver.mjs +73 -8
  137. package/scripts/export-hw-learnings.mjs +113 -1
  138. package/scripts/generate-agents-skills.mjs +378 -0
  139. package/scripts/generate-cursor-adapter.mjs +45 -8
  140. package/scripts/generate-hook-import-set.mjs +249 -0
  141. package/scripts/lib/agent-status.mjs +13 -2
  142. package/scripts/lib/auto-dream.mjs +38 -36
  143. package/scripts/lib/autonomy/suitability.mjs +6 -0
  144. package/scripts/lib/autopilot/loop.mjs +2 -2
  145. package/scripts/lib/ci-status-banner.mjs +220 -75
  146. package/scripts/lib/codex/plugin-contract.mjs +82 -6
  147. package/scripts/lib/config/auto-dream.mjs +2 -1
  148. package/scripts/lib/config/block-header.mjs +8 -0
  149. package/scripts/lib/config/block-preprocess.mjs +177 -0
  150. package/scripts/lib/config/broken-window.mjs +2 -1
  151. package/scripts/lib/config/cold-start.mjs +2 -1
  152. package/scripts/lib/config/config-protection.mjs +22 -2
  153. package/scripts/lib/config/context-coverage.mjs +2 -1
  154. package/scripts/lib/config/cross-repo.mjs +2 -1
  155. package/scripts/lib/config/custom-phases.mjs +2 -1
  156. package/scripts/lib/config/dialectic.mjs +2 -1
  157. package/scripts/lib/config/discovery-validator.mjs +2 -1
  158. package/scripts/lib/config/dispatcher-autonomy-capture.mjs +24 -1
  159. package/scripts/lib/config/dispatcher-autonomy.mjs +2 -1
  160. package/scripts/lib/config/docs-orchestrator.mjs +2 -1
  161. package/scripts/lib/config/docs-staleness.mjs +2 -1
  162. package/scripts/lib/config/drift-check.mjs +2 -1
  163. package/scripts/lib/config/eval.mjs +2 -1
  164. package/scripts/lib/config/events-rotation.mjs +2 -1
  165. package/scripts/lib/config/evolve.mjs +8 -2
  166. package/scripts/lib/config/frontend-slop-hook.mjs +7 -3
  167. package/scripts/lib/config/gitlab-portfolio.mjs +2 -1
  168. package/scripts/lib/config/handover-gate.mjs +2 -1
  169. package/scripts/lib/config/health-endpoints.mjs +7 -2
  170. package/scripts/lib/config/issue-budget.mjs +2 -1
  171. package/scripts/lib/config/loop-guard.mjs +2 -1
  172. package/scripts/lib/config/memory.mjs +2 -1
  173. package/scripts/lib/config/moc-staleness.mjs +2 -1
  174. package/scripts/lib/config/persona-gate-wave.mjs +2 -1
  175. package/scripts/lib/config/private-config-dir.mjs +67 -0
  176. package/scripts/lib/config/reconcile.mjs +2 -1
  177. package/scripts/lib/config/remote-hosts.mjs +2 -1
  178. package/scripts/lib/config/section-extractor.mjs +7 -1
  179. package/scripts/lib/config/skill-evolution.mjs +2 -1
  180. package/scripts/lib/config/slopcheck.mjs +2 -1
  181. package/scripts/lib/config/state-md-lock.mjs +2 -1
  182. package/scripts/lib/config/templates-first.mjs +2 -1
  183. package/scripts/lib/config/test.mjs +2 -1
  184. package/scripts/lib/config/vault-integration.mjs +7 -1
  185. package/scripts/lib/config/vault-mirror-quality.mjs +2 -1
  186. package/scripts/lib/config/vault-staleness.mjs +2 -1
  187. package/scripts/lib/config/vault-sync.mjs +2 -1
  188. package/scripts/lib/config/verification-auto-fix.mjs +2 -1
  189. package/scripts/lib/config/wave-reviewers.mjs +2 -1
  190. package/scripts/lib/config/worktree-orphans.mjs +2 -1
  191. package/scripts/lib/convergence-monitor.mjs +82 -16
  192. package/scripts/lib/dispatcher/rank.mjs +124 -48
  193. package/scripts/lib/ecosystem-health.mjs +16 -2
  194. package/scripts/lib/eval/engine.mjs +9 -1
  195. package/scripts/lib/eval/session-resolve.mjs +23 -4
  196. package/scripts/lib/events.mjs +22 -6
  197. package/scripts/lib/frontmatter-guard.mjs +131 -13
  198. package/scripts/lib/gates/gate-full.mjs +26 -0
  199. package/scripts/lib/gates/gate-helpers.mjs +76 -0
  200. package/scripts/lib/hardware-pattern-detector.mjs +18 -1
  201. package/scripts/lib/harness-audit/categories/category4.mjs +31 -11
  202. package/scripts/lib/host-identity.mjs +50 -11
  203. package/scripts/lib/instruction-budget-guard.mjs +171 -5
  204. package/scripts/lib/learnings/evolve-telemetry.mjs +178 -0
  205. package/scripts/lib/learnings/io.mjs +60 -6
  206. package/scripts/lib/memory-proposals/store.mjs +30 -22
  207. package/scripts/lib/owner-config-banner.mjs +43 -6
  208. package/scripts/lib/owner-config-loader.mjs +21 -10
  209. package/scripts/lib/owner-interview.mjs +3 -3
  210. package/scripts/lib/owner-yaml.mjs +207 -14
  211. package/scripts/lib/platform.mjs +108 -15
  212. package/scripts/lib/plugin-update-banner.mjs +406 -0
  213. package/scripts/lib/project-hygiene.mjs +38 -2
  214. package/scripts/lib/qg-command-drift-banner.mjs +50 -12
  215. package/scripts/lib/quality-gate.mjs +133 -44
  216. package/scripts/lib/reconcile/emitter.mjs +68 -6
  217. package/scripts/lib/reconcile/engine.mjs +13 -4
  218. package/scripts/lib/reconcile/idempotency.mjs +37 -4
  219. package/scripts/lib/reconcile/writer.mjs +40 -18
  220. package/scripts/lib/session-close-backfill.mjs +67 -9
  221. package/scripts/lib/session-id.mjs +12 -23
  222. package/scripts/lib/session-identity/own-session.mjs +125 -10
  223. package/scripts/lib/session-lock-shape.mjs +43 -0
  224. package/scripts/lib/session-lock.mjs +5 -10
  225. package/scripts/lib/session-registry.mjs +25 -9
  226. package/scripts/lib/session-schema/constants.mjs +36 -2
  227. package/scripts/lib/session-schema/validator.mjs +38 -4
  228. package/scripts/lib/session-start-probes.mjs +18 -1
  229. package/scripts/lib/sessions-staleness-banner.mjs +18 -11
  230. package/scripts/lib/skill-health/join.mjs +17 -4
  231. package/scripts/lib/state-md.mjs +78 -0
  232. package/scripts/lib/sunset/walker.mjs +6 -0
  233. package/scripts/lib/telemetry/schema.mjs +181 -9
  234. package/scripts/lib/telemetry/sync.mjs +368 -12
  235. package/scripts/lib/validate/check-agents-skills.mjs +327 -0
  236. package/scripts/lib/validate/check-agents.mjs +3 -3
  237. package/scripts/lib/validate/check-cursor-adapter.mjs +234 -72
  238. package/scripts/lib/validate/check-hooks-symmetry.mjs +45 -16
  239. package/scripts/lib/validate/check-owner-leakage.mjs +281 -20
  240. package/scripts/lib/validate/check-skill-links.mjs +163 -0
  241. package/scripts/lib/validate/check-skill-script-paths.mjs +47 -28
  242. package/scripts/lib/validate/check-unwired-features.mjs +0 -2
  243. package/scripts/lib/validate/check-validator-registration.mjs +10 -4
  244. package/scripts/lib/validate/enumerate-repo-files.mjs +317 -0
  245. package/scripts/lib/vault-backfill/template.mjs +63 -6
  246. package/scripts/lib/vault-mirror/process.mjs +165 -42
  247. package/scripts/lib/vault-mirror/telemetry.mjs +2 -2
  248. package/scripts/lib/vault-status/narrative-mirror.mjs +127 -18
  249. package/scripts/lib/wave-executor/dispatch-common.mjs +164 -0
  250. package/scripts/lib/wave-executor/foreign-dispatch.mjs +7 -142
  251. package/scripts/lib/wave-executor/remote-dispatch.mjs +5 -7
  252. package/scripts/lib/wave-resource-gate.mjs +8 -2
  253. package/scripts/lib/wave-sizing.mjs +4 -1
  254. package/scripts/lib/wave-transcript-tail.mjs +118 -4
  255. package/scripts/materialize-wave-scope.mjs +12 -5
  256. package/scripts/memory-propose.mjs +19 -5
  257. package/scripts/migrate-cold-start-seed.mjs +4 -1
  258. package/scripts/parse-config.mjs +60 -3
  259. package/scripts/release.mjs +337 -29
  260. package/scripts/repair-invalid-sessions.mjs +3 -3
  261. package/scripts/run-quality-gate.mjs +128 -11
  262. package/scripts/sweep-expired-learnings.mjs +90 -0
  263. package/scripts/sync-vault-schema.mjs +3 -1
  264. package/scripts/telemetry.mjs +2 -2
  265. package/scripts/validate-plugin.mjs +161 -0
  266. package/scripts/validate-wave-scope.mjs +28 -8
  267. package/scripts/wave-scope-binding.mjs +215 -0
  268. package/skills/_shared/instruction-file-resolution.md +10 -0
  269. package/skills/_shared/parallel-aware-preamble.md +1 -0
  270. package/skills/_shared/platform-tools.md +1 -1
  271. package/skills/_shared/state-ownership.md +1 -1
  272. package/skills/architecture/SKILL.md +7 -5
  273. package/skills/{domain-model/SKILL.md → architecture/references/domain-model.md} +9 -9
  274. package/skills/autopilot/SKILL.md +4 -18
  275. package/skills/claude-md-drift-check/SKILL.md +5 -1
  276. package/skills/claude-md-drift-check/checker.mjs +62 -2
  277. package/skills/convergence-monitoring/SIGNALS.md +55 -0
  278. package/skills/discovery/probes/vault-staleness.mjs +37 -13
  279. package/skills/discovery/probes-arch.md +20 -18
  280. package/skills/dispatcher/SKILL.md +3 -2
  281. package/skills/evolve/SKILL.md +65 -26
  282. package/skills/frontmatter-guard/SKILL.md +11 -5
  283. package/skills/npm-publish/SKILL.md +1 -1
  284. package/skills/reconcile/SKILL.md +33 -0
  285. package/skills/remote-offload/SKILL.md +1 -1
  286. package/skills/session-end/SKILL.md +18 -905
  287. package/skills/session-end/phase-3-6-tail.md +10 -3
  288. package/skills/session-end/plan-verification.md +221 -155
  289. package/skills/session-end/references/phase-2-quality-gate.md +93 -0
  290. package/skills/session-end/references/phase-3-documentation-updates.md +229 -0
  291. package/skills/session-end/references/phase-4a-worktree-cleanup.md +120 -0
  292. package/skills/session-end/references/phase-4b-worktree-orphan-sweep.md +58 -0
  293. package/skills/session-end/references/phase-5-issue-cleanup.md +104 -0
  294. package/skills/session-end/references/session-summary-template.md +62 -0
  295. package/skills/session-plan/SKILL.md +49 -0
  296. package/skills/session-start/SKILL.md +22 -904
  297. package/skills/session-start/phase-8-5-express-path.md +1 -1
  298. package/skills/session-start/references/phase-1-1-dispatcher-autonomy-capture.md +55 -0
  299. package/skills/session-start/references/phase-1-2-session-lock.md +140 -0
  300. package/skills/session-start/references/phase-1-5-session-continuity.md +254 -0
  301. package/skills/session-start/references/phase-1-7-vault-status-board.md +53 -0
  302. package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +75 -0
  303. package/skills/session-start/references/phase-4-ssot-environment-check.md +155 -0
  304. package/skills/session-start/references/phase-6-5-forced-reads.md +75 -0
  305. package/skills/session-start/references/phase-6-6-project-intelligence.md +81 -0
  306. package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +103 -0
  307. package/skills/vault-sync/validator.mjs +21 -27
  308. package/skills/wave-executor/SKILL.md +15 -1
  309. package/skills/wave-executor/references/wave-loop-dispatch.md +612 -0
  310. package/skills/wave-executor/references/wave-loop-review.md +570 -0
  311. package/skills/wave-executor/references/wave-loop-scope-manifest.md +162 -0
  312. package/skills/wave-executor/wave-loop.md +14 -1309
  313. package/templates/_shared/journey-manifest.md +10 -6
  314. package/.cursor/commands/autopilot-multi.md +0 -14
  315. package/.cursor/commands/contract-version-bump.md +0 -14
  316. package/.cursor/commands/journey-audit.md +0 -14
  317. package/.cursor/skills/contract-version-bump/SKILL.md +0 -12
  318. package/.cursor/skills/daily/SKILL.md +0 -12
  319. package/.cursor/skills/domain-model/SKILL.md +0 -13
  320. package/.cursor/skills/journey-audit/SKILL.md +0 -13
  321. package/.cursor/skills/skill-creator/SKILL.md +0 -13
  322. package/.cursor/skills/ubiquitous-language/SKILL.md +0 -13
  323. package/commands/autopilot-multi.md +0 -74
  324. package/commands/contract-version-bump.md +0 -28
  325. package/commands/journey-audit.md +0 -43
  326. package/pi/prompts/autopilot-multi.md +0 -12
  327. package/pi/prompts/contract-version-bump.md +0 -12
  328. package/pi/prompts/journey-audit.md +0 -12
  329. package/scripts/autopilot-multi.mjs +0 -885
  330. package/scripts/backfill-learnings-expires.mjs +0 -196
  331. package/scripts/backfill-learnings.mjs +0 -203
  332. package/scripts/fleet-instruction-scan.mjs +0 -141
  333. package/scripts/lib/autopilot/dep-graph.mjs +0 -417
  334. package/scripts/lib/autopilot/multi-killswitch.mjs +0 -184
  335. package/scripts/lib/webhook-url.mjs +0 -105
  336. package/scripts/lifecycle-sim-v6.mjs +0 -347
  337. package/scripts/migrate-learnings-jsonl.mjs +0 -189
  338. package/scripts/migrate-subagents-jsonl.mjs +0 -196
  339. package/scripts/upload-social-preview.mjs +0 -316
  340. package/skills/_shared/model-selection.md +0 -64
  341. package/skills/contract-version-bump/SKILL.md +0 -219
  342. package/skills/daily/SKILL.md +0 -222
  343. package/skills/daily/generate.sh +0 -92
  344. package/skills/daily/templates/daily.md.tpl +0 -36
  345. package/skills/journey-audit/SKILL.md +0 -270
  346. package/skills/skill-creator/SKILL.md +0 -168
  347. package/skills/ubiquitous-language/SKILL.md +0 -97
  348. package/skills/vault-sync/package-lock.json +0 -40
  349. /package/skills/{domain-model → architecture/references}/ADR-FORMAT.md +0 -0
  350. /package/skills/{domain-model → architecture/references}/CONTEXT-FORMAT.md +0 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: Start a development session (housekeeping, feature, deep)
3
- argument-hint: "[housekeeping|feature|deep]"
2
+ description: Start a development session (housekeeping, feature, deep; ultradeep = deep + profile)
3
+ argument-hint: "[housekeeping|feature|deep|ultradeep]"
4
4
  ---
5
5
 
6
6
  # Session Start
@@ -9,7 +9,22 @@ You are beginning a new development session. The user has invoked `/session` wit
9
9
 
10
10
  **Default rationale (measured, not assumed):** `deep` is the default because it is what operators actually run — 77.3 % of 489 recorded sessions across 5 repos, and 115 of 228 (50.4 %) in this repo's own `.orchestrator/metrics/sessions.jsonl`. The former `feature` default made the majority case the one that had to be typed out every time. A `deep` default costs a downgrade keystroke in the minority case; a `feature` default cost an upgrade keystroke in the majority case.
11
11
 
12
- **Argument validation:** Valid session types are `housekeeping`, `feature`, and `deep`. An explicit `$ARGUMENTS` value ALWAYS wins over the default — `/session housekeeping` and `/session feature` behave exactly as before. If `$ARGUMENTS` is not empty and does not match any valid type, inform the user: "Invalid session type '$ARGUMENTS'. Valid types: housekeeping, feature, deep." Then fall back to `deep`.
12
+ **Argument validation:** Valid session types are `housekeeping`, `feature`, and `deep`. An explicit `$ARGUMENTS` value ALWAYS wins over the default — `/session housekeeping` and `/session feature` behave exactly as before. `ultradeep` is additionally accepted as an ARGUMENT ALIAS (see below); it is not a fourth type. If `$ARGUMENTS` is not empty and does not match any valid type or the alias, inform the user: "Invalid session type '$ARGUMENTS'. Valid types: housekeeping, feature, deep (alias: ultradeep)." Then fall back to `deep`.
13
+
14
+ ### Argument alias: `ultradeep` (PRD `docs/prd/2026-09-06-ultradeep-session-profile.md`)
15
+
16
+ `/session ultradeep` is an alias, NOT a fourth `session_type`. Resolve it to TWO STATE.md frontmatter values and then continue exactly as a `deep` session would:
17
+
18
+ ```yaml
19
+ session-type: deep # what every downstream consumer sees
20
+ session-profile: ultradeep # the only place the alias survives
21
+ ```
22
+
23
+ - **`session-type` NEVER becomes `ultradeep`.** The value is a closed set in `scripts/lib/session-schema/constants.mjs` (`VALID_SESSION_TYPES`) and in `scripts/lib/wave-sizing.mjs`; a fourth member would degrade silently in two places (`scripts/lib/telemetry/schema.mjs` maps an unknown type to `"other"`, `scripts/lib/session-close-backfill.mjs` labels it `housekeeping`). The alias exists so that no closed set has to change.
24
+ - **`session-profile` is optional and absent by default.** A plain `/session deep` writes NO `session-profile` key. Absent means "no profile" — never write an empty string, `none`, or `null` to mean absence. Read/write helpers: `readSessionProfile` / `setSessionProfile` in `scripts/lib/state-md.mjs`.
25
+ - **What the profile changes** is the WAVE SHAPE, not the session type: 7 waves with a coordinator-direct Synthesis-Gate at wave 2. See `skills/session-plan/SKILL.md` § Role-to-Wave Mapping and `skills/wave-executor/SKILL.md` § Ultradeep Profile.
26
+ - **Precondition.** The profile needs 7 waves. If Session Config sets `waves` below 7, do NOT silently plan 5 waves under an ultradeep label — name the conflict to the user and let them raise `waves` or drop the alias.
27
+ - **Budgets are deliberately not implemented yet** (PRD § 7): no `ultradeep.max-*` key is read anywhere. Do not invent one; the PRD defers thresholds until three runs have been measured.
13
28
 
14
29
  > **Not read from Session Config.** There is deliberately no `session-type:` (or equivalent) key in the `## Session Config` block — `scripts/lib/config.mjs` `parseSessionConfig()` does not emit one, so any such key in a repo's CLAUDE.md (or its Codex CLI equivalent AGENTS.md) is inert prose. The `session-type:` scalar that IS live lives in STATE.md frontmatter (read by `scripts/print-applicable-rules.mjs` for rule mode-gating) and is written per session, not configured per repo. Do not reintroduce a Session Config key here without wiring it into the parser first.
15
30
 
package/docs/README.md CHANGED
@@ -98,6 +98,10 @@ Two things worth knowing about this split:
98
98
  | `docs/plans/` | Active work document | `/write-executable-plan` artifacts for in-progress work. May not exist when nothing is mid-plan. |
99
99
  | `docs/_private/`, `docs/specs/` | Local-only (gitignored) | Operator scratch space; never tracked, out of scope for this classification. |
100
100
 
101
+ ### Superseded design notes
102
+
103
+ Because `docs/specs/` is gitignored, a correction written INTO a spec can never be committed — so the correction lives here instead. `docs/specs/2026-05-26-parallel-aware-sessions-design.md` (parallel-aware sessions) specifies PID-based lock liveness (`stale-pid-dead`). That is **superseded**: liveness is heartbeat-age based since #1137 (`isLockLive`; `acquire()` knows only `stale-heartbeat`), and the recorded PID is consulted nowhere since #1151 — it was the PID of the short-lived subprocess that wrote the lock, dead within a second. Read the local spec only with that correction applied.
104
+
101
105
  ## See Also
102
106
 
103
107
  - `docs/prd/2026-07-08-docs-public-split.md` — the epic that established this split (S1–S8, issues #775–#782).
@@ -1,37 +1,30 @@
1
- ---
2
- name: agents-authoring-spec
3
- description: NOT A DISPATCHABLE AGENT — never select this. It is the authoring specification that the agent definitions in this directory must follow, loaded as a nested instruction file. Claude Code's plugin loader registers every agents/*.md as an agent by directory convention, and the manifest's `agents` key is additive-only, so it cannot exclude a path. Without this frontmatter the file registered as an unnamed agent with FULL tool access; the minimal `tools` line below is what bounds that. If you need agent-authoring rules, read this file — do not dispatch it.
4
- tools: Read
5
- ---
1
+ <!-- Moved in v4.0.0 from `agents/AGENTS.md` (audit 2026-09-06 § 5A). It never was an agent: Claude Code's plugin loader registers every `agents/*.md` by directory convention and the manifest's `agents` key is additive-only, so no manifest entry could exclude it — only pseudo-frontmatter (`name: agents-authoring-spec`, `tools: Read`) kept the false registration bounded. Living under `docs/` removes the registration instead of bounding it. -->
6
2
 
7
- # `agents/` — Sub-Agent Authoring Conventions
3
+ # Sub-Agent Authoring Conventions (`agents/**`)
8
4
 
9
- > Nested instruction file for the `agents/` subtree. Claude Code / Cursor IDE
10
- > and Codex CLI both load this additively when working on files in this
11
- > directory (root `CLAUDE.md` for the big picture, this file for local
12
- > conventions). Resolution rule:
5
+ > Authoring spec for the sub-agent definitions in `agents/`. Read it together
6
+ > with the root `CLAUDE.md` (big picture) and, when working under `agents/`,
7
+ > whatever nested instruction file that subtree carries. Resolution rule:
13
8
  > [`../skills/_shared/instruction-file-resolution.md`](../skills/_shared/instruction-file-resolution.md).
14
9
  >
15
- > This is **not** an agent definition it is the authoring spec the agent
16
- > `*.md` definitions in this directory must follow. The plugin validator
17
- > (`scripts/lib/validate/check-agents.mjs`) excludes `AGENTS.md` / `CLAUDE.md`
18
- > from agent-frontmatter validation by name, and `measureDescriptionSurface`
19
- > excludes them from its walked corpus (#878).
20
- >
21
- > **Claude Code's plugin loader makes no such exception.** It registers every
22
- > `agents/*.md` as a dispatchable agent by directory convention, and the
23
- > manifest's `agents` key is documented as *additive* ("in addition to those in
24
- > the `agents/` directory"), so it cannot exclude a path. With no frontmatter
25
- > this file therefore registered as an agent named `AGENTS` with **full tool
26
- > access**. The frontmatter above is the containment: it names the file for what
27
- > it is, states in the `description` that it must never be dispatched, and caps
28
- > `tools` at `Read`. Do not remove it — and if you add another non-agent doc to
29
- > this directory, give it the same treatment.
10
+ > **This spec lives in `docs/`, not in `agents/`, on purpose.** Claude Code's
11
+ > plugin loader registers every `agents/*.md` as a dispatchable agent by
12
+ > directory convention, and the manifest's `agents` key is documented as
13
+ > *additive* ("in addition to those in the `agents/` directory"), so it cannot
14
+ > exclude a path. As `agents/AGENTS.md` this file was therefore a registered
15
+ > agent — first an unnamed one with **full tool access**, later a contained one
16
+ > whose pseudo-frontmatter capped `tools` at `Read`. Moving it out of the
17
+ > directory removes the registration rather than bounding it. The same applies
18
+ > to any future non-agent doc: put it under `docs/`, never in `agents/`.
19
+ > (`scripts/lib/validate/check-agents.mjs` still excludes `AGENTS.md` /
20
+ > `CLAUDE.md` by name, and `measureDescriptionSurface` still excludes them from
21
+ > its walked corpus (#878) both now vacuous for this file, and the safety net
22
+ > for anyone who reintroduces one.)
30
23
  >
31
24
  > Sibling spec: for `.claude/rules/*.md` frontmatter (conditional loading via
32
25
  > globs/mode/host-class/expiry, plus the never-always-on invariant for
33
26
  > auto-generated rules), see the canonical authoring spec
34
- > [`docs/rule-authoring.md`](../docs/rule-authoring.md).
27
+ > [`docs/rule-authoring.md`](./rule-authoring.md).
35
28
 
36
29
  ## Local Validation Commands
37
30
 
@@ -0,0 +1,67 @@
1
+ # The projects-baseline Relationship
2
+
3
+ **One line:** `projects-baseline` is a **private, optional** companion repository that
4
+ holds the operator's canonical rule and schema corpus. session-orchestrator reads
5
+ from it when it is present and degrades to a documented fallback when it is not.
6
+ Nothing in this plugin requires it, and no public consumer needs to obtain it.
7
+
8
+ ## What it is
9
+
10
+ A separate git repository (not vendored, not a submodule, not on npm) carrying:
11
+
12
+ - `packages/zod-schemas/src/vault-frontmatter.ts` — the canonical Zod schema for
13
+ Obsidian vault note frontmatter.
14
+ - `templates/shared/.vault.yaml.template` — the canonical `.vault.yaml` template.
15
+ - A `.claude/rules/` corpus. Measured: **26 rule files, all using `paths:`
16
+ frontmatter, 0 using `globs:`** (`scripts/lib/rule-loader.mjs` module doc;
17
+ restated in `scripts/lib/validate/check-rules.mjs`). That corpus is the reason
18
+ `paths:` exists as a same-shape alias for `globs:` at all (#795) — the fleet's
19
+ rules are read **from the baseline**, not from this plugin, so the plugin had to
20
+ learn the baseline's frontmatter convention rather than the other way round.
21
+
22
+ ## How the plugin finds it
23
+
24
+ Never by a hardcoded path. Resolution is host-local, most specific first:
25
+
26
+ 1. `SO_BASELINE_PATH` environment variable
27
+ 2. `owner.yaml` `paths.baseline-path` (`~/.config/session-orchestrator/owner.yaml`,
28
+ host-local, never committed — see `docs/owner-config-schema.md`)
29
+ 3. a sibling checkout at `<repoRoot>/../projects-baseline`
30
+ 4. `~/Projects/projects-baseline` (legacy default)
31
+
32
+ Tiers 1–2 go through `resolveHostPath('baseline-path', …)` in
33
+ `scripts/lib/config/host-paths.mjs`. `scripts/lib/vault-backfill/template.mjs`
34
+ additionally honours `PROJECTS_BASELINE_DIR` above all four, for back-compat.
35
+
36
+ ## The four hard-runtime touchpoints, and what each degrades to
37
+
38
+ | Touchpoint | Reads / writes | Without a baseline |
39
+ |---|---|---|
40
+ | `scripts/lib/frontmatter-guard.mjs` | the canonical vault-frontmatter Zod schema | `readVaultSchema()` → `null`; `generateFrontmatterSnippet()` falls back to an in-module enum set mirroring `skills/vault-sync/validator.mjs` and warns ONCE on stderr; `computeSchemaHash()` → `null` (never the empty-string hash) |
41
+ | `scripts/lib/vault-backfill/template.mjs` | `.vault.yaml.template` | `loadTemplate()` calls `dieFn(2, …)` with a message naming `owner.yaml paths.baseline-path`, `SO_BASELINE_PATH`, `PROJECTS_BASELINE_DIR`, and the sibling-checkout convention. Only `scripts/vault-backfill.mjs` is affected; nothing else aborts |
42
+ | `scripts/sync-vault-schema.mjs` | `--check` drift guard against the canonical schema | exits 2 (missing file). It is a maintenance script, never on a session path |
43
+ | `scripts/lib/reconcile/writer.mjs` + `scripts/lib/session-end/phase-skip.mjs` | writes rule proposals into the baseline (`reconcile.targets` containing `baseline`) | `baselineRoot` absent ⇒ the `baseline` target is a **no-op**; `repo-local` (the default target) is unaffected |
44
+
45
+ `scripts/promote-vault-strict.mjs` also uses a baseline template and already ships
46
+ an explicit `--no-baseline` opt-out.
47
+
48
+ ## The public fallback
49
+
50
+ A repository bootstrapped without the baseline is a normal, supported outcome —
51
+ `skills/bootstrap/public-fallback.md` owns that path. `bootstrap.lock` records
52
+ which source produced the scaffold in its `source:` field:
53
+
54
+ - `claude-init` — `claude init` ran successfully (Claude Code fast path)
55
+ - `plugin-template` — the plugin's own template was copied (every other case)
56
+ - `projects-baseline` — the private baseline was present and used
57
+
58
+ The first two are the **public** values. A consumer repo that shows either is
59
+ fully bootstrapped; the baseline adds the operator's private corpus on top, it
60
+ does not gate the scaffold.
61
+
62
+ ## See also
63
+
64
+ - `docs/owner-config-schema.md` — `owner.yaml` schema, including `paths.baseline-path`
65
+ - `docs/rule-authoring.md` — `paths:` / `globs:` frontmatter
66
+ - `skills/bootstrap/public-fallback.md` — the no-baseline bootstrap path
67
+ - `skills/frontmatter-guard/SKILL.md` — the schema-source resolution table
package/docs/ci-setup.md CHANGED
@@ -14,62 +14,78 @@ project-level Job Token allowlists are explicitly configured — an admin action
14
14
  in the foreign project that cannot be scripted from here. The fix is a deploy
15
15
  token or PAT stored as the masked CI variable `SCHEMA_DRIFT_TOKEN`.
16
16
 
17
- > **Current decision (2026-08-28, #1062): amber is the accepted normal state.**
18
- > `glab variable list` on this project returns zero CI variables — no
19
- > `SCHEMA_DRIFT_TOKEN` is set so every pipeline runs the job to exit 3
20
- > (`NOT VERIFIED`) and `pipeline-gate` prints the amber line. This is a
21
- > deliberate operator choice, not a defect: the job is correctly fail-loud
22
- > (exit taxonomy below), the vendored schema is compared manually at each
23
- > baseline refresh (#1100), and no token is rotated for a check that runs
24
- > against a private project of our own. Session-start's CI banner keeps
25
- > reporting the soft failure on purpose (`allow_failure` jobs are invisible
26
- > at pipeline level, which is what that banner exists to surface). Revisit
27
- > trigger: the first time a vendored-schema drift ships unnoticed, or when
28
- > the baseline gains a public mirror then set the token (Option A below)
29
- > and flip `SCHEMA_DRIFT_OPTIONAL` at both sites.
30
-
31
- ### Activation status (measured 2026-09-02)
32
-
33
- **Update, same day:** the token below was **revoked** — an unused credential is a
34
- liability per SEC-005's secrets-lifecycle discipline, and leaving a live,
35
- never-set-as-a-CI-variable token sitting in `infrastructure/projects-baseline`
36
- served no purpose once the control run below had already answered the
37
- question it was minted for. Re-minting it (same `glab api --method POST … --input -`
38
- recipe as Option A step 1) is now **Step 0** of the re-activation sequence
39
- below, not an assumed-still-valid token.
40
-
41
- A Project Access Token was provisioned today, scoped exactly as Option A
42
- below recommends:
17
+ > **Armed (2026-09-03, #1175): the hard gate is live.** #531 landed upstream
18
+ > `infrastructure/projects-baseline` commit `cb9ec97` adds `peer-card`,
19
+ > `board`, and `source-repo` to the canonical schema (the issue's AC named
20
+ > only `peer-card`; the close comment widened scope to all three values
21
+ > already vendored ahead here). That closed the vendored-schema divergence
22
+ > which had blocked activation since 2026-09-02; `skills/vault-sync/
23
+ > validator.mjs` was regenerated and `node scripts/sync-vault-schema.mjs
24
+ > --check` now exits 0. The Project Access Token was re-minted (id 53, see
25
+ > § Activation status below), the masked `SCHEMA_DRIFT_TOKEN` CI variable is
26
+ > set on this project, and `SCHEMA_DRIFT_OPTIONAL` is `"false"` at both
27
+ > sites in `.gitlab-ci.yml` a missing or expired token now hard-fails the
28
+ > pipeline (exit 4) instead of printing the amber `NOT VERIFIED` line that
29
+ > was the accepted state under the prior (2026-08-28, #1062) decision. Both
30
+ > directions were proven before the flip — see below. Revisit trigger for
31
+ > the token itself: expiry (2027-09-01) or a scope/rotation need — see
32
+ > § Rotation / re-arm sequence.
33
+
34
+ ### Activation status (token re-minted 2026-09-03, id 53)
35
+
36
+ The Project Access Token was revoked on 2026-09-02 once a control run had
37
+ answered the question it was minted for an unused credential is a
38
+ liability per SEC-005's secrets-lifecycle discipline. That control run had
39
+ also surfaced the real reason activation was still blocked:
40
+ `skills/vault-sync/validator.mjs`'s `vaultNoteTypeSchema` enum carried
41
+ `peer-card` and `board`, and `vaultFrontmatterSchema` carried
42
+ `source-repo: z.string().optional()`, none of which the canonical
43
+ `infrastructure/projects-baseline` source had yet — the documented
44
+ vendor-ahead state (`scripts/sync-vault-schema.mjs` header, "Vendor-ahead
45
+ state (2026-05-23, #503, I5)"), tracked as upstream-sync-debt in issue #531
46
+ (#503 itself was already closed).
47
+
48
+ **#531 landed upstream** as commit `cb9ec97`: `vaultNoteTypeSchema` gained
49
+ `peer-card` and `board`; `vaultFrontmatterSchema` gained `source-repo:
50
+ z.string().optional()`. With the canonical source caught up,
51
+ `node scripts/sync-vault-schema.mjs --check` exits 0 — no drift.
52
+
53
+ **Token, re-minted:**
43
54
 
44
55
  - **Name:** `session-orchestrator-ci-schema-drift`
45
56
  - **Project:** `infrastructure/projects-baseline` (id 52) — the TARGET repo,
46
57
  not this one
58
+ - **Token id:** 53
47
59
  - **Scopes:** `read_repository`
48
60
  - **Access level:** Reporter (20)
49
61
  - **Expires:** 2027-09-01
50
62
 
51
- The masked `SCHEMA_DRIFT_TOKEN` CI variable on this project (id 74) was set
52
- with that token, then **removed again**. A control run with the token set
53
- confirmed the clone step authenticates correctly — but the drift check itself
54
- then failed for a real, already-known reason:
55
- `skills/vault-sync/validator.mjs`'s `vaultNoteTypeSchema` enum carries
56
- `peer-card` and `board`, and the canonical `infrastructure/projects-baseline`
57
- source does not have either yet. This is the documented vendor-ahead state
58
- (`scripts/sync-vault-schema.mjs` header, "Vendor-ahead state (2026-05-23,
59
- #503, I5)") and tracked as upstream-sync-debt in issue #531 (#503 itself is
60
- closed). With the variable set and `SCHEMA_DRIFT_OPTIONAL` still `"true"`,
61
- this exit-1 `DRIFT` is a **hard** failure it is not in
62
- `allow_failure.exit_codes: [3]` so leaving the variable set today would turn
63
- the next push red for a fact already tracked in #531, not for a new defect.
64
- The variable was removed rather than left set; activation stays blocked until
65
- the canonical enum gains both values.
66
-
67
- **Re-activation sequence once #531 lands upstream:**
68
-
69
- 0. **Re-mint the token** it was revoked (see § Activation status above). Run
70
- the same `glab api --method POST --input -` recipe as Option A step 1,
71
- against the TARGET project (id 52), and copy the response's `token` field
72
- immediately it is shown exactly once.
63
+ The masked `SCHEMA_DRIFT_TOKEN` CI variable is set on this project (id 74),
64
+ **not** Protected same reasoning as Option A step 3 below.
65
+
66
+ **Proof pipelines, both directions, run before the flip:**
67
+
68
+ - **GREEN** pipeline 8358 @ `dc9522dd` (branch
69
+ `proof/1175-schema-drift-green`): job `schema-drift-check` #84625 ran with
70
+ the token, cloned the baseline, and printed `RESULT: IN-SYNC (exit 0)`;
71
+ `pipeline-gate` succeeded.
72
+ - **RED** pipelines 8355–8357 @ `bca78dae` (branch
73
+ `proof/1175-schema-drift-red`, a deliberately bogus enum value injected
74
+ into the vendored copy): `sync-vault-schema.mjs` reported drift, the job
75
+ failed with exit 1 outside `allow_failure.exit_codes: [3]` and
76
+ `pipeline-gate` never ran.
77
+
78
+ With both proofs recorded, `SCHEMA_DRIFT_OPTIONAL` is `"false"` at both
79
+ sites in `.gitlab-ci.yml` `schema-drift-check` and `pipeline-gate`.
80
+ `tests/ci/schema-drift-check.test.mjs` pins the committed value on both
81
+ jobs, so a half-revert or a template refresh flipping one site back to
82
+ `"true"` fails the suite locally, not silently in a pipeline.
83
+
84
+ **Rotation / re-arm sequence** (token expiry or replacement):
85
+
86
+ 0. **Re-mint the token.** Run the same `glab api --method POST … --input -`
87
+ recipe as Option A step 1, against the TARGET project (id 52), and copy
88
+ the response's `token` field immediately — it is shown exactly once.
73
89
  1. `read -rs TOKEN` at the prompt (no echo), then pipe it into `glab variable
74
90
  set` rather than passing it as a `--value` argument — a value passed on the
75
91
  command line is visible to any other process on the host via `ps`, while
@@ -92,10 +108,12 @@ the canonical enum gains both values.
92
108
  `RESULT: IN-SYNC` — and confirm the job DURATION is well over 20 seconds
93
109
  (see the pipeline-6815 warning above). A fast "success" is the exit-3
94
110
  soft-skip in disguise, not a real run.
95
- 3. Flip `SCHEMA_DRIFT_OPTIONAL` to `"false"` at **both** sites —
96
- `schema-drift-check` and `pipeline-gate` in one commit.
97
- `tests/ci/schema-drift-check.test.mjs` already asserts the two values are
98
- equal, so no test edit is needed to enforce the flip.
111
+ 3. `SCHEMA_DRIFT_OPTIONAL` stays `"false"` at **both** sites —
112
+ `schema-drift-check` and `pipeline-gate`. A rotation replaces only the
113
+ credential, never the flag; if the flag was ever reverted for an
114
+ emergency, flip it back to `"false"` at both sites in one commit —
115
+ `tests/ci/schema-drift-check.test.mjs` pins the committed value on both
116
+ jobs, so a half-flip fails the suite locally.
99
117
  4. Local counter-probe before trusting the pipeline: clone
100
118
  `infrastructure/projects-baseline` with the token, make a throwaway copy of
101
119
  `packages/zod-schemas/src/vault-frontmatter.ts` with one field
@@ -134,11 +152,12 @@ let alone diff a schema against it. Issue #933.
134
152
 
135
153
  ```yaml
136
154
  variables:
137
- SCHEMA_DRIFT_OPTIONAL: "true"
155
+ SCHEMA_DRIFT_OPTIONAL: "false"
138
156
  ```
139
157
 
140
- It is the review-visible declaration that "no token" is *currently* an accepted
141
- state. The behaviour matrix:
158
+ It is the review-visible declaration that "no token" is *no longer* an
159
+ accepted state armed 2026-09-03 (#1175, see § Activation status above).
160
+ The behaviour matrix:
142
161
 
143
162
  | `SCHEMA_DRIFT_TOKEN` | `SCHEMA_DRIFT_OPTIONAL` | Exit | State | Pipeline effect |
144
163
  |---|---|---|---|---|
@@ -169,14 +188,41 @@ note, not a blocker: the sentinels are intact today, and the fix — if it is
169
188
  ever needed — is giving `sync-vault-schema.mjs`'s malformed-sentinel case a
170
189
  distinct exit code, not a change here.
171
190
 
172
- **After completing the token setup below, change `SCHEMA_DRIFT_OPTIONAL` to
173
- `"false"` in `.gitlab-ci.yml`** in **both** places: the `schema-drift-check`
191
+ **This is what the armed state looks like.** `SCHEMA_DRIFT_OPTIONAL` is
192
+ `"false"` in `.gitlab-ci.yml` at **both** places: the `schema-drift-check`
174
193
  job and `pipeline-gate`. One flag, two enforcement points;
175
- `tests/ci/schema-drift-check.test.mjs` asserts the mirroring, so a half-flip
176
- fails the suite locally rather than silently leaving one point advisory. The
177
- flip is what converts a missing token from a tolerated warning into a hard red,
178
- and it is the whole point of the flag: the opt-out is a line in a reviewed file,
179
- not the accidental side effect of an unset CI variable.
194
+ `tests/ci/schema-drift-check.test.mjs` asserts the mirroring AND pins the
195
+ literal `"false"` value on both jobs, so a half-flip or a full revert —
196
+ fails the suite locally rather than silently leaving one point advisory. A
197
+ missing or expired token now hard-fails the pipeline (exit 4) instead of the
198
+ tolerated amber warning — that is the whole point of the flag: the opt-out is
199
+ a line in a reviewed file, not the accidental side effect of an unset CI
200
+ variable.
201
+
202
+ **To switch it back to amber temporarily** (a token rotation window, or
203
+ taking the check offline for an emergency): set `SCHEMA_DRIFT_OPTIONAL` to
204
+ `"true"` at **both** sites, in one commit — the same mirrored-pair discipline
205
+ applies in reverse, and the same test catches a half-revert. Re-arm by
206
+ flipping both sites back to `"false"` once the reason for the amber window is
207
+ resolved; see § Rotation / re-arm sequence above for the token side of that
208
+ operation.
209
+
210
+ **Fork / external-contributor MR caveat.** `.gate-rules` (`.gitlab-ci.yml:74`)
211
+ includes `if: $CI_PIPELINE_SOURCE == "merge_request_event"`, so a merge
212
+ request pipeline runs `schema-drift-check` regardless of who opened it — but
213
+ GitLab does not pass the target project's masked CI/CD variables to a
214
+ pipeline running a **forked** project's code, by design, so that an untrusted
215
+ fork cannot exfiltrate a secret. A fork/contributor MR therefore cannot read
216
+ `SCHEMA_DRIFT_TOKEN` even though the variable is set and unprotected on this
217
+ project, and with `SCHEMA_DRIFT_OPTIONAL: "false"` that reads as a genuinely
218
+ missing token: exit **4** (`MISCONFIGURED`), a hard pipeline failure — not the
219
+ amber `SKIPPED` a same-project branch would get. The accepted mitigation is
220
+ either of: a maintainer re-runs the pipeline from within this project (e.g.
221
+ pushing the same commit to a branch here, where the variable IS available),
222
+ or a maintainer temporarily sets `SCHEMA_DRIFT_OPTIONAL: "true"` on that one
223
+ MR/branch for the duration of review. Do not weaken the committed default in
224
+ `.gitlab-ci.yml` for this — it stays `"false"` at both sites per the armed
225
+ state above.
180
226
 
181
227
  > **Before you flip it, run ONE pipeline with the token present while
182
228
  > `SCHEMA_DRIFT_OPTIONAL` is still `"true"`, and check the job's DURATION.**
@@ -11,6 +11,8 @@ Guide for using Session Orchestrator with OpenAI Codex through Codex's public pl
11
11
 
12
12
  ## Installation
13
13
 
14
+ **Recommended:** the short remote form (`codex plugin marketplace add <owner>/<repo>`) needs no local clone — see "Short-Form Marketplace Add" below. The steps below are the maintainer/local-clone path used by `scripts/codex-install.mjs`.
15
+
14
16
  Clone the repository, install its runtime dependencies, and run the installer from the plugin root:
15
17
 
16
18
  ```bash
@@ -30,7 +32,7 @@ codex plugin list --available --json
30
32
 
31
33
  It operates only through public Codex plugin commands; hook trust remains untouched.
32
34
 
33
- ### Short-Form Marketplace Add (Verified 2026-08-28, codex-cli 0.141.0)
35
+ ### Short-Form Marketplace Add (Recommended — Verified 2026-09-04, codex-cli 0.144.4)
34
36
 
35
37
  `codex plugin marketplace add --help` documents a short remote form:
36
38
 
@@ -38,33 +40,22 @@ It operates only through public Codex plugin commands; hook trust remains untouc
38
40
  codex plugin marketplace add owner/repo --ref main
39
41
  ```
40
42
 
41
- Tested against this repo in a scoped throwaway `CODEX_HOME` (2026-08-28, codex-cli 0.141.0):
43
+ This is the recommended install path no local clone needed. Confirmed end-to-end on codex-cli **0.144.4** (2026-09-04), against this repo's unchanged flat layout (`.codex-plugin/plugin.json` + `.claude-plugin/marketplace.json` at repo root, no `plugins/<name>/`):
42
44
 
43
45
  ```
44
- $ codex plugin marketplace add Kanevry/session-orchestrator --json
45
- {
46
- "marketplaceName": "kanevry",
47
- "installedRoot": ".../.tmp/marketplaces/kanevry",
48
- "alreadyAdded": false
49
- }
46
+ $ codex plugin add session-orchestrator@kanevry --json
47
+ {"pluginId":"session-orchestrator@kanevry","version":"3.22.1+codex.20260825125233","installedPath":"~/.codex/plugins/cache/kanevry/session-orchestrator/<version>","authPolicy":"ON_INSTALL"}
50
48
  $ echo $?
51
49
  0
52
50
  ```
53
51
 
54
- This succeeds and clones the repo via git — no `--ref`/`owner/repo` string is needed beyond the short form; the resulting marketplace name (`kanevry`) is read from `.claude-plugin/marketplace.json`'s `name` field, not from the `owner/repo` argument.
52
+ `codex plugin list --available --json --marketplace kanevry` confirms `installed: true, enabled: true` for the same layout no `plugins/<name>/` restructuring was needed.
55
53
 
56
- **However**, the subsequent install step fails identically for both this short remote form *and* the long-form local install documented above (`codex plugin marketplace add "$PWD"`, same as `scripts/codex-install.mjs` runs):
57
-
58
- ```
59
- $ codex plugin add session-orchestrator@kanevry --json
60
- Error: plugin `session-orchestrator` was not found in marketplace `kanevry`
61
- $ echo $?
62
- 1
63
- ```
54
+ **Historical note:** on codex-cli 0.141.0 (2026-08-28), the identical `plugin add` command failed against this same layout with `Error: plugin session-orchestrator was not found in marketplace kanevry`; upgrading to 0.144.4+ resolves it.
64
55
 
65
- `codex plugin list --available --json --marketplace kanevry` returns `{"installed": [], "available": []}` for both forms — the marketplace is configured, but no plugin is discoverable inside it, contradicting item 1 under "Understand the Three States" below. A synthetic marketplace root mirroring this repo's exact layout (`.codex-plugin/plugin.json` directly at root, no `.claude-plugin/marketplace.json`) reproduces the same empty discovery; by contrast, a directory scanned via a `<root>/plugins/<name>/.codex-plugin/plugin.json` layout (the shape `codex plugin marketplace add --help`'s `--sparse plugins/foo` example implies, and the shape this host's own pre-existing `local` marketplace uses via `~/plugins/session-orchestrator`) resolves correctly. This suggests codex's own plugin-discovery convention expects a `plugins/<name>/` marketplace layout that this repo's flat root does not provide, though `.claude-plugin/marketplace.json` (Claude Code's schema) is independently accepted as "a supported manifest" at the `marketplace add` step, without resolving to a discoverable Codex plugin at `list` time.
56
+ ### Switching Marketplace Sources
66
57
 
67
- **Caveat that limits this finding:** this host's installed codex-cli is **0.141.0**, older than the "0.144.4 or newer" prerequisite this guide states above. This failure was not re-verified against 0.144.4+, so it may be specific to running below the documented minimum rather than a defect in this repo's layout on a supported version. Until re-verified on 0.144.4+, treat both the short remote form and the long-form local install (`node scripts/codex-install.mjs`) as **unconfirmed end-to-end on this host** — the `marketplace add` step succeeds either way, but `plugin add` does not, on 0.141.0. Do not elevate either form to a README-level recommended command until a `plugin add` success is measured and dated.
58
+ `codex plugin marketplace add owner/repo` silently **replaces** an already-registered marketplace of the same declared name the name comes from `marketplace.json`'s `name` field, not the `owner/repo` argument with a fresh git clone under `~/.codex/.tmp/marketplaces/<name>`. Re-adding the original local path afterward then fails with `marketplace '<name>' is already added from a different source; remove it before adding this source`. To switch sources deliberately, run `codex plugin marketplace remove <name>` first.
68
59
 
69
60
  ## Understand the Three States
70
61
 
@@ -76,7 +67,16 @@ Codex reports three distinct states that must not be conflated:
76
67
 
77
68
  ## Refresh and Explicit Cache Invalidation
78
69
 
79
- After pulling changes, rerun the installer:
70
+ **If you installed via the short remote form** (`codex plugin marketplace add owner/repo`), the refresh is a marketplace upgrade, not a re-install. Measured 2026-09-06 on codex-cli 0.144.4 — `codex plugin marketplace upgrade --help`: *"Refresh configured Git marketplace snapshots. Omit MARKETPLACE_NAME to upgrade all configured Git marketplaces."*
71
+
72
+ ```bash
73
+ codex plugin marketplace upgrade kanevry # or omit the name to refresh all
74
+ codex plugin add session-orchestrator@kanevry
75
+ ```
76
+
77
+ `upgrade` re-fetches the Git snapshot; `plugin add` then re-installs the bundle from that refreshed snapshot. There is no local clone in this path, so "re-run the installer" does not apply to it.
78
+
79
+ **If you installed from a local clone** (the maintainer path), rerun the installer after pulling:
80
80
 
81
81
  ```bash
82
82
  git pull
@@ -126,7 +126,51 @@ The plugin bundle includes the Codex role definitions under `.codex-plugin/agent
126
126
 
127
127
  The Codex hook command uses Codex's native `${PLUGIN_ROOT}` expansion. The wrapper also exports `CODEX_PLUGIN_ROOT="${PLUGIN_ROOT}"` for shared compatibility code and sets `SO_PLATFORM=codex` so Codex wins when multiple harness variables are present.
128
128
 
129
- Claude-only events (`SessionEnd`, `PostToolUseFailure`, `PostToolBatch`, and `CwdChanged`) are intentionally absent because Codex 0.144.4 does not expose them as supported project events. Claude Edit/Write payload handlers are also absent: Codex emits canonical `apply_patch` data, while those handlers currently expect Claude's Edit/Write payload shape. They will remain unwired until a real `apply_patch` adapter exists; pretending the payloads are compatible would create false enforcement. The same applies to the Bash-payload handlers, including `post-bash-write-verify.mjs` (#942): they gate on Claude's `tool_name === 'Bash'`, which no Codex bridge delivers, so wiring them today would be a silent no-op (the #919-P2 class). These per-event gaps are tracked as documented asymmetries in `scripts/lib/validate/check-hooks-symmetry.mjs` (Check 6, `handlerAsymmetries`) — an UNDOCUMENTED one-platform-only handler now fails validation.
129
+ ### What Codex actually exposes (measured 2026-09-06, codex-cli 0.144.4)
130
+
131
+ The Codex runtime knows **ten** hook events. This is read out of the shipped binary, which embeds one JSON-Schema pair per event, not quoted from release notes:
132
+
133
+ ```
134
+ $ strings -a "$(npm root -g)/@openai/codex/node_modules/@openai/codex-darwin-arm64/vendor/aarch64-apple-darwin/bin/codex" \
135
+ | grep '"title": "'
136
+ "title": "post-tool-use.command.input" / ".output"
137
+ "title": "permission-request.command.input" / ".output"
138
+ "title": "post-compact.command.input" / ".output"
139
+ "title": "pre-tool-use.command.input" / ".output"
140
+ "title": "pre-compact.command.input" / ".output"
141
+ "title": "session-start.command.input" / ".output"
142
+ "title": "subagent-start.command.input" / ".output"
143
+ "title": "subagent-stop.command.input" / ".output"
144
+ "title": "user-prompt-submit.command.input" / ".output"
145
+ "title": "stop.command.input" / ".output"
146
+ ```
147
+
148
+ | Event | 0.144.4 | Wired here |
149
+ |---|---|---|
150
+ | `SessionStart` | yes | yes — banner + `on-session-start.mjs` |
151
+ | `PostToolUse` | yes | yes — `loop-guard.mjs` |
152
+ | `SubagentStop`, `Stop` | yes | yes — `on-stop.mjs` |
153
+ | `PreToolUse`, `SubagentStart` | yes | declared, **empty** (see below) |
154
+ | `UserPromptSubmit`, `PermissionRequest`, `PreCompact`, `PostCompact` | yes | no — this repo has no handler for them |
155
+ | `SessionEnd`, `Interrupt` | **no — event does not exist** | n/a |
156
+ | `PostToolUseFailure`, `PostToolBatch`, `CwdChanged` | no — Claude-only | n/a |
157
+
158
+ **`SessionEnd` is not "Claude-only", it is absent**, and that distinction is load-bearing: the manifest deserializer rejects unknown keys (`unexpected map key` in the same binary), so adding one does not skip a hook — it can reject the whole manifest and take every already-working hook with it. `Interrupt` arrives in 0.150.0+ and async handlers (`"async": true`) in 0.148+; both are **documented upstream but unverified here**, because this host runs 0.144.4. Re-measure against the shipped binary before widening the set — the machine-readable copy is `CODEX_NATIVE_EVENTS` in `scripts/lib/codex/plugin-contract.mjs`.
159
+
160
+ For the day `SessionEnd` does land: upstream caps it (and `Interrupt`) at a **1 s default / 3 s maximum** timeout, where every other event gets 600 s. `hooks/on-session-end.mjs` measures ~221 ms median, so it fits — but only just, and only while it stays that fast.
161
+
162
+ ### Why our PreToolUse guards stay unwired — the reason, corrected
163
+
164
+ Earlier revisions of this page said the handlers were unwired because "no Codex bridge delivers `tool_name`". **That was measuring the wrong thing** — it grepped our own adapter code rather than the Codex payload contract. There is no bridge because none is needed:
165
+
166
+ - `pre-tool-use.command.input` REQUIRES `tool_name` and `tool_input`, alongside `cwd`, `hook_event_name`, `model`, `permission_mode`, `session_id`, `tool_use_id`, `transcript_path`, `turn_id`.
167
+ - The deny envelope is `hookSpecificOutput.{hookEventName, permissionDecision, permissionDecisionReason}` — byte-identical to what `emitDeny()` already writes, and Codex enforces exactly that shape (its own error text: *"PreToolUse hook returned permissionDecision:deny without a non-empty permissionDecisionReason"*). Codex additionally rejects `permissionDecision: "allow"` and `"ask"`; our allow path is a bare `exit 0` with no stdout, so it is compatible.
168
+
169
+ The real blocker is the **tool-name vocabulary**. Codex has no `Bash`, `Edit`, `Write` or `MultiEdit` tool — `strings -a <codex> | grep -c '"Bash"'` returns `0`; its tools are `shell`, `exec_command`, `unified_exec`, `apply_patch`, `update_plan`, `view_image`. Every PreToolUse guard in `hooks/` opens with an equality gate on a Claude tool name and returns `emitAllow()` otherwise, so wiring `pre-bash-destructive-guard.mjs` or `enforce-scope.mjs` today produces a hook that runs, matches nothing, and allows everything — **false enforcement, which is worse than a registered gap** (#919-P2 class).
170
+
171
+ Consequence to state plainly: **PSA-003 (destructive-command guard) and the file-scope guard are behavioural only on Codex today.** The repair is a tool-name map (`shell`/`exec_command`/`unified_exec` → `Bash`) for the Bash guards, plus an `apply_patch` payload adapter for the Edit/Write matchers specifically. Only the second half needs the adapter.
172
+
173
+ These per-event gaps are tracked as documented asymmetries in `scripts/lib/validate/check-hooks-symmetry.mjs` (Check 6, `handlerAsymmetries`) — an UNDOCUMENTED one-platform-only handler fails validation.
130
174
 
131
175
  An empty `PreToolUse` or `SubagentStart` array means the event belongs to the validated Codex surface but currently has no payload-compatible handler. It does not mean installation or hook trust failed.
132
176