session-orchestrator 3.24.0 → 4.0.1

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 (435) 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 +3 -2
  47. package/.codex-plugin/skills/architecture/SKILL.md +20 -0
  48. package/.codex-plugin/skills/autopilot/SKILL.md +21 -0
  49. package/.codex-plugin/skills/autopilot/agents/openai.yaml +5 -0
  50. package/.codex-plugin/skills/bootstrap/SKILL.md +22 -0
  51. package/.codex-plugin/skills/bootstrap/agents/openai.yaml +5 -0
  52. package/.codex-plugin/skills/brainstorm/SKILL.md +22 -0
  53. package/.codex-plugin/skills/brainstorm/agents/openai.yaml +5 -0
  54. package/.codex-plugin/skills/claude-md-drift-check/SKILL.md +17 -0
  55. package/.codex-plugin/skills/close/SKILL.md +21 -0
  56. package/.codex-plugin/skills/close/agents/openai.yaml +5 -0
  57. package/.codex-plugin/skills/convergence-monitoring/SKILL.md +24 -0
  58. package/.codex-plugin/skills/debug/SKILL.md +21 -0
  59. package/.codex-plugin/skills/debug/agents/openai.yaml +5 -0
  60. package/.codex-plugin/skills/discovery/SKILL.md +21 -0
  61. package/.codex-plugin/skills/discovery/agents/openai.yaml +5 -0
  62. package/.codex-plugin/skills/dispatcher/SKILL.md +21 -0
  63. package/.codex-plugin/skills/dispatcher/agents/openai.yaml +5 -0
  64. package/.codex-plugin/skills/docs-orchestrator/SKILL.md +20 -0
  65. package/.codex-plugin/skills/ecosystem-health/SKILL.md +22 -0
  66. package/.codex-plugin/skills/eli5/SKILL.md +21 -0
  67. package/.codex-plugin/skills/eli5/agents/openai.yaml +5 -0
  68. package/.codex-plugin/skills/eval/SKILL.md +21 -0
  69. package/.codex-plugin/skills/eval/agents/openai.yaml +5 -0
  70. package/.codex-plugin/skills/evolve/SKILL.md +21 -0
  71. package/.codex-plugin/skills/evolve/agents/openai.yaml +5 -0
  72. package/.codex-plugin/skills/frontmatter-guard/SKILL.md +17 -0
  73. package/.codex-plugin/skills/gitlab-ops/SKILL.md +22 -0
  74. package/.codex-plugin/skills/gitlab-portfolio/SKILL.md +17 -0
  75. package/.codex-plugin/skills/go/SKILL.md +22 -0
  76. package/.codex-plugin/skills/go/agents/openai.yaml +5 -0
  77. package/.codex-plugin/skills/grill/SKILL.md +21 -0
  78. package/.codex-plugin/skills/grill/agents/openai.yaml +5 -0
  79. package/.codex-plugin/skills/harness-audit/SKILL.md +19 -0
  80. package/.codex-plugin/skills/harness-audit/agents/openai.yaml +5 -0
  81. package/.codex-plugin/skills/hook-development/SKILL.md +17 -0
  82. package/.codex-plugin/skills/mcp-builder/SKILL.md +17 -0
  83. package/.codex-plugin/skills/memory-cleanup/SKILL.md +21 -0
  84. package/.codex-plugin/skills/memory-cleanup/agents/openai.yaml +5 -0
  85. package/.codex-plugin/skills/mode-selector/SKILL.md +19 -0
  86. package/.codex-plugin/skills/npm-publish/SKILL.md +18 -0
  87. package/.codex-plugin/skills/peekaboo-driver/SKILL.md +20 -0
  88. package/.codex-plugin/skills/persona-panel/SKILL.md +22 -0
  89. package/.codex-plugin/skills/persona-panel/agents/openai.yaml +5 -0
  90. package/.codex-plugin/skills/plan/SKILL.md +22 -0
  91. package/.codex-plugin/skills/plan/agents/openai.yaml +5 -0
  92. package/.codex-plugin/skills/playwright-driver/SKILL.md +22 -0
  93. package/.codex-plugin/skills/portfolio/SKILL.md +21 -0
  94. package/.codex-plugin/skills/portfolio/agents/openai.yaml +5 -0
  95. package/.codex-plugin/skills/quality-gates/SKILL.md +22 -0
  96. package/.codex-plugin/skills/reconcile/SKILL.md +21 -0
  97. package/.codex-plugin/skills/reconcile/agents/openai.yaml +5 -0
  98. package/.codex-plugin/skills/release/SKILL.md +22 -0
  99. package/.codex-plugin/skills/release/agents/openai.yaml +5 -0
  100. package/.codex-plugin/skills/remote-offload/SKILL.md +22 -0
  101. package/.codex-plugin/skills/repo-audit/SKILL.md +19 -0
  102. package/.codex-plugin/skills/repo-audit/agents/openai.yaml +5 -0
  103. package/.codex-plugin/skills/session/SKILL.md +21 -0
  104. package/.codex-plugin/skills/session/agents/openai.yaml +5 -0
  105. package/.codex-plugin/skills/session-end/SKILL.md +22 -0
  106. package/.codex-plugin/skills/session-plan/SKILL.md +22 -0
  107. package/.codex-plugin/skills/session-start/SKILL.md +22 -0
  108. package/.codex-plugin/skills/spinout/SKILL.md +21 -0
  109. package/.codex-plugin/skills/spinout/agents/openai.yaml +5 -0
  110. package/.codex-plugin/skills/sunset-review/SKILL.md +21 -0
  111. package/.codex-plugin/skills/sunset-review/agents/openai.yaml +5 -0
  112. package/.codex-plugin/skills/templates-ack/SKILL.md +21 -0
  113. package/.codex-plugin/skills/templates-ack/agents/openai.yaml +5 -0
  114. package/.codex-plugin/skills/test/SKILL.md +21 -0
  115. package/.codex-plugin/skills/test/agents/openai.yaml +5 -0
  116. package/.codex-plugin/skills/test-runner/SKILL.md +22 -0
  117. package/.codex-plugin/skills/tmux-layout/SKILL.md +23 -0
  118. package/.codex-plugin/skills/using-orchestrator/SKILL.md +19 -0
  119. package/.codex-plugin/skills/vault-mirror/SKILL.md +17 -0
  120. package/.codex-plugin/skills/vault-sync/SKILL.md +17 -0
  121. package/.codex-plugin/skills/wave-executor/SKILL.md +22 -0
  122. package/.codex-plugin/skills/write-executable-plan/SKILL.md +24 -0
  123. package/.cursor/commands/autopilot.md +2 -2
  124. package/.cursor/commands/bootstrap.md +1 -1
  125. package/.cursor/commands/brainstorm.md +1 -1
  126. package/.cursor/commands/debug.md +1 -1
  127. package/.cursor/commands/discovery.md +1 -1
  128. package/.cursor/commands/dispatcher.md +2 -2
  129. package/.cursor/commands/eli5.md +2 -2
  130. package/.cursor/commands/eval.md +2 -2
  131. package/.cursor/commands/evolve.md +1 -1
  132. package/.cursor/commands/go.md +1 -1
  133. package/.cursor/commands/grill.md +2 -2
  134. package/.cursor/commands/memory-cleanup.md +2 -2
  135. package/.cursor/commands/persona-panel.md +1 -1
  136. package/.cursor/commands/plan.md +1 -1
  137. package/.cursor/commands/portfolio.md +1 -1
  138. package/.cursor/commands/reconcile.md +2 -2
  139. package/.cursor/commands/release.md +2 -2
  140. package/.cursor/commands/session.md +2 -2
  141. package/.cursor/commands/spinout.md +2 -2
  142. package/.cursor/commands/sunset-review.md +2 -2
  143. package/.cursor/commands/templates-ack.md +2 -2
  144. package/.cursor/commands/test.md +2 -2
  145. package/.cursor/skills/brainstorm/SKILL.md +1 -1
  146. package/.cursor/skills/eval/SKILL.md +1 -1
  147. package/.cursor/skills/quality-gates/SKILL.md +1 -1
  148. package/.cursor/skills/remote-offload/SKILL.md +1 -1
  149. package/.cursor-plugin/plugin.json +30 -0
  150. package/.orchestrator/policy/blocked-commands.json +121 -0
  151. package/.orchestrator/policy/ecosystem.schema.json +66 -0
  152. package/.orchestrator/policy/quality-gates.example.json +16 -0
  153. package/.orchestrator/policy/quality-gates.schema.json +38 -0
  154. package/.orchestrator/policy/templates-policy.json +27 -0
  155. package/.orchestrator/policy/test-profiles.json +47 -0
  156. package/AGENTS.md +225 -0
  157. package/CHANGELOG.md +1314 -2
  158. package/NOTICE +11 -6
  159. package/README.md +135 -94
  160. package/agents/eval-judge.md +1 -1
  161. package/agents/skill-applied-judge.md +1 -1
  162. package/assets/wave-lifecycle.svg +98 -0
  163. package/commands/release.md +6 -3
  164. package/commands/session.md +18 -3
  165. package/docs/README.md +4 -0
  166. package/{agents/AGENTS.md → docs/agent-authoring.md} +19 -26
  167. package/docs/baseline.md +67 -0
  168. package/docs/ci-setup.md +108 -62
  169. package/docs/codex-setup.md +107 -29
  170. package/docs/components.md +38 -16
  171. package/docs/cursor-setup.md +6 -2
  172. package/docs/events-schema.md +9 -6
  173. package/docs/instruction-delivery.md +69 -0
  174. package/{agents/memory-proposal-collector.md → docs/memory-proposal-flow.md} +1 -8
  175. package/docs/migration-v4.md +365 -0
  176. package/docs/pi-setup.md +6 -1
  177. package/docs/plugin-architecture-v3.md +1 -1
  178. package/docs/rule-authoring.md +85 -19
  179. package/docs/scope-collision-guard.md +5 -5
  180. package/docs/session-config-reference.md +57 -56
  181. package/docs/session-config-template.md +6 -29
  182. package/docs/telemetry.md +157 -3
  183. package/docs/vault-docs-architecture.md +50 -11
  184. package/hooks/_lib/hook-import-set.json +1488 -0
  185. package/hooks/_lib/subagent-transcript.mjs +562 -0
  186. package/hooks/config-protection.mjs +2 -2
  187. package/hooks/cwd-change-restore.mjs +2 -2
  188. package/hooks/enforce-commands.mjs +69 -0
  189. package/hooks/hooks-codex.json +1 -1
  190. package/hooks/hooks-cursor.json +10 -0
  191. package/hooks/hooks-pi.json +5 -0
  192. package/hooks/hooks.json +6 -1
  193. package/hooks/loop-guard.mjs +3 -3
  194. package/hooks/on-session-end.mjs +2 -2
  195. package/hooks/on-session-start.mjs +103 -2
  196. package/hooks/on-stop.mjs +60 -14
  197. package/hooks/operator-steer.mjs +2 -2
  198. package/hooks/post-bash-write-verify.mjs +85 -0
  199. package/hooks/post-edit-import-probe.mjs +344 -0
  200. package/hooks/post-subagent-discovery-validator.mjs +187 -431
  201. package/hooks/post-tool-batch-wave-signal.mjs +118 -4
  202. package/hooks/post-tool-failure-corrective-context.mjs +2 -2
  203. package/hooks/post-tooluse-frontend-slop.mjs +3 -3
  204. package/hooks/pre-bash-destructive-guard.mjs +39 -13
  205. package/hooks/skill-invocation-telemetry.mjs +17 -5
  206. package/hooks/subagent-telemetry.mjs +13 -4
  207. package/monitors/monitors.json +3 -3
  208. package/package.json +9 -1
  209. package/pi/prompts/session.md +2 -2
  210. package/scripts/backfill-abandoned-sessions.mjs +50 -4
  211. package/scripts/backfill-learnings-from-vault.mjs +9 -3
  212. package/scripts/dialectic-deriver.mjs +73 -8
  213. package/scripts/export-hw-learnings.mjs +113 -1
  214. package/scripts/generate-agents-skills.mjs +378 -0
  215. package/scripts/generate-codex-skills.mjs +246 -0
  216. package/scripts/generate-cursor-adapter.mjs +45 -8
  217. package/scripts/generate-hook-import-set.mjs +292 -0
  218. package/scripts/lib/agent-status.mjs +13 -2
  219. package/scripts/lib/auto-dream.mjs +38 -36
  220. package/scripts/lib/autonomy/suitability.mjs +6 -0
  221. package/scripts/lib/autopilot/loop.mjs +2 -2
  222. package/scripts/lib/ci-status-banner.mjs +220 -75
  223. package/scripts/lib/codex/plugin-contract.mjs +88 -6
  224. package/scripts/lib/config/auto-dream.mjs +2 -1
  225. package/scripts/lib/config/block-header.mjs +8 -0
  226. package/scripts/lib/config/block-preprocess.mjs +177 -0
  227. package/scripts/lib/config/broken-window.mjs +2 -1
  228. package/scripts/lib/config/cold-start.mjs +2 -1
  229. package/scripts/lib/config/config-protection.mjs +22 -2
  230. package/scripts/lib/config/context-coverage.mjs +2 -1
  231. package/scripts/lib/config/cross-repo.mjs +2 -1
  232. package/scripts/lib/config/custom-phases.mjs +2 -1
  233. package/scripts/lib/config/dialectic.mjs +2 -1
  234. package/scripts/lib/config/discovery-validator.mjs +2 -1
  235. package/scripts/lib/config/dispatcher-autonomy-capture.mjs +24 -1
  236. package/scripts/lib/config/dispatcher-autonomy.mjs +2 -1
  237. package/scripts/lib/config/docs-orchestrator.mjs +2 -1
  238. package/scripts/lib/config/docs-staleness.mjs +2 -1
  239. package/scripts/lib/config/drift-check.mjs +2 -1
  240. package/scripts/lib/config/eval.mjs +2 -1
  241. package/scripts/lib/config/events-rotation.mjs +2 -1
  242. package/scripts/lib/config/evolve.mjs +8 -2
  243. package/scripts/lib/config/frontend-slop-hook.mjs +7 -3
  244. package/scripts/lib/config/gitlab-portfolio.mjs +2 -1
  245. package/scripts/lib/config/handover-gate.mjs +2 -1
  246. package/scripts/lib/config/health-endpoints.mjs +7 -2
  247. package/scripts/lib/config/host-paths.mjs +20 -4
  248. package/scripts/lib/config/issue-budget.mjs +2 -1
  249. package/scripts/lib/config/loop-guard.mjs +2 -1
  250. package/scripts/lib/config/memory.mjs +2 -1
  251. package/scripts/lib/config/moc-staleness.mjs +2 -1
  252. package/scripts/lib/config/persona-gate-wave.mjs +2 -1
  253. package/scripts/lib/config/private-config-dir.mjs +67 -0
  254. package/scripts/lib/config/reconcile.mjs +2 -1
  255. package/scripts/lib/config/remote-hosts.mjs +2 -1
  256. package/scripts/lib/config/section-extractor.mjs +7 -1
  257. package/scripts/lib/config/skill-evolution.mjs +2 -1
  258. package/scripts/lib/config/slopcheck.mjs +2 -1
  259. package/scripts/lib/config/state-md-lock.mjs +2 -1
  260. package/scripts/lib/config/templates-first.mjs +2 -1
  261. package/scripts/lib/config/test.mjs +2 -1
  262. package/scripts/lib/config/vault-integration.mjs +7 -1
  263. package/scripts/lib/config/vault-mirror-quality.mjs +2 -1
  264. package/scripts/lib/config/vault-staleness.mjs +2 -1
  265. package/scripts/lib/config/vault-sync.mjs +2 -1
  266. package/scripts/lib/config/verification-auto-fix.mjs +2 -1
  267. package/scripts/lib/config/wave-reviewers.mjs +2 -1
  268. package/scripts/lib/config/worktree-orphans.mjs +2 -1
  269. package/scripts/lib/convergence-monitor.mjs +82 -16
  270. package/scripts/lib/dispatcher/rank.mjs +124 -48
  271. package/scripts/lib/ecosystem-health.mjs +16 -2
  272. package/scripts/lib/eval/engine.mjs +9 -1
  273. package/scripts/lib/eval/session-resolve.mjs +23 -4
  274. package/scripts/lib/events.mjs +22 -6
  275. package/scripts/lib/frontmatter-guard.mjs +131 -13
  276. package/scripts/lib/gates/gate-full.mjs +30 -0
  277. package/scripts/lib/gates/gate-helpers.mjs +76 -0
  278. package/scripts/lib/hardware-pattern-detector.mjs +18 -1
  279. package/scripts/lib/harness-audit/categories/category4.mjs +31 -11
  280. package/scripts/lib/host-identity.mjs +50 -11
  281. package/scripts/lib/instruction-budget-guard.mjs +171 -5
  282. package/scripts/lib/learnings/evolve-telemetry.mjs +178 -0
  283. package/scripts/lib/learnings/io.mjs +60 -6
  284. package/scripts/lib/memory-proposals/store.mjs +30 -22
  285. package/scripts/lib/owner-config-banner.mjs +41 -6
  286. package/scripts/lib/owner-config-loader.mjs +21 -10
  287. package/scripts/lib/owner-interview.mjs +3 -3
  288. package/scripts/lib/owner-yaml.mjs +215 -15
  289. package/scripts/lib/platform.mjs +108 -15
  290. package/scripts/lib/plugin-update-banner.mjs +414 -0
  291. package/scripts/lib/project-hygiene.mjs +38 -2
  292. package/scripts/lib/qg-command-drift-banner.mjs +50 -12
  293. package/scripts/lib/quality-gate.mjs +133 -44
  294. package/scripts/lib/reconcile/emitter.mjs +68 -6
  295. package/scripts/lib/reconcile/engine.mjs +51 -11
  296. package/scripts/lib/reconcile/idempotency.mjs +37 -4
  297. package/scripts/lib/reconcile/writer.mjs +40 -18
  298. package/scripts/lib/session-close-backfill.mjs +67 -9
  299. package/scripts/lib/session-id.mjs +12 -23
  300. package/scripts/lib/session-identity/own-session.mjs +125 -10
  301. package/scripts/lib/session-lock-shape.mjs +43 -0
  302. package/scripts/lib/session-lock.mjs +5 -10
  303. package/scripts/lib/session-registry.mjs +25 -9
  304. package/scripts/lib/session-schema/constants.mjs +64 -3
  305. package/scripts/lib/session-schema/validator.mjs +38 -4
  306. package/scripts/lib/session-start-probes.mjs +30 -1
  307. package/scripts/lib/sessions-staleness-banner.mjs +18 -11
  308. package/scripts/lib/skill-health/join.mjs +17 -4
  309. package/scripts/lib/state-md.mjs +78 -0
  310. package/scripts/lib/sunset/walker.mjs +6 -0
  311. package/scripts/lib/telemetry/schema.mjs +202 -9
  312. package/scripts/lib/telemetry/sync.mjs +368 -12
  313. package/scripts/lib/telemetry-flush-health-banner.mjs +211 -0
  314. package/scripts/lib/validate/check-agents-skills.mjs +327 -0
  315. package/scripts/lib/validate/check-agents.mjs +3 -3
  316. package/scripts/lib/validate/check-codex-skills.mjs +191 -0
  317. package/scripts/lib/validate/check-cursor-adapter.mjs +234 -72
  318. package/scripts/lib/validate/check-hooks-symmetry.mjs +45 -16
  319. package/scripts/lib/validate/check-owner-leakage.mjs +319 -22
  320. package/scripts/lib/validate/check-skill-links.mjs +193 -0
  321. package/scripts/lib/validate/check-skill-script-paths.mjs +47 -28
  322. package/scripts/lib/validate/check-test-git-config-target.mjs +192 -12
  323. package/scripts/lib/validate/check-unwired-features.mjs +163 -15
  324. package/scripts/lib/validate/check-validator-registration.mjs +10 -4
  325. package/scripts/lib/validate/confidential-names.mjs +95 -30
  326. package/scripts/lib/validate/enumerate-repo-files.mjs +317 -0
  327. package/scripts/lib/validate/repo-files.mjs +48 -14
  328. package/scripts/lib/vault-backfill/template.mjs +63 -6
  329. package/scripts/lib/vault-mirror/process.mjs +165 -42
  330. package/scripts/lib/vault-mirror/telemetry.mjs +2 -2
  331. package/scripts/lib/vault-status/narrative-mirror.mjs +127 -18
  332. package/scripts/lib/wave-executor/dispatch-common.mjs +164 -0
  333. package/scripts/lib/wave-executor/foreign-dispatch.mjs +7 -142
  334. package/scripts/lib/wave-executor/remote-dispatch.mjs +5 -7
  335. package/scripts/lib/wave-resource-gate.mjs +8 -2
  336. package/scripts/lib/wave-sizing.mjs +4 -1
  337. package/scripts/lib/wave-transcript-tail.mjs +118 -4
  338. package/scripts/materialize-wave-scope.mjs +12 -5
  339. package/scripts/memory-propose.mjs +19 -5
  340. package/scripts/migrate-cold-start-seed.mjs +4 -1
  341. package/scripts/parse-config.mjs +60 -3
  342. package/scripts/release.mjs +430 -31
  343. package/scripts/repair-invalid-sessions.mjs +3 -3
  344. package/scripts/run-quality-gate.mjs +128 -11
  345. package/scripts/site-numbers.mjs +344 -8
  346. package/scripts/sweep-expired-learnings.mjs +90 -0
  347. package/scripts/sync-vault-schema.mjs +3 -1
  348. package/scripts/telemetry.mjs +2 -2
  349. package/scripts/validate-plugin.mjs +164 -0
  350. package/scripts/validate-wave-scope.mjs +28 -8
  351. package/scripts/wave-scope-binding.mjs +215 -0
  352. package/skills/_shared/instruction-file-resolution.md +10 -0
  353. package/skills/_shared/parallel-aware-preamble.md +1 -0
  354. package/skills/_shared/platform-tools.md +1 -1
  355. package/skills/_shared/state-ownership.md +1 -1
  356. package/skills/architecture/SKILL.md +7 -5
  357. package/skills/{domain-model/SKILL.md → architecture/references/domain-model.md} +9 -9
  358. package/skills/autopilot/SKILL.md +4 -18
  359. package/skills/claude-md-drift-check/SKILL.md +5 -1
  360. package/skills/claude-md-drift-check/checker.mjs +62 -2
  361. package/skills/convergence-monitoring/SIGNALS.md +55 -0
  362. package/skills/discovery/probes/vault-staleness.mjs +37 -13
  363. package/skills/discovery/probes-arch.md +20 -18
  364. package/skills/dispatcher/SKILL.md +3 -2
  365. package/skills/evolve/SKILL.md +65 -26
  366. package/skills/frontmatter-guard/SKILL.md +11 -5
  367. package/skills/npm-publish/SKILL.md +1 -1
  368. package/skills/reconcile/SKILL.md +33 -0
  369. package/skills/remote-offload/SKILL.md +1 -1
  370. package/skills/session-end/SKILL.md +18 -905
  371. package/skills/session-end/phase-3-6-tail.md +10 -3
  372. package/skills/session-end/plan-verification.md +221 -155
  373. package/skills/session-end/references/phase-2-quality-gate.md +93 -0
  374. package/skills/session-end/references/phase-3-documentation-updates.md +229 -0
  375. package/skills/session-end/references/phase-4a-worktree-cleanup.md +120 -0
  376. package/skills/session-end/references/phase-4b-worktree-orphan-sweep.md +58 -0
  377. package/skills/session-end/references/phase-5-issue-cleanup.md +104 -0
  378. package/skills/session-end/references/session-summary-template.md +62 -0
  379. package/skills/session-plan/SKILL.md +49 -0
  380. package/skills/session-start/SKILL.md +22 -904
  381. package/skills/session-start/phase-8-5-express-path.md +1 -1
  382. package/skills/session-start/references/phase-1-1-dispatcher-autonomy-capture.md +55 -0
  383. package/skills/session-start/references/phase-1-2-session-lock.md +140 -0
  384. package/skills/session-start/references/phase-1-5-session-continuity.md +254 -0
  385. package/skills/session-start/references/phase-1-7-vault-status-board.md +53 -0
  386. package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +75 -0
  387. package/skills/session-start/references/phase-4-ssot-environment-check.md +160 -0
  388. package/skills/session-start/references/phase-6-5-forced-reads.md +75 -0
  389. package/skills/session-start/references/phase-6-6-project-intelligence.md +81 -0
  390. package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +103 -0
  391. package/skills/vault-sync/SKILL.md +10 -0
  392. package/skills/vault-sync/validator.mjs +21 -27
  393. package/skills/wave-executor/SKILL.md +15 -1
  394. package/skills/wave-executor/references/wave-loop-dispatch.md +612 -0
  395. package/skills/wave-executor/references/wave-loop-review.md +570 -0
  396. package/skills/wave-executor/references/wave-loop-scope-manifest.md +162 -0
  397. package/skills/wave-executor/wave-loop.md +14 -1309
  398. package/templates/_shared/journey-manifest.md +10 -6
  399. package/.cursor/commands/autopilot-multi.md +0 -14
  400. package/.cursor/commands/contract-version-bump.md +0 -14
  401. package/.cursor/commands/journey-audit.md +0 -14
  402. package/.cursor/skills/contract-version-bump/SKILL.md +0 -12
  403. package/.cursor/skills/daily/SKILL.md +0 -12
  404. package/.cursor/skills/domain-model/SKILL.md +0 -13
  405. package/.cursor/skills/journey-audit/SKILL.md +0 -13
  406. package/.cursor/skills/skill-creator/SKILL.md +0 -13
  407. package/.cursor/skills/ubiquitous-language/SKILL.md +0 -13
  408. package/commands/autopilot-multi.md +0 -74
  409. package/commands/contract-version-bump.md +0 -28
  410. package/commands/journey-audit.md +0 -43
  411. package/pi/prompts/autopilot-multi.md +0 -12
  412. package/pi/prompts/contract-version-bump.md +0 -12
  413. package/pi/prompts/journey-audit.md +0 -12
  414. package/scripts/autopilot-multi.mjs +0 -885
  415. package/scripts/backfill-learnings-expires.mjs +0 -196
  416. package/scripts/backfill-learnings.mjs +0 -203
  417. package/scripts/fleet-instruction-scan.mjs +0 -141
  418. package/scripts/lib/autopilot/dep-graph.mjs +0 -417
  419. package/scripts/lib/autopilot/multi-killswitch.mjs +0 -184
  420. package/scripts/lib/webhook-url.mjs +0 -105
  421. package/scripts/lifecycle-sim-v6.mjs +0 -347
  422. package/scripts/migrate-learnings-jsonl.mjs +0 -189
  423. package/scripts/migrate-subagents-jsonl.mjs +0 -196
  424. package/scripts/upload-social-preview.mjs +0 -316
  425. package/skills/_shared/model-selection.md +0 -64
  426. package/skills/contract-version-bump/SKILL.md +0 -219
  427. package/skills/daily/SKILL.md +0 -222
  428. package/skills/daily/generate.sh +0 -92
  429. package/skills/daily/templates/daily.md.tpl +0 -36
  430. package/skills/journey-audit/SKILL.md +0 -270
  431. package/skills/skill-creator/SKILL.md +0 -168
  432. package/skills/ubiquitous-language/SKILL.md +0 -97
  433. package/skills/vault-sync/package-lock.json +0 -40
  434. /package/skills/{domain-model → architecture/references}/ADR-FORMAT.md +0 -0
  435. /package/skills/{domain-model → architecture/references}/CONTEXT-FORMAT.md +0 -0
@@ -632,6 +632,75 @@ Not read off the code — run, on two disjoint scopes, comparing the emitted sub
632
632
 
633
633
  ```console
634
634
  $ # hooks scope
635
+ ---
636
+
637
+ ## 8. Which harness reads which file (measured 2026-09-06)
638
+
639
+ > Survey of 8 agent harnesses, W1 d10/d11 of session `main-2026-09-06-deep-1`.
640
+ > The question this table settles: *when a foreign harness opens this repository,
641
+ > what does it actually load?*
642
+
643
+ | Harness | Instruction file | Skill discovery path |
644
+ |---|---|---|
645
+ | Claude Code | `CLAUDE.md` | plugin skills (`.claude-plugin/`) |
646
+ | Codex CLI | `AGENTS.md` | `.codex-plugin` skills |
647
+ | Cursor | `AGENTS.md` | `.agents/skills`, `.cursor/skills` |
648
+ | Copilot CLI | `AGENTS.md` **and** `CLAUDE.md` | `.github/skills`, `.claude/skills`, `.agents/skills` |
649
+ | OpenCode | `AGENTS.md` | `~/.claude/skills` |
650
+ | Amp | `AGENTS.md` | `.agents/skills` |
651
+ | Kiro | `AGENTS.md` | — |
652
+ | Gemini CLI | `GEMINI.md` | `skills/<name>/SKILL.md` layout |
653
+ | Pi | — | manifest skills |
654
+
655
+ **The finding.** 7 of 8 read `AGENTS.md`; exactly one (Claude Code) reads only
656
+ `CLAUDE.md`; exactly one (Copilot CLI) reads both. Measured the same day,
657
+ `git ls-files | grep -i AGENTS.md` returned only `agents/AGENTS.md` (the
658
+ sub-agent authoring spec) and one rule file — i.e. **this repo, opened in Codex
659
+ CLI, OpenCode, Kiro or Amp, could not find its own `## Session Config`.** The
660
+ gap was invisible from inside Claude Code, which is the only harness anyone here
661
+ develops in.
662
+
663
+ `.agents/skills/` is the intersection of the skill-discovery column: Cursor, Amp
664
+ and Copilot CLI all read it, so one generated mirror serves three harnesses.
665
+
666
+ ### 8.1 `AGENTS.md` is generated, never edited
667
+
668
+ The root `AGENTS.md` is a **byte-identical generated copy** of `CLAUDE.md`
669
+ (`scripts/generate-agents-skills.mjs`), gated by that script's `--check` inside
670
+ `scripts/validate-plugin.mjs`. Edit `CLAUDE.md` and regenerate; a hand-edit is a
671
+ CI failure. Hand-maintenance is not an option this repo gets to pick — #726
672
+ measured six divergent `AGENTS.md` strategies across the fleet.
673
+
674
+ A symlink was the smaller diff and was rejected on three measurements:
675
+ `package.json` `files[]` does not publish `CLAUDE.md` (a symlink would dangle in
676
+ the npm tarball); `core.symlinks` defaults to false on Windows without Developer
677
+ Mode, where git writes the link out as a 10-byte regular file containing the
678
+ literal text `CLAUDE.md`; and `git ls-files -s | awk '$1=="120000"'` returned
679
+ zero rows, so this repo — itself a template others copy — has no symlink
680
+ precedent. The drift gate still ACCEPTS a symlink, for consumer repos that
681
+ prefer one.
682
+
683
+ The `.agents/skills/` mirror carries only the six frontmatter fields
684
+ agentskills.io permits outside Claude Code (`name`, `description`, `license`,
685
+ `compatibility`, `metadata`, `allowed-tools`); our `tools:` spelling maps onto
686
+ `allowed-tools:`, and non-spec keys (`tags`, `model-preference*`, `color`,
687
+ `args-schema`, …) fold into `metadata` as strings. The body is a pointer at
688
+ `skills/<name>/SKILL.md`, never a copy of it — progressive disclosure keeps the
689
+ whole mirror at 47,380 bytes across 43 files.
690
+
691
+ These are the two artifacts emitted by `scripts/generate-agents-skills.mjs`. Plugin
692
+ manifests are maintained separately under `.claude-plugin/`, `.codex-plugin/` and
693
+ `.cursor-plugin/`; `scripts/release.mjs` updates their versions with `package.json`.
694
+ The initial 4.0.0 standard root `plugin.json` was moved to the native Cursor location
695
+ because it intercepted Codex's skill path and version selection; see
696
+ [Codex manifest compatibility](codex-setup.md#manifest-compatibility).
697
+
698
+ Codex has a separate generated surface: `scripts/generate-codex-skills.mjs` writes
699
+ `.codex-plugin/skills/` from the union of canonical command and skill names. Commands
700
+ win same-name overlaps, and each adapter reads the canonical document before dispatch.
701
+ The portable `.agents/skills/` mirrors continue to reference canonical skills directly;
702
+ they do not replace the installed Codex command entrypoints.
703
+
635
704
  ## Learnings Index (selected for your file scope)
636
705
 
637
706
  7 entries (3 matched your declared file scope, 4 general). One line each — this is an INDEX, not the corpus.
@@ -1,11 +1,4 @@
1
- ---
2
- name: memory-proposal-collector
3
- description: 'Reference documentation (NOT a dispatchable agent) for the coordinator-direct AUQ rendering flow at session-end Phase 3.6.3. The coordinator collects proposals from `.orchestrator/metrics/proposals.jsonl` via `collectProposals()` and renders the multiSelect AUQ in batches of 4. Approved proposals flow to `learnings.jsonl` with `_provenance: agent-proposed@<wave-id>` via `sink.writeApproved()`. AUQ is a coordinator-only tool — this flow does NOT dispatch as a subagent. <example>Context: session-end Phase 3.6.3, proposals.jsonl contains 5 entries from W2/W3 agents. user "Close the session." assistant "I''ll render the AUQ in 2 batches of 4 + 1, then route the user''s choices through writeApproved + archiveRejected per agents/memory-proposal-collector.md." <commentary>The collector flow is coordinator-direct because AskUserQuestion is unavailable inside subagents per .claude/rules/ask-via-tool.md AUQ-004.</commentary></example>'
4
- model: inherit
5
- color: cyan
6
- tools: Read, Grep, Glob
7
- sandbox-tier: read-only
8
- ---
1
+ <!-- Moved in v4.0.0 from `agents/memory-proposal-collector.md` (audit 2026-09-06 § 5A). It never was a dispatchable agent — it documents a coordinator-direct flow — but 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. Living under `docs/` removes the registration instead of bounding it. -->
9
2
 
10
3
  # Memory Proposal Collector (Reference Documentation)
11
4
 
@@ -0,0 +1,365 @@
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 integration | native manifests | generated root `AGENTS.md` + `.agents/skills/`; separate Claude, Codex and Cursor manifests |
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
+ The Codex command integration uses generated skills: search for `go` or `close` in the
130
+ picker and select the **Session Orchestrator** entry, or invoke `$session-orchestrator:go` and
131
+ `$session-orchestrator:close`. Refresh the installed plugin as above and restart Codex if
132
+ the new entries do not appear. The native `/goal` command is separate.
133
+
134
+ The initial 4.0.0 root Agent Plugins `plugin.json` has been replaced by a native Cursor
135
+ manifest. Read-only probes on Codex 0.153.3 and desktop runtime 0.153.4 showed that the
136
+ standard root manifest overrides Codex's declared skill directory and cache version.
137
+ The separate native manifests avoid that conflict; details are in
138
+ [Codex manifest compatibility](codex-setup.md#manifest-compatibility).
139
+
140
+ ### 3c. Cursor IDE
141
+
142
+ ```bash
143
+ cd ~/Projects/session-orchestrator
144
+ git pull && npm install
145
+ node scripts/cursor-install.mjs /path/to/your-project # links NEW commands/rules/skills only
146
+ # Restart Cursor
147
+ ```
148
+
149
+ **The installer adds new files; it never overwrites or removes an existing one.** `linkPath()`
150
+ skips whenever the destination already exists as a symlink or a file
151
+ (`scripts/cursor-install.mjs:69-73`), and the `hooks.json` writer skips outright when one is
152
+ already there (`:139-140`). Two consequences on this upgrade: the malformed `argument-hint` fix
153
+ (the 3.x generator wrote it into 24 of 28 command files, GH#54) reaches you for free through
154
+ your existing symlinks the moment `git pull` updates this checkout — no re-run needed for that.
155
+ But the three retired commands do **not** disappear from `.cursor/commands/` on their own, and a
156
+ `hooks.json` written before 4.0.0 is never synchronised with a new hook event automatically.
157
+ Both need the manual step in § 5 ("Cursor still shows the removed commands") below.
158
+
159
+ Cursor's plugin metadata now lives at `.cursor-plugin/plugin.json`, replacing the initial
160
+ 4.0.0 standard root `plugin.json`. The native manifest retains the canonical skills and
161
+ MCP paths and explicitly disables additional component discovery; the installer above
162
+ continues to supply commands and hooks. The shape follows the
163
+ [official Cursor manifest reference](https://cursor.com/docs/reference/plugins); native
164
+ Cursor loading was not runtime-tested during this compatibility repair.
165
+
166
+ ### 3d. Pi
167
+
168
+ ```bash
169
+ pi install npm:session-orchestrator
170
+ ```
171
+
172
+ Or against a local checkout:
173
+
174
+ ```bash
175
+ cd ~/Projects/session-orchestrator
176
+ git pull && npm install
177
+ node scripts/pi-install.mjs /path/to/your-project --settings-only
178
+ ```
179
+
180
+ `pi/prompts/` drops from 28 to 25 files, matching `commands/`.
181
+
182
+ ### 3e. Verify
183
+
184
+ Run `/session housekeeping` in any configured repo. You should see the session-start banner;
185
+ `/contract-version-bump`, `/journey-audit` and `/autopilot-multi` should no longer be offered.
186
+ Then:
187
+
188
+ ```bash
189
+ node scripts/parse-config.mjs --json # now works — in 3.x this failed with "File not found: --json"
190
+ node scripts/validate-plugin.mjs
191
+ ```
192
+
193
+ ## 4. What Stays the Same
194
+
195
+ **Your state is untouched. There is no migration step and no format change.**
196
+
197
+ - **`.orchestrator/` in every repo** — `metrics/sessions.jsonl`, `metrics/learnings.jsonl`,
198
+ `metrics/events.jsonl`, `current-session.json`, `session.lock`, `state.lock`, filescopes and
199
+ wave-scope manifests are all read-write compatible in both directions. Nothing is rewritten
200
+ on upgrade, and nothing 4.0.0 writes is unreadable by 3.24.0.
201
+ - **`STATE.md`** — same frontmatter schema. 4.0.0 adds ONE optional scalar,
202
+ `session-profile`, and absent is not empty: a STATE.md without it behaves exactly as before.
203
+ A 3.x build reading a 4.0.0 STATE.md simply ignores the extra key.
204
+ - **Session Config in `CLAUDE.md` / `AGENTS.md` / Cursor rules** — no key you are likely using
205
+ is renamed or given a new default. Two keys ARE removed — `autopilot.bg-isolation` and
206
+ `webhooks.<kind>.url` — see § 1a above; everything else you configured in 3.x is still
207
+ correct as-is.
208
+ - **Session memory** (`~/.claude/projects/<project>/memory/`) — untouched.
209
+ - **`session-type`** — still the closed set `housekeeping` / `feature` / `deep`. `ultradeep`
210
+ is an argument ALIAS that resolves to `session-type: deep` plus
211
+ `session-profile: ultradeep`; it is deliberately not a fourth type, because a fourth member
212
+ would degrade silently in the telemetry mapper and the close-backfiller.
213
+ - **The whole core loop** — `/session`, `/go`, `/close`, `/plan`, `/discovery`, `/evolve`,
214
+ `/bootstrap`, `/debug`, `/autopilot` and the other remaining commands take the same
215
+ arguments and run the same flow.
216
+ - **VCS integration** — `glab` / `gh` commands, label taxonomy, issue and MR templates.
217
+
218
+ ## 5. Known Issues & Workarounds
219
+
220
+ ### Your CLAUDE.md cites a removed skill
221
+
222
+ **Nothing breaks at runtime.** A citation in a consumer repo's `CLAUDE.md` (or `AGENTS.md`) to
223
+ `daily`, `skill-creator`, `ubiquitous-language`, `contract-version-bump`, `journey-audit`,
224
+ `domain-model` or `skills/_shared/model-selection.md` is prose. No loader resolves it, no hook
225
+ reads it, and the session starts normally.
226
+
227
+ **But `claude-md-drift-check` may flag it** as a dangling citation, and if you run it with
228
+ `enforcement: strict` that finding is an error rather than a warning. Two ways out, both fine:
229
+
230
+ 1. Delete or rewrite the citation. `domain-model` becomes
231
+ `skills/architecture/references/domain-model.md`; the other five have no successor, so the
232
+ sentence usually goes away with the skill.
233
+ 2. Leave it and accept the warning until your next docs pass. It is a documentation-parity
234
+ finding, not a functional one.
235
+
236
+ Same story for a rule file or ADR that names one of the removed scripts.
237
+
238
+ ### A wrapper script or Routine calls a removed top-level script
239
+
240
+ `node scripts/<name>.mjs` on any of the eight removed scripts now exits with a Node
241
+ `ERR_MODULE_NOT_FOUND`-class failure — a loud error, not a silent no-op. If a cron job,
242
+ Routine or CI step calls one, delete that step: the two `migrate-*` scripts had already
243
+ completed their one-shot migration, and the two `backfill-learnings*` scripts their one-shot
244
+ repair, before this release.
245
+
246
+ ### A dashboard suddenly reports far fewer "sessions stopped"
247
+
248
+ Expected, and it was wrong before, not now. See § 1b — you were counting turns. Match on
249
+ `orchestrator.turn.stopped`, or better, count `session.started` ids for sessions and
250
+ `sessions.jsonl` records with `status: completed` for closes.
251
+
252
+ ### `npm install` fails with `ERESOLVE` or peer-dep warnings
253
+
254
+ Use Node 24 or later, matching `engines.node: ">=24.0.0"`. If it persists:
255
+ `npm install --legacy-peer-deps`.
256
+
257
+ ### Hooks silently no-op after the update
258
+
259
+ Node must be on `PATH` inside the **editor** process, not only in your terminal. Verify from
260
+ inside Claude Code with `!node --version`. This is unchanged from v3.
261
+
262
+ ### Cursor still shows the removed commands
263
+
264
+ Re-running the installer does **not** fix this: `linkPath()` skips any destination that already
265
+ exists (`scripts/cursor-install.mjs:69-73`), including a stale symlink pointing at a command
266
+ that no longer exists in this repo. Remove only the three dead **symlinks** from your project —
267
+ never an unconditional `rm -f`, which would just as happily delete a regular file, including a
268
+ command you wrote yourself under one of these three names (the installer itself never overwrites
269
+ or deletes a regular file; this recipe must not either):
270
+
271
+ ```bash
272
+ for f in autopilot-multi contract-version-bump journey-audit; do
273
+ p=/path/to/your-project/.cursor/commands/$f.md
274
+ [ -L "$p" ] && rm "$p" # -L: true only for a symlink, so a real file with this name survives
275
+ done
276
+ ```
277
+
278
+ `[ -L "$p" ]` checks the destination's TYPE, not who created it — it removes any symlink at that
279
+ path regardless of origin. If you separately symlinked your own command under one of these three
280
+ names, this recipe deletes that symlink too; a regular (non-symlink) file is the only thing it
281
+ leaves untouched.
282
+
283
+ Then restart Cursor. Same story for `.cursor/hooks.json`: the installer skips it outright once
284
+ it exists (`:139-140`), so a `hooks.json` written before 4.0.0 is never re-synced with a new hook
285
+ event automatically — re-check it by hand (diff it against a fresh `node scripts/cursor-install.mjs`
286
+ run in an empty scratch directory if you suspect drift).
287
+
288
+ ## 6. Rollback
289
+
290
+ 4.0.0 removes surfaces; it does not migrate data. **Rolling back is therefore a plain version
291
+ switch — no state has to be converted, and nothing you wrote under 4.0.0 becomes unreadable.**
292
+
293
+ **Claude Code / plugin cache.** A marketplace install tracks the marketplace's current
294
+ version; this repo documents no version-pin flag for `/plugin install`, so do not guess one.
295
+ Roll back by pointing Claude Code at a local clone parked on the old tag:
296
+
297
+ ```bash
298
+ git clone https://github.com/Kanevry/session-orchestrator ~/so-3.24.0
299
+ cd ~/so-3.24.0 && git checkout v3.24.0 && npm install
300
+ ```
301
+
302
+ Then, inside Claude Code, remove the marketplace-installed copy and add the clone as the
303
+ plugin source (`/plugin marketplace add ~/so-3.24.0`, then install from it) and restart the
304
+ editor. If you are unsure of the exact `/plugin` subcommands on your build, run `/plugin`
305
+ with no arguments — it lists them.
306
+
307
+ **Local checkout (Codex / Cursor / Pi / maintainer):**
308
+
309
+ ```bash
310
+ cd /path/to/session-orchestrator
311
+ git fetch --tags
312
+ git checkout v3.24.0
313
+ npm install # the 3.24.0 lockfile, not the 4.0.0 one
314
+ node scripts/codex-install.mjs # Codex — no target-project argument
315
+ node scripts/cursor-install.mjs /path/to/your-project # Cursor — pass YOUR project, not this checkout
316
+ node scripts/pi-install.mjs /path/to/your-project --settings-only # Pi — same argument contract
317
+ # Restart your editor
318
+ ```
319
+
320
+ Run only the line for your platform. `cursor-install.mjs` and `pi-install.mjs` both default their
321
+ target to `process.cwd()` when no argument is given (`scripts/cursor-install.mjs:24-51`) — omit
322
+ the project path here and the installer links into `/path/to/session-orchestrator` itself, not
323
+ into your project.
324
+
325
+ **npm consumers:** `npm install session-orchestrator@3.24.0`.
326
+
327
+ What you get back, and what you do not:
328
+
329
+ - **Your state survives in both directions.** `sessions.jsonl`, `learnings.jsonl`,
330
+ `events.jsonl` and `STATE.md` written by 4.0.0 are readable by 3.24.0. The one 4.0.0
331
+ addition to STATE.md, `session-profile`, is an unknown key to 3.24.0 and is ignored, not
332
+ rejected.
333
+ - **`orchestrator.turn.stopped` records written under 4.0.0 stay in your `events.jsonl` after
334
+ a rollback.** 3.24.0 does not know the name and will not count them; the
335
+ `orchestrator.session.stopped` twin of every one of those records is right beside it, so no
336
+ data is lost — only a 3.x reader sees each turn once instead of twice.
337
+ - **The removed skills, commands and scripts come back with the checkout.** They were deleted
338
+ from the repository, not from your disk history.
339
+ - **What does NOT roll back automatically** is anything an installer wrote into YOUR project:
340
+ `.cursor/commands/`, `.cursor/hooks.json`, Pi settings. The two installers behave
341
+ differently: `cursor-install.mjs` skips any destination that already exists — a symlink or a
342
+ file (`scripts/cursor-install.mjs:69-73`; the `hooks.json` writer at `:139-140`) — and
343
+ re-creates only the ones that are MISSING, so re-running it from the 3.24.0 checkout only
344
+ **adds** command links missing from your project; it does not restore a link you removed
345
+ yourself and does not resync an existing `hooks.json`.
346
+ `pi-install.mjs --settings-only` **does** rewrite the Pi settings file: it reads it, upserts
347
+ this package's entry and writes it back (`scripts/pi-install.mjs` `upsertPackage` /
348
+ `writeSettings`), so re-running it from the 3.24.0 checkout re-points Pi at that checkout.
349
+ For Cursor, to get a removed link back: delete the stale file first (§ "Cursor still shows the
350
+ removed commands" has a safe, symlink-only removal recipe), then re-run the installer with
351
+ your project path, as shown above.
352
+
353
+ If 4.0.0 blocks you, please open an issue describing the blocker before rolling back — a
354
+ removal we got wrong is fixable in a 4.0.x patch.
355
+
356
+ ## 7. Support
357
+
358
+ - **GitHub:** [Kanevry/session-orchestrator/issues](https://github.com/Kanevry/session-orchestrator/issues)
359
+ — preferred for bugs and feature requests.
360
+ - **Homepage:** [session-orchestrator.com](https://session-orchestrator.com)
361
+
362
+ When filing a bug, include `node --version`, your OS and arch, the harness (Claude Code /
363
+ Codex CLI / Cursor / Pi), the plugin version actually running (the session-start banner prints
364
+ it), and a minimal reproduction. For hook failures, attach the relevant entries from
365
+ `.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 documented for Pi packages (`pi install git:github.com/user/repo`) is **unverified against this repo as of 2026-08-28** the `pi` CLI was not installed on the verifying host (`which pi` not found), so no install attempt could be made. The npm form above remains the only measured, documented install path; do not elevate the `git:` short form to this guide or to README until it has been run against this repo and the result dated.
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`, `SO_STATE_DIR`, `detectPlatform()` |
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) |
@@ -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) (~L80107) is the **single source of truth** for every learning `type`'s TTL policy and its two cross-module capability flags. 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.
197
+ `LEARNING_TYPE_REGISTRY` in [`scripts/lib/learnings/schema.mjs`](../scripts/lib/learnings/schema.mjs) (~L92127) 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)