session-orchestrator 5.11.0 → 5.13.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 (394) hide show
  1. package/.claude-plugin/marketplace.json +12 -1
  2. package/.claude-plugin/plugin.json +4 -1
  3. package/.codex-plugin/agents/explorer.toml +1 -1
  4. package/.codex-plugin/agents/session-reviewer.toml +2 -2
  5. package/.codex-plugin/agents/wave-worker.toml +1 -1
  6. package/.codex-plugin/plugin.json +1 -1
  7. package/.cursor-plugin/plugin.json +1 -1
  8. package/.orchestrator/policy/blocked-commands.json +8 -0
  9. package/.orchestrator/policy/public-export.json +30 -0
  10. package/CHANGELOG.md +180 -3
  11. package/README.md +126 -117
  12. package/agents/analyst.md +7 -2
  13. package/agents/architect-reviewer.md +7 -2
  14. package/agents/code-implementer.md +4 -2
  15. package/agents/db-specialist.md +9 -2
  16. package/agents/dialectic-deriver.md +9 -3
  17. package/agents/docs-writer.md +7 -2
  18. package/agents/eval-judge.md +7 -1
  19. package/agents/qa-strategist.md +7 -2
  20. package/agents/security-reviewer.md +9 -2
  21. package/agents/session-reviewer.md +18 -2
  22. package/agents/skill-applied-judge.md +7 -1
  23. package/agents/test-writer.md +9 -2
  24. package/agents/ui-developer.md +9 -2
  25. package/agents/ux-evaluator.md +6 -1
  26. package/commands/session.md +4 -2
  27. package/commands/templates-ack.md +89 -18
  28. package/docs/agent-authoring.md +30 -11
  29. package/docs/ci-setup.md +38 -2
  30. package/docs/codex-setup.md +33 -9
  31. package/docs/components.md +13 -2
  32. package/docs/cursor-setup.md +3 -3
  33. package/docs/events-schema.md +5 -4
  34. package/docs/evidence-candidates.md +63 -0
  35. package/docs/fleet-checkin-audit.md +7 -4
  36. package/docs/github-mirror-protection.md +150 -3
  37. package/docs/install.md +102 -25
  38. package/docs/instruction-delivery.md +1 -1
  39. package/docs/migration-v4.md +2 -2
  40. package/docs/mods.md +118 -0
  41. package/docs/owner-config-schema.md +1 -0
  42. package/docs/plugin-architecture-v3.md +1 -1
  43. package/docs/pm-skills-marketplace.md +4 -3
  44. package/docs/rule-authoring.md +24 -13
  45. package/docs/scope-collision-guard.md +2 -1
  46. package/docs/session-config-reference.md +55 -21
  47. package/docs/session-config-template.md +32 -24
  48. package/docs/sessions-ledger-repair.md +137 -0
  49. package/docs/vault-docs-architecture.md +1 -1
  50. package/hooks/_lib/hook-import-set.json +406 -73
  51. package/hooks/_lib/hook-root.mjs +301 -0
  52. package/hooks/_lib/lock-bootstrap.mjs +434 -4
  53. package/hooks/_lib/orchestrator-ignore.mjs +3 -0
  54. package/hooks/_lib/subagent-transcript.mjs +2 -2
  55. package/hooks/_lib/vcs-create-matcher.mjs +13 -17
  56. package/hooks/cwd-change-restore.mjs +5 -1
  57. package/hooks/enforce-commands.mjs +4 -3
  58. package/hooks/enforce-scope.mjs +11 -1
  59. package/hooks/hooks-codex.json +48 -2
  60. package/hooks/hooks.json +31 -31
  61. package/hooks/on-session-end.mjs +38 -15
  62. package/hooks/on-session-start.mjs +158 -59
  63. package/hooks/on-stop.mjs +11 -6
  64. package/hooks/post-bash-issue-budget-refund.mjs +6 -1
  65. package/hooks/post-bash-write-verify.mjs +8 -4
  66. package/hooks/post-edit-validate.mjs +45 -52
  67. package/hooks/post-subagent-discovery-validator.mjs +2 -2
  68. package/hooks/post-tool-batch-wave-signal.mjs +8 -4
  69. package/hooks/post-tool-failure-corrective-context.mjs +5 -1
  70. package/hooks/pre-bash-destructive-guard.mjs +220 -8
  71. package/hooks/pre-bash-issue-budget.mjs +6 -1
  72. package/hooks/pre-bash-sessions-ledger-guard.mjs +691 -123
  73. package/hooks/pre-bash-staging-fence.mjs +258 -14
  74. package/hooks/pre-bash-templates-first.mjs +28 -27
  75. package/hooks/run-node.sh +1 -1
  76. package/hooks/skill-invocation-telemetry.mjs +15 -8
  77. package/hooks/subagent-telemetry.mjs +77 -14
  78. package/hooks/wave-scope-commit-guard.mjs +143 -14
  79. package/mods/so-hud/.claude-plugin/plugin.json +11 -0
  80. package/mods/so-hud/README.md +57 -0
  81. package/mods/so-hud/hooks/beacon-io.mjs +101 -0
  82. package/mods/so-hud/hooks/heredoc-scan.ts +394 -0
  83. package/mods/so-hud/hooks/hooks.json +1 -0
  84. package/mods/so-hud/hooks/logic.ts +182 -0
  85. package/mods/so-hud/hooks/register.tsx +670 -0
  86. package/mods/so-hud/hooks/rules.ts +2998 -0
  87. package/mods/so-hud/tsconfig.json +8 -0
  88. package/mods/so-hud/types/index.d.ts +36 -0
  89. package/package.json +4 -3
  90. package/rules/_index.md +1 -1
  91. package/rules/always-on/ask-via-tool.md +1 -1
  92. package/rules/always-on/loop-and-monitor.md +17 -194
  93. package/rules/always-on/parallel-sessions.md +3 -1
  94. package/rules/opt-in-stack/backend-data.md +1 -1
  95. package/rules/opt-in-stack/backend.md +1 -1
  96. package/rules/opt-in-stack/security-web.md +5 -1
  97. package/scripts/agent-usage-census.mjs +79 -0
  98. package/scripts/apply-session-learnings.mjs +34 -6
  99. package/scripts/archive-closed-prds.mjs +21 -5
  100. package/scripts/autopilot.mjs +11 -5
  101. package/scripts/backfill-abandoned-sessions.mjs +13 -3
  102. package/scripts/backfill-evidence-digest.mjs +2 -1
  103. package/scripts/backfill-learnings-from-vault.mjs +61 -6
  104. package/scripts/backfill-sessions.mjs +16 -2
  105. package/scripts/check-package-manager.mjs +26 -8
  106. package/scripts/check-sessions-integrity.mjs +4 -1
  107. package/scripts/ci/assert-vitest-green.mjs +3 -0
  108. package/scripts/ci/windows-smoke.mjs +201 -0
  109. package/scripts/close-precheck.mjs +55 -0
  110. package/scripts/dialectic-deriver.mjs +20 -12
  111. package/scripts/emit-event.mjs +2 -2
  112. package/scripts/emit-session.mjs +239 -20
  113. package/scripts/eval-session.mjs +17 -3
  114. package/scripts/export-hw-learnings.mjs +29 -2
  115. package/scripts/fleet-checkin-audit.mjs +8 -4
  116. package/scripts/fleet-checkin.mjs +73 -3
  117. package/scripts/gc-stale-worktrees.mjs +6 -1
  118. package/scripts/github-export.mjs +128 -0
  119. package/scripts/github-protection-audit.mjs +3 -1
  120. package/scripts/handover-queue-check.mjs +209 -0
  121. package/scripts/harness-audit.mjs +6 -4
  122. package/scripts/lib/agent-frontmatter.mjs +57 -10
  123. package/scripts/lib/agent-status.mjs +125 -7
  124. package/scripts/lib/agent-usage-census.mjs +394 -0
  125. package/scripts/lib/auto-dialectic.mjs +17 -10
  126. package/scripts/lib/auto-dream.mjs +22 -14
  127. package/scripts/lib/autopilot/loop.mjs +3 -1
  128. package/scripts/lib/autopilot/recent-runs.mjs +4 -2
  129. package/scripts/lib/autopilot/stall-sampler.mjs +2 -1
  130. package/scripts/lib/autopilot/telemetry.mjs +5 -1
  131. package/scripts/lib/autopilot/worktree-pipeline.mjs +5 -5
  132. package/scripts/lib/baseline-archetypes.mjs +10 -2
  133. package/scripts/lib/blocked-commands-policy.mjs +4 -3
  134. package/scripts/lib/build-live-signals.mjs +13 -9
  135. package/scripts/lib/ci-status-banner.mjs +329 -24
  136. package/scripts/lib/codex/plugin-contract.mjs +8 -0
  137. package/scripts/lib/cold-start-detector.mjs +5 -2
  138. package/scripts/lib/command-blocker.mjs +603 -43
  139. package/scripts/lib/common.mjs +3 -2
  140. package/scripts/lib/config/cross-repo.mjs +74 -7
  141. package/scripts/lib/config/host-paths.mjs +6 -2
  142. package/scripts/lib/config/remote-hosts.mjs +2 -2
  143. package/scripts/lib/config/section-extractor.mjs +65 -11
  144. package/scripts/lib/config/template-keys.mjs +153 -0
  145. package/scripts/lib/config/vault-integration.mjs +1 -0
  146. package/scripts/lib/config.mjs +3 -3
  147. package/scripts/lib/coordinator-snapshot.mjs +1 -1
  148. package/scripts/lib/discovery/triage-state.mjs +2 -1
  149. package/scripts/lib/dispatcher/rank.mjs +5 -7
  150. package/scripts/lib/ecosystem-health.mjs +2 -2
  151. package/scripts/lib/eval/engine.mjs +3 -2
  152. package/scripts/lib/eval/session-resolve.mjs +6 -2
  153. package/scripts/lib/eval/sink.mjs +4 -3
  154. package/scripts/lib/events-retention-banner.mjs +3 -2
  155. package/scripts/lib/events-schema.mjs +10 -0
  156. package/scripts/lib/events.mjs +23 -12
  157. package/scripts/lib/evolve/autonomy-verdict.mjs +4 -9
  158. package/scripts/lib/evolve/autopilot-effectiveness.mjs +8 -18
  159. package/scripts/lib/fleet-protocol.mjs +21 -0
  160. package/scripts/lib/gates/gate-full.mjs +172 -11
  161. package/scripts/lib/gates/gate-helpers.mjs +236 -23
  162. package/scripts/lib/git-config-drift.mjs +141 -7
  163. package/scripts/lib/github-export.mjs +447 -0
  164. package/scripts/lib/gitlab-portfolio/cli.mjs +16 -5
  165. package/scripts/lib/handover-queue-marks.mjs +159 -0
  166. package/scripts/lib/hardware-pattern-detector.mjs +103 -13
  167. package/scripts/lib/harness-audit/categories/category1.mjs +16 -4
  168. package/scripts/lib/harness-audit/categories/category4.mjs +11 -8
  169. package/scripts/lib/harness-audit/categories/category6.mjs +25 -5
  170. package/scripts/lib/harness-audit/categories/category9.mjs +10 -4
  171. package/scripts/lib/host-identity.mjs +9 -5
  172. package/scripts/lib/http-request.mjs +64 -0
  173. package/scripts/lib/instruction-budget-guard.mjs +30 -22
  174. package/scripts/lib/io.mjs +6 -3
  175. package/scripts/lib/issue-budget-reconcile.mjs +3 -2
  176. package/scripts/lib/issue-budget.mjs +36 -7
  177. package/scripts/lib/learnings/evidence-candidates.mjs +154 -0
  178. package/scripts/lib/learnings/expiry-sweep.mjs +99 -7
  179. package/scripts/lib/learnings/io.mjs +289 -15
  180. package/scripts/lib/learnings/select.mjs +53 -4
  181. package/scripts/lib/learnings/store-role.mjs +209 -0
  182. package/scripts/lib/learnings/surface.mjs +46 -7
  183. package/scripts/lib/ledger-path.mjs +113 -0
  184. package/scripts/lib/maintenance-due-banner.mjs +63 -12
  185. package/scripts/lib/memory-banner.mjs +5 -6
  186. package/scripts/lib/memory-proposals/collector.mjs +5 -2
  187. package/scripts/lib/memory-proposals/sink.mjs +7 -4
  188. package/scripts/lib/memory-proposals/store.mjs +22 -5
  189. package/scripts/lib/mode-selector-accuracy.mjs +2 -1
  190. package/scripts/lib/no-follow-open.mjs +57 -0
  191. package/scripts/lib/orphan-reaper/reaper-audit.mjs +4 -2
  192. package/scripts/lib/own-lock-root.mjs +95 -0
  193. package/scripts/lib/owner-interview.mjs +2 -1
  194. package/scripts/lib/owner-yaml.mjs +70 -7
  195. package/scripts/lib/platform.mjs +161 -9
  196. package/scripts/lib/plugin-update-banner.mjs +15 -11
  197. package/scripts/lib/pre-push-local-partial.mjs +117 -0
  198. package/scripts/lib/pre-push-remote-gate.mjs +151 -25
  199. package/scripts/lib/process-group.mjs +270 -34
  200. package/scripts/lib/project-hygiene.mjs +28 -0
  201. package/scripts/lib/quality-gate.mjs +33 -9
  202. package/scripts/lib/reconcile/backlog.mjs +29 -15
  203. package/scripts/lib/reconcile/engine.mjs +26 -2
  204. package/scripts/lib/reconcile/idempotency.mjs +65 -3
  205. package/scripts/lib/reconcile/rule-expiry-sweep.mjs +53 -12
  206. package/scripts/lib/reconcile/verdict-ledger.mjs +224 -0
  207. package/scripts/lib/reconcile-nudge-banner.mjs +40 -6
  208. package/scripts/lib/resource-probe/evaluate.mjs +32 -9
  209. package/scripts/lib/resource-probe/probe-platform.mjs +3 -1
  210. package/scripts/lib/rule-loader.mjs +20 -10
  211. package/scripts/lib/scope-baseline.mjs +123 -8
  212. package/scripts/lib/scope-echo.mjs +5 -2
  213. package/scripts/lib/scope-gate.mjs +55 -20
  214. package/scripts/lib/session-close-backfill.mjs +75 -7
  215. package/scripts/lib/session-end/close-precheck.mjs +151 -0
  216. package/scripts/lib/session-end/phase-skip.mjs +8 -7
  217. package/scripts/lib/session-end/tail-runner.mjs +7 -2
  218. package/scripts/lib/session-end/vault-orphans.mjs +205 -0
  219. package/scripts/lib/session-id.mjs +9 -1
  220. package/scripts/lib/session-identity/own-session.mjs +63 -0
  221. package/scripts/lib/session-invocation.mjs +14 -3
  222. package/scripts/lib/session-lock.mjs +114 -0
  223. package/scripts/lib/session-record-repair.mjs +245 -35
  224. package/scripts/lib/session-registry.mjs +85 -12
  225. package/scripts/lib/session-schema/constants.mjs +9 -0
  226. package/scripts/lib/session-schema/filters.mjs +56 -1
  227. package/scripts/lib/session-schema/validator.mjs +15 -5
  228. package/scripts/lib/session-start-probes.mjs +149 -22
  229. package/scripts/lib/session-token-rollup.mjs +2 -1
  230. package/scripts/lib/session-work-trees.mjs +166 -0
  231. package/scripts/lib/sessions-canonical.mjs +61 -3
  232. package/scripts/lib/sessions-integrity-banner.mjs +17 -39
  233. package/scripts/lib/sessions-staleness-banner.mjs +8 -5
  234. package/scripts/lib/sh-quote.mjs +1 -0
  235. package/scripts/lib/skill-evidence-window.mjs +5 -1
  236. package/scripts/lib/skill-health/join.mjs +10 -9
  237. package/scripts/lib/skill-invocations-schema.mjs +13 -0
  238. package/scripts/lib/skill-judgments-schema.mjs +6 -2
  239. package/scripts/lib/snapshot-probe.mjs +414 -0
  240. package/scripts/lib/so-hud/collect.mjs +174 -0
  241. package/scripts/lib/so-hud/runtime.mjs +87 -0
  242. package/scripts/lib/spiral-carryover.mjs +8 -1
  243. package/scripts/lib/state-md/frontmatter-mutators.mjs +266 -8
  244. package/scripts/lib/state-md/idle-reset.mjs +248 -0
  245. package/scripts/lib/state-md/mission-status.mjs +5 -1
  246. package/scripts/lib/state-md/recommendations.mjs +26 -4
  247. package/scripts/lib/state-md-peer-guard.mjs +2 -0
  248. package/scripts/lib/state-md.mjs +31 -8
  249. package/scripts/lib/sunset/walker.mjs +4 -3
  250. package/scripts/lib/telemetry/consent.mjs +4 -2
  251. package/scripts/lib/telemetry/queue.mjs +3 -3
  252. package/scripts/lib/telemetry/sync.mjs +45 -9
  253. package/scripts/lib/test-runner/artifact-paths.mjs +10 -2
  254. package/scripts/lib/tmux-layout/layouts.mjs +20 -3
  255. package/scripts/lib/ux-grill/paths.mjs +5 -1
  256. package/scripts/lib/validate/check-agents.mjs +37 -6
  257. package/scripts/lib/validate/check-component-paths.mjs +25 -1
  258. package/scripts/lib/validate/check-guard-requires-parity.mjs +3 -3
  259. package/scripts/lib/validate/check-hooks-symmetry.mjs +53 -32
  260. package/scripts/lib/validate/check-json-files.mjs +3 -1
  261. package/scripts/lib/validate/check-learning-provenance.mjs +3 -2
  262. package/scripts/lib/validate/check-learnings-shell-writes.mjs +10 -4
  263. package/scripts/lib/validate/check-metrics-ledger-root.mjs +234 -0
  264. package/scripts/lib/validate/check-owner-leakage.mjs +159 -11
  265. package/scripts/lib/validate/check-test-posix-shell.mjs +246 -0
  266. package/scripts/lib/validate/check-unwired-features.mjs +4 -2
  267. package/scripts/lib/validate/check-vcs-repo-flag-positional.mjs +58 -0
  268. package/scripts/lib/validate/check-vcs-repo-flag.mjs +259 -73
  269. package/scripts/lib/validate/check-workflow-continue-on-error.mjs +63 -0
  270. package/scripts/lib/validate/confidential-names.mjs +3 -1
  271. package/scripts/lib/vault-mirror/migrate-ids.mjs +321 -0
  272. package/scripts/lib/vault-mirror/namespace.mjs +22 -9
  273. package/scripts/lib/vault-mirror/process.mjs +197 -65
  274. package/scripts/lib/vault-mirror/prune.mjs +5 -2
  275. package/scripts/lib/vault-mirror/render-learnings.mjs +8 -7
  276. package/scripts/lib/vault-mirror/render-sessions.mjs +36 -53
  277. package/scripts/lib/vault-mirror/retention.mjs +2 -2
  278. package/scripts/lib/vault-mirror/utils.mjs +106 -13
  279. package/scripts/lib/vault-staleness-banner.mjs +4 -7
  280. package/scripts/lib/vault-status/board-writer.mjs +34 -5
  281. package/scripts/lib/vault-status/narrative-mirror.mjs +66 -7
  282. package/scripts/lib/wave-executor/foreign-dispatch.mjs +20 -0
  283. package/scripts/lib/win-process-tree.mjs +137 -0
  284. package/scripts/lib/workspace.mjs +1 -1
  285. package/scripts/lib/worktree/constants.mjs +1 -1
  286. package/scripts/lib/worktree/lifecycle.mjs +1 -1
  287. package/scripts/lib/worktree/listing.mjs +1 -1
  288. package/scripts/lib/zx.mjs +50 -0
  289. package/scripts/mcp-server.mjs +16 -7
  290. package/scripts/mcp-server.sh +13 -83
  291. package/scripts/measure-policy-cache-effectiveness.mjs +7 -5
  292. package/scripts/memory-propose.mjs +10 -3
  293. package/scripts/migrate-cold-start-seed.mjs +7 -0
  294. package/scripts/migrate-legacy-learnings.sh +22 -0
  295. package/scripts/migrate-sessions-jsonl.mjs +16 -2
  296. package/scripts/migrate-vault-paths.mjs +29 -13
  297. package/scripts/parse-config.mjs +71 -14
  298. package/scripts/print-learnings-index.mjs +25 -2
  299. package/scripts/release-session-lock.mjs +94 -7
  300. package/scripts/release.mjs +451 -24
  301. package/scripts/relocate-vault-corpus.mjs +11 -7
  302. package/scripts/repair-invalid-sessions.mjs +68 -3
  303. package/scripts/resolve-session-invocation.mjs +57 -8
  304. package/scripts/run-migrate-v2-cross-repo.mjs +56 -1
  305. package/scripts/run-quality-gate.mjs +33 -7
  306. package/scripts/self-update.mjs +56 -7
  307. package/scripts/session-commit-files.mjs +133 -0
  308. package/scripts/site-numbers.mjs +52 -9
  309. package/scripts/snapshot-probe.mjs +156 -0
  310. package/scripts/so-hud.mjs +68 -0
  311. package/scripts/state-md-idle-reset.mjs +82 -0
  312. package/scripts/sweep-expired-learnings.mjs +54 -6
  313. package/scripts/sweep-expired-rules.mjs +4 -1
  314. package/scripts/validate-plugin.mjs +22 -0
  315. package/scripts/vault-integration-watcher.mjs +54 -6
  316. package/scripts/vault-mirror.mjs +9 -0
  317. package/scripts/vault-orphans.mjs +171 -0
  318. package/skills/_shared/fleet-protocol.md +166 -3
  319. package/skills/_shared/instruction-file-resolution.md +1 -1
  320. package/skills/_shared/monitor-patterns.md +44 -25
  321. package/skills/_shared/platform-tools.md +7 -0
  322. package/skills/_shared/state-ownership.md +5 -4
  323. package/skills/architecture/references/domain-model.md +1 -1
  324. package/skills/autopilot/SKILL.md +3 -2
  325. package/skills/bootstrap/SKILL.md +3 -1
  326. package/skills/bootstrap/_shared-template.md +4 -4
  327. package/skills/bootstrap/fast-template.md +1 -1
  328. package/skills/bootstrap/private-contract.md +1 -1
  329. package/skills/bootstrap/references/bootstrap-retroactive-flow.md +17 -9
  330. package/skills/bootstrap/templates/agents/project-code-review.md +5 -1
  331. package/skills/bootstrap/templates/agents/project-discovery.md +5 -1
  332. package/skills/bootstrap/templates/agents/project-quality-gate.md +5 -1
  333. package/skills/claude-md-drift-check/SKILL.md +3 -3
  334. package/skills/claude-md-drift-check/checker.mjs +61 -101
  335. package/skills/close/SKILL.md +20 -7
  336. package/skills/discovery/probes/docs-staleness.mjs +7 -5
  337. package/skills/discovery/probes/frontend-slop.mjs +7 -3
  338. package/skills/discovery/probes/ssot-code-diff.mjs +5 -3
  339. package/skills/discovery/probes/supply-chain-slopcheck.mjs +10 -8
  340. package/skills/discovery/probes/vault-narrative-staleness.mjs +30 -10
  341. package/skills/discovery/probes/vault-staleness.mjs +5 -3
  342. package/skills/discovery/probes-session.md +3 -0
  343. package/skills/discovery/probes-vault.md +2 -0
  344. package/skills/dispatcher/SKILL.md +1 -1
  345. package/skills/eval/SKILL.md +3 -1
  346. package/skills/evolve/SKILL.md +2 -0
  347. package/skills/evolve/references/evolve-analyze-mode.md +3 -3
  348. package/skills/evolve/references/evolve-dialectic-mode.md +1 -1
  349. package/skills/gitlab-ops/SKILL.md +7 -6
  350. package/skills/gitlab-portfolio/SKILL.md +2 -2
  351. package/skills/go/SKILL.md +13 -1
  352. package/skills/npm-publish/SKILL.md +5 -2
  353. package/skills/plan/SKILL.md +23 -10
  354. package/skills/plan/mode-feature.md +13 -8
  355. package/skills/plan/mode-new.md +6 -14
  356. package/skills/plan/prd-feature-template.md +19 -0
  357. package/skills/plan/prd-full-template.md +12 -5
  358. package/skills/plan/prd-premortem-panel.md +48 -0
  359. package/skills/plan/prd-reviewer-prompt.md +11 -3
  360. package/skills/plan/soul.md +1 -1
  361. package/skills/portfolio/SKILL.md +5 -6
  362. package/skills/quality-gates/SKILL.md +2 -4
  363. package/skills/reconcile/SKILL.md +27 -4
  364. package/skills/release/SKILL.md +16 -8
  365. package/skills/session-end/SKILL.md +97 -13
  366. package/skills/session-end/phase-3-2-docs-verification.md +1 -0
  367. package/skills/session-end/phase-3-6-tail.md +11 -7
  368. package/skills/session-end/phase-3-7a-recommendations.md +9 -2
  369. package/skills/session-end/plan-verification.md +16 -1
  370. package/skills/session-end/references/phase-3-7e-vault-orphans.md +63 -0
  371. package/skills/session-end/references/phase-3-documentation-updates.md +25 -13
  372. package/skills/session-end/references/phase-5-issue-cleanup.md +1 -1
  373. package/skills/session-end/references/session-summary-template.md +8 -0
  374. package/skills/session-end/session-metrics-write.md +7 -4
  375. package/skills/session-plan/SKILL.md +5 -3
  376. package/skills/session-start/SKILL.md +10 -4
  377. package/skills/session-start/phase-4-5-resource-health.md +11 -5
  378. package/skills/session-start/phase-7-5-mode-selector.md +3 -1
  379. package/skills/session-start/phase-8-5-express-path.md +4 -3
  380. package/skills/session-start/references/phase-1-2-session-lock.md +7 -5
  381. package/skills/session-start/references/phase-1-5-session-continuity.md +13 -5
  382. package/skills/session-start/references/phase-1-7-vault-status-board.md +1 -1
  383. package/skills/session-start/references/phase-4-ssot-environment-check.md +3 -2
  384. package/skills/tmux-layout/SKILL.md +2 -2
  385. package/skills/vault-sync/validator.mjs +3 -2
  386. package/skills/wave-executor/SKILL.md +5 -4
  387. package/skills/wave-executor/references/wave-executor-state-init.md +3 -3
  388. package/skills/wave-executor/references/wave-loop-dispatch.md +11 -5
  389. package/skills/wave-executor/references/wave-loop-review.md +13 -5
  390. package/skills/wave-executor/references/wave-loop-scope-manifest.md +1 -1
  391. package/AGENTS.md +0 -207
  392. package/assets/og-card.png +0 -0
  393. package/assets/og-card.svg +0 -47
  394. package/assets/wave-lifecycle.svg +0 -98
@@ -75,7 +75,14 @@ die vom Lease-Validator akzeptierte `adresse` einer aktiven Lease, sonst `null`
75
75
  Lease, kein Eintrag oder ein abgelehnter Wert — nie ein ungeprüfter String). `fallback_due_at` ist
76
76
  der Zeitpunkt, ab dem die Standard-Auflagen (unten) gelten, in der Form von `zeit` (Code:
77
77
  `fallbackDueAt()`); er steht nur auf stdout, die Check-in-Datei behält ihr Schema. Exit 0
78
- geschrieben, 2 ungültige Eingabe (Fehlerliste auf stderr, keine Datei), 1 Schreibfehler.
78
+ geschrieben, 2 ungültige Eingabe (Fehlerliste auf stderr, keine Datei) oder semantische Session-ID
79
+ von einem anderen Repo belegt (eine Zeile auf stderr mit JSON-escaped Repo-Namen, fremde Datei unverändert,
80
+ tmp entfernt, kein Event), 1 Schreibfehler.
81
+ Vor dem `rename` lehnt der Schreiber ein vorhandenes String-`repo` ungleich dem eigenen ab;
82
+ gleiches `repo`, unlesbare Dateien und ungültiges JSON dürfen überschrieben werden.
83
+ Die Prüfung folgt keinen Symlinks, öffnet nichtblockierend und liest nur reguläre Dateien
84
+ bis 64 KiB. Symlinks, andere Dateitypen, größere Dateien oder fehlende sichere Open-Flags
85
+ gelten für diese Prüfung als unlesbar (fail-open zum `rename`).
79
86
 
80
87
  | Feld | Inhalt |
81
88
  |---|---|
@@ -99,6 +106,146 @@ nur wenn die Lease aktiv ist und `navigator_adresse` (stdout der Check-in-CLI) n
99
106
  `ListAgents` erreichbar ist, und nur an genau diesen Namen; nie eine Antwort
100
107
  erwarten, nie darauf warten (CSM-004).
101
108
 
109
+ ## Rücklauf an den Navigator (Pflicht)
110
+
111
+ In jedem Warte-Zug, den eine Eingabe ausgelöst hat (Anstoß der Owner-Inbox, Nachricht vom Lead,
112
+ Nachricht vom Owner, auch ein Befehl wie `/go` oder `/close`) — keine Arbeit gefunden, Blocker länger
113
+ als 15 min, `/go` oder `/close` ohne Plan, fertig, nur noch Zug/Pipeline offen — genau eine Meldung
114
+ an den Koordinator, im Zug der Warte-Antwort selbst: Session (`<name>`, unten), Wartefall
115
+ (`keine-arbeit`, `blocker-<issue>`, `go-ohne-plan`, `close-ohne-plan`, `fertig`, `zug-<name>`), seit
116
+ wann (Uhr aus `date`, die lokale Systemzeit des Hosts), was gebraucht wird. Auch wenn derselbe Fall
117
+ in einem früheren Zug schon gemeldet wurde (Resume, Verdichtung, erneuter Anstoß): Die Owner-Inbox
118
+ lässt eine Session nur ruhen, wenn sie im Zug ihrer letzten Antwort gemeldet hat (SendMessage oder
119
+ `owner-queue add`) UND diese Antwort als Warte-Antwort erkennt; eine unterdrückte Wiederholung hält
120
+ sie wach und führt zu stündlichen Anstößen (#1611). Ausgenommen sind Züge, die keine Eingabe
121
+ ausgelöst hat: Weckungen durch `/loop`, ein Monitor-Ereignis, ein eigener Hintergrund-Agent oder eine
122
+ eigene Hintergrund-Shell, ScheduleWakeup. Sie melden nicht erneut: solange ein Monitor oder
123
+ Hintergrund-Lauf offen ist, stößt die Inbox ohnehin nicht an; nach einer Weckung durch `/loop` oder
124
+ ScheduleWakeup holt der nächste Anstoß die Meldung nach. Flotte und Lease lesend messen, ohne Check-in zu schreiben
125
+ (derselbe Helfer `readNavigatorLease()`, aus dem die Check-in-CLI `navigator_adresse` gewinnt):
126
+
127
+ ```bash
128
+ node --input-type=module -e "const { pathToFileURL } = await import('node:url'); const m = await import(pathToFileURL(process.argv[1]).href); const r = await m.readNavigatorLease(); console.log(JSON.stringify({flotte: m.fleetIntegrationEnabled(), state: r.state, adresse: r.lease?.adresse ?? null}))" "${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-$PLUGIN_ROOT}}/scripts/lib/fleet-protocol.mjs"
129
+ ```
130
+
131
+ `flotte: false` (§ Verhalten ohne Flotte): keine Meldung, keine Datei; hier endet der Abschnitt.
132
+ Sonst die Meldung über eine Rückfallkette; die nächste Stufe greift, sobald die vorige nicht greift
133
+ oder scheitert:
134
+
135
+ 1. `state: active`, `adresse` nicht `null` und per `ListAgents` erreichbar: eine `SendMessage` an
136
+ genau diese Adresse. Werkzeugfehler oder unbekannte Adresse: weiter mit Stufe 2.
137
+ 2. Sonst (Lease `none` oder `unreadable`, keine oder keine erreichbare Adresse, Stufe 1
138
+ gescheitert): ein Lead-Todo in der owner-queue des Koordinators, `<repo>` wie das Check-in-Feld
139
+ `repo`, Titel mit `<name>` (unten) und dem, worauf die Session wartet. Exit 4 heißt „ähnlicher
140
+ offener Eintrag liegt schon in der Queue“. Der Befehl selbst muss Exit 0 und 4 auf Exit 0
141
+ normalisieren: Claude Code markiert jeden Exit ungleich 0 als Werkzeugfehler (`is_error`), und
142
+ einen gescheiterten Aufruf zählt die Owner-Inbox nicht als Meldung. Pflichtform:
143
+
144
+ ```bash
145
+ navigator owner-queue add --repo <repo> --kind lead-todo --waits-on lead --title '<name>: <worauf die Session wartet>'; rc=$?; [ "$rc" -eq 0 ] || [ "$rc" -eq 4 ] || { echo "Meldung gescheitert: owner-queue add exit $rc" >&2; exit "$rc"; }
146
+ ```
147
+
148
+ `navigator` ist die CLI des Koordinators (lead-session-orchestrator: Binary `navigator`); nennt
149
+ die Steuerungsregel des Koordinators im Systemprompt der Session einen Aufrufpfad, gilt dieser.
150
+ Einen eigenen Pfad zum Koordinator-Repo nicht raten.
151
+ 3. Scheitert auch Stufe 2 (Exit weder 0 noch 4, z. B. 127, weil `navigator` nicht im `PATH` liegt):
152
+ der letzte Absatz der Antwort nennt sichtbar `Meldung gescheitert: <Grund>` (Stufe, Exit-Code
153
+ oder Fehlertext), vor dem Wartesatz. Still warten ist nie zulässig.
154
+
155
+ **Wartesatz.** Jede Warte-Antwort endet mit einem Satz, den der Koordinator als Warte-Antwort
156
+ erkennt (letzte 600 Zeichen ohne Code-Blöcke, kein `?` am Ende des letzten Absatzes, Muster wie
157
+ unter Übergabe Punkt 3): `Bereit zum Schließen.`, wenn die Übergabe unten gilt, sonst
158
+ `Ich warte auf den nächsten Auftrag.` Eine Meldung oder Statuszeile allein (etwa
159
+ `/go: kein Plan vorhanden – nichts ausgeführt`) erkennt er nicht.
160
+
161
+ **Flotten-Ordner und Session-Name.** Beide stehen im eigenen Eintrag der Claude-Session-Registry
162
+ `~/.claude/sessions/<pid>.json`, dem mit `sessionId` gleich `$CLAUDE_CODE_SESSION_ID`:
163
+
164
+ ```bash
165
+ jq -c --arg id "$CLAUDE_CODE_SESSION_ID" 'select(.sessionId == $id) | {name, cwd, startedAt}' ~/.claude/sessions/*.json
166
+ ```
167
+
168
+ `<name>` ist das Feld `name` (der Peer-Name, z. B. `session-orchestrator-cf`; fehlt es, die ersten
169
+ acht Zeichen von `sessionId`), nicht `session_id` und nicht `semantic_session_id`. Der Flotten-Ordner
170
+ ist `<cwd>/.orchestrator/runtime/fleet/` mit dem `cwd`, der im Moment des Schreibens in diesem
171
+ Eintrag steht: den Befehl unmittelbar davor ausführen, nie einen früher gemessenen Wert nehmen. Nach
172
+ `EnterWorktree` zeigt `cwd` auf den Worktree, und dort sucht der Koordinator. `/close` kann einen
173
+ auto-promoteten Worktree samt der Datei darin entfernen (session-end Phase 4a); die Datei entsteht
174
+ deshalb erst mit der Meldung, und der Koordinator liest sie vor dem Abschluss.
175
+
176
+ **Übergabe und Zug-Manifest.** Nur mit Flottenintegration (`flotte: true` in derselben Messung),
177
+ auch ohne aktive Lease: der Koordinator schließt eine von ihm geführte Session, sobald ihre Übergabe
178
+ vorliegt, ohne die Lease zu prüfen. Und nur in der Warte- oder Fertig-Antwort außerhalb von
179
+ session-end (Phase start oder go: das Abschluss-Ergebnis des wave-executor, das Ende des Express Path,
180
+ `/go` ohne Plan, keine Arbeit). Ist die Session fertig oder wartet sie nur noch auf einen Release-Zug oder eine Pipeline
181
+ und hat keine andere Arbeit:
182
+
183
+ 1. Im selben Zug wie diese Antwort schreibt sie selbst mit dem Datei-Werkzeug des Harness (Claude
184
+ Code: Write), nicht per Shell, in den Flotten-Ordner: fertig die Übergabe
185
+ `uebergabe-<name>-an-<Nachfolger>.md` (ohne Nachfolger `uebergabe-<name>.md`), bei Zug oder
186
+ Pipeline das Zug-Manifest `<name>-zug-<zugname>.md` — enthaltene MRs, Köpfe, Migrationen,
187
+ manuelle Jobs, Nachkontrolle, Rückweg, offene Themen. Der Koordinator erkennt nur genau diese
188
+ Namen (`uebergabe-<name>.md`, `uebergabe-<name>-….md`, `<name>-zug-….md`) und nur eine Datei, die
189
+ die Session im Zug ihrer letzten Antwort nachweislich selbst geschrieben hat. Vorher
190
+ `git -C <cwd> check-ignore --no-index -q .orchestrator/runtime/fleet/<datei>` prüfen: Exit 1
191
+ (nicht ignoriert) hält das Schreiben nicht auf — der Koordinator braucht die Datei genau
192
+ dort —, aber Meldung und Antwort nennen „ungetrackte Datei in <repo>:
193
+ .orchestrator/runtime/fleet/<datei>“. Kein Ausweichen in einen anderen Ordner.
194
+ 1a. **Jeder offene Punkt trägt eine Vorgangsmarke (#1639).** Jeder Listenpunkt unter einer
195
+ Überschrift, die mit „Offen“, „Nachkontrolle“, „Folge“ oder „Danach“ beginnt (ohne „erledigt“ im
196
+ Titel), endet mit `queue:#<id>`. Hat der Punkt schon ein GitLab-Issue und braucht keinen
197
+ Zeitpunkt, endet er stattdessen mit `issue:#<iid>`. Erledigte Punkte stehen als `[x]` da. Fehlt die
198
+ Marke, legt die Session den Vorgang vor dem Schreiben an
199
+ (`navigator owner-queue add --repo <repo> … --title '<name>: <punkt>'`, `<repo>` wie oben):
200
+ Prüfung nach Merge oder Zug `--kind nachsorge --waits-on lead --ref <repo>!<iid>`; Folgearbeit,
201
+ Termin oder Nachfolge-Session `--kind lead-todo --waits-on lead` (mit `--not-before`/`--due`
202
+ bei Termin oder Frist); Versprechen an einen Peer `--kind zusage --waits-on peer:<session>`;
203
+ Owner-Frage wie bisher als Entscheid mit `--options`, `--recommendation`, `--class`. Exit 0 und 4
204
+ gelten als Erfolg; bei 4 die ID des vorhandenen Vorgangs übernehmen (`--json` liefert sie als
205
+ `ids`). Danach prüft sie die geschriebene Datei mechanisch:
206
+
207
+ ```bash
208
+ node "${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-$PLUGIN_ROOT}}/scripts/handover-queue-check.mjs" --file <cwd>/.orchestrator/runtime/fleet/<datei> --name <name> --since <startedAt> --apply --repo <repo> --navigator-cli <koordinator-cli>
209
+ ```
210
+
211
+ `<koordinator-cli>` ist der Aufrufpfad der Koordinator-CLI aus der Steuerungsregel (eine `.js`-Datei
212
+ läuft unter node), sonst entfällt die Option und `navigator` aus dem `PATH` gilt. `--apply` legt
213
+ für jeden Punkt ohne Marke den Vorgang an (Nachkontrolle als `nachsorge`, sonst `lead-todo`, Ref
214
+ aus dem ersten `!N`/`#N` im Punkt, nur wenn die CLI ihn annimmt) und schreibt `queue:#<id>` in die
215
+ Datei. Punkte unter einer Überschrift mit „Owner“ oder „Entscheid“ legt es nie an, es meldet sie:
216
+ Owner-Fragen brauchen einen Entscheid mit Optionen und Klasse. `--apply` verlangt `--name`
217
+ (sonst Exit 2) und schreibt nur in die eigene Datei (`uebergabe-<name>.md`,
218
+ `uebergabe-<name>-*.md`, `<name>-zug-*.md`); eine fremde Datei, einen Symlink oder eine Datei
219
+ älter als `--since` (Vorgänger gleichen Namens) lehnt es unverändert ab (Exit 4), nie in einer
220
+ Schleife über den Flotten-Ordner aufrufen. Hat es Vorgänge
221
+ angelegt, die Datei danach lesen und mit dem Datei-Werkzeug unverändert neu schreiben: der
222
+ Koordinator erkennt nur eine selbst geschriebene Datei. Exit 3 heißt, Punkte bleiben ohne Marke
223
+ (die Liste steht in der Ausgabe): dann nennen Meldung und Antwort „Übergabe ohne Queue-IDs: <n>
224
+ Punkte“, und die Antwort endet mit `Ich warte auf den nächsten Auftrag.`, nicht mit dem Satz aus
225
+ Schritt 3. Ohne Flottenintegration prüft das Skript nichts (Exit 0).
226
+ 2. Mit jeder weiteren Warte-Antwort schreibt sie die Datei neu, auch wenn sie aus einem früheren Zug
227
+ schon dasteht, so wie sie in jedem Warte-Zug neu meldet.
228
+ 3. Sie meldet „bereit zum Schließen“ (in der Meldung dieses Zugs) und beendet
229
+ die Antwort mit genau diesem Satz: `Bereit zum Schließen.` Der Koordinator erkennt eine Warte-
230
+ oder Fertig-Antwort nur in ihren letzten 600 Zeichen (Code-Blöcke zählen nicht mit); ein langer
231
+ Bericht mit dem Satz weiter oben schließt nicht. Der letzte Absatz endet nicht auf `?`, und die
232
+ letzten 400 Zeichen enthalten weder `soll ich` noch `weiter mit`, `welche option` oder
233
+ `freigabe für`: sonst gilt die Antwort als Frage an den Owner, und es schließt ebenfalls nicht.
234
+ Auch eine Verneinung („noch nicht bereit zum Schließen“) zählt dort als Fertig-Antwort: nie ans
235
+ Ende stellen. Sie beginnt nichts Neues und beendet Monitore, Hintergrund-Shells und
236
+ Hintergrund-Agenten (Claude Code: TaskStop); solange einer läuft, gilt sie als nicht fertig.
237
+ 4. Sie schließt nicht selbst: `/close` ist nicht modell-aufrufbar (`disable-model-invocation`), und
238
+ den Abschluss löst der Koordinator aus. session-end (Phase 4.5) meldet im Zug von `/close` genau
239
+ einmal den Fall `zug-<name>` (eigener Warte-Zug, gewollt) und schreibt keine Datei.
240
+ Das gilt auch für den Express Path (session-start Phase 8.5, `skills/go/SKILL.md`): mit
241
+ Flottenintegration ruft `/go` session-end nicht selbst auf, sondern endet nach Deviation-Eintrag
242
+ mit Meldung, Übergabe und Wartesatz wie oben (#1620). Ohne Flottenintegration bleibt der
243
+ Express Path beim eigenen Abschluss.
244
+
245
+ Ohne Flottenintegration keine Meldung, keine Übergabe-Datei und kein Manifest. Nie auf Antwort
246
+ warten, nie eine Entscheidung an einer Antwort festmachen (CSM-004); eine Meldung ist keine Freigabe
247
+ (ADR-002). Schließen nur über session-end, nie durch handgeschriebene Metriken.
248
+
102
249
  ## `auflagen/<session_id>.json` — Navigator an Session
103
250
 
104
251
  Bedingungen, die der Navigator einer Session schreibt (z. B. Agent-Caps, volle Pipelines je Repo,
@@ -130,15 +277,31 @@ aktiven Navigator ist `fallback_due_at` gleich `zeit`, die Auflagen gelten also
130
277
  Lesende Arbeit und Schreiben im eigenen Worktree laufen währenddessen weiter; der Rückfall ist ein
131
278
  Dateistand mit Frist, kein Warten auf eine Antwort.
132
279
 
280
+ ## Verhalten ohne Flotte
281
+
282
+ Flottenintegration liegt vor, wenn `NAVIGATOR_CONFIG_DIR` gesetzt und nicht leer ist (ausdrückliches
283
+ Opt-in, auch vor dem ersten Anlegen) oder `~/.config/navigator/` als Verzeichnis existiert (Code:
284
+ `fleetIntegrationEnabled()`, #1559). Ein Flottenhost hat das Verzeichnis, weil der Koordinator dort
285
+ die Lease schreibt. Ohne Flottenintegration validiert `fleet-checkin.mjs` die Eingabe wie immer
286
+ (ungültig → Exit 2), schreibt dann aber nichts, legt kein Verzeichnis an, emittiert kein Event und
287
+ meldet `{"ok":true,"skipped":"no-fleet",…}`. Es gelten keine Auflagen, auch keine Standard-Auflagen:
288
+ ohne Flotte gibt es nichts zu koordinieren. Die Navigator-Zeile im Sessionstart-Banner entfällt
289
+ ebenso. Das gilt auch für `plattform: kopflos`: der Datensatz beweist keinen Koordinator, und ein
290
+ Schreiben legte das Verzeichnis an, das danach jede Solo-Session zur Flotte macht. Ein kopfloser
291
+ Lauf ohne Flottenintegration wendet stattdessen die Standard-Auflagen sofort an — er kann niemanden
292
+ fragen. Ein Flotten-Starter, der auf einem frischen Remote-Host startet, setzt deshalb
293
+ `NAVIGATOR_CONFIG_DIR` oder legt das Verzeichnis vorher an.
294
+
133
295
  ## Verhalten ohne Navigator
134
296
 
135
- Lease `none` oder `unreadable`: die Check-in-Datei wird **trotzdem** geschrieben (sie ist der
297
+ Flottenintegration vorhanden, Lease `none` oder `unreadable`: die Check-in-Datei wird **trotzdem** geschrieben (sie ist der
136
298
  zählbare Beleg), die Standard-Auflagen gelten sofort, es geht keine Nachricht ab. Kopflose Läufe
137
299
  sind per Nachricht nicht erreichbar und nutzen dieselben Dateien: vor jeder Welle `auflagen/` lesen.
138
300
 
139
301
  ## See Also
140
302
 
141
303
  `skills/session-start/SKILL.md` Phase 7.6 · `skills/session-start/references/operations-contract.md`
142
- (Peer-Preflight) · `skills/_shared/state-ownership.md` § Session Identity and Lock Ownership (`role`) ·
304
+ (Peer-Preflight) · Rücklauf-Verweise: `skills/go/SKILL.md` § No plan to execute, `skills/close/SKILL.md`, `skills/wave-executor/SKILL.md` § Completion,
305
+ `skills/session-end/SKILL.md` Phase 4.5 · `skills/_shared/state-ownership.md` § Session Identity and Lock Ownership (`role`) ·
143
306
  `docs/events-schema.md` (`orchestrator.fleet.checkin`) · `.claude/rules/cross-session-messaging.md`
144
307
  (CSM-003/004) · `scripts/lib/fleet-protocol.mjs` · `scripts/fleet-checkin.mjs`
@@ -33,7 +33,7 @@ Apply these steps in order against the repo root. Stop at the first hit. Never m
33
33
  Since the cross-harness portable surface landed, this repo carries BOTH files at its root. That does not weaken the rule above — it is what makes the rule safe to hold while still serving foreign readers:
34
34
 
35
35
  - **Our own readers still never read both.** `resolveInstructionFile()` picks exactly one (`CLAUDE.md` wins ties), and every consumer listed below goes through it. Nothing merges, diffs, or cross-validates the two as sources.
36
- - **The root `AGENTS.md` exists for FOREIGN readers**, not for ours. 7 of 8 surveyed harnesses (Codex CLI, Cursor, Copilot CLI, OpenCode, Amp, Kiro, …) read `AGENTS.md`; only Claude Code reads `CLAUDE.md`, and only Copilot CLI reads both. Without a root `AGENTS.md` this repo's `## Session Config` was unreachable from six of them.
36
+ - **The root `AGENTS.md` exists for FOREIGN readers**, not for ours. 7 of 8 surveyed harnesses (Codex CLI, Cursor, Copilot CLI, OpenCode, Amp, Kiro, …) read `AGENTS.md`. Claude Code reads `CLAUDE.md`; Copilot CLI and Cursor read both (Cursor per its rules help, checked 2026-10-21; the 2026-09-06 survey had it as `AGENTS.md` only). Without a root `AGENTS.md` this repo's `## Session Config` was unreachable from six of them.
37
37
  - **It is byte-identical by construction, and generated.** `scripts/generate-agents-skills.mjs` copies `CLAUDE.md` verbatim; `--check` (wired into `scripts/validate-plugin.mjs`) fails CI on any divergence. **Never edit `AGENTS.md`** — edit `CLAUDE.md` and regenerate. A consumer repo may instead symlink it; both shapes are accepted by the drift gate.
38
38
  - **Why a copy and not a symlink here:** `package.json` `files[]` does not publish `CLAUDE.md`, so a symlink would be DANGLING in the npm tarball; and `core.symlinks` defaults to false on Windows without Developer Mode, where git materialises the link as a 10-byte regular file containing the literal text `CLAUDE.md` — a pointer with no Session Config, which is precisely the failure this file guards against.
39
39
  - **The invariant is "the two cannot disagree", not "exactly one file exists."** `claude-md-drift-check` Check 7 (`vault-dir-parity`) enforces it: alias-by-construction → parity satisfied; two independent files that diverge → error. Check 9's probe 2a uses the same predicate so a defect in `CLAUDE.md` is never reported twice.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Vetted Monitor-tool snippets for the recurring observation points in the
4
4
  > session-orchestrator workflow. Each snippet ships with the description
5
- > string, recommended timeout / persistent flag, and an explicit failure
5
+ > string, recommended timeout, and an explicit failure
6
6
  > coverage note (per the **silence-is-not-success** rule from
7
7
  > `.claude/rules/loop-and-monitor.md`).
8
8
 
@@ -10,8 +10,9 @@
10
10
 
11
11
  Anthropic recommends `Monitor` over `/loop` for any stream-able event
12
12
  (https://code.claude.com/docs/en/scheduled-tasks). The Monitor tool turns
13
- each stdout line into a notification, avoiding poll-token cost. But a
14
- naïve filter that matches only the success marker reads identical to a
13
+ each output or exit event into one notification, avoiding poll-token cost.
14
+ Output may contain multiple stdout lines; it is not a notification per line.
15
+ A naïve filter that matches only the success marker reads identical to a
15
16
  crash — silent. The snippets below are calibrated to emit on **every
16
17
  terminal state**, not just the happy path.
17
18
 
@@ -21,6 +22,27 @@ coverage check.
21
22
 
22
23
  ---
23
24
 
25
+ ## Deadline and re-arm (Claude Code v2.1.271+)
26
+
27
+ Every Monitor watch has a deadline: 5 minutes by default, at most 30 minutes
28
+ (10 in single-prompt `-p` runs). The former no-timeout option was removed. At
29
+ the deadline the watch ends and Claude gets one exit notice, so the coordinator
30
+ re-arms the same snippet if the watch is still needed. Output and exit each
31
+ produce one notification; an exit notice is not proof that the watched job
32
+ succeeded. Inspect the terminal state and actual exit code. Filters keep the
33
+ coverage rule: match every terminal state, so silence at expiry is the
34
+ deadline notice, never a success signal. Source: CHANGELOG 2.1.271 and
35
+ https://code.claude.com/docs/en/tools-reference (retrieved 2026-10-12).
36
+
37
+ The snippets below use interactive timeout recommendations. For a `-p` run,
38
+ set `timeout_ms` to at most `600000` (10 minutes), as stated at each snippet.
39
+ Background detachment and Monitor watches do not keep a single-prompt run alive
40
+ after its turn ends. In unattended `-p` workflows, wait in the foreground with
41
+ a bounded command, read its actual exit, and repeat the wait if needed; do not
42
+ finish the turn while a watched job is still running.
43
+
44
+ ---
45
+
24
46
  ## Pattern 1 — GitLab pipeline + GitHub mirror sync (post-push)
25
47
 
26
48
  **When.** After `git push origin main` from `skills/close/SKILL.md` Phase 6.
@@ -29,9 +51,7 @@ the GitHub mirror's main-branch SHA so the operator can confirm parity.
29
51
 
30
52
  **Description.** `pipeline + mirror sync after push`
31
53
 
32
- **timeout_ms.** `1800000` (30 min — most pipelines finish well inside)
33
-
34
- **persistent.** `false`
54
+ **timeout_ms.** Interactive: `1800000` (30 min). Single-prompt `-p`: `600000` (10 min). Re-arm on expiry while the pipeline is still running.
35
55
 
36
56
  ```bash
37
57
  prev=""
@@ -116,9 +136,7 @@ and any failure signature without re-running the suite.
116
136
 
117
137
  **Description.** `vitest progress + failure signatures`
118
138
 
119
- **timeout_ms.** `1200000` (20 min)
120
-
121
- **persistent.** `false`
139
+ **timeout_ms.** Interactive: `1200000` (20 min). Single-prompt `-p`: `600000` (10 min). Re-arm on expiry while the suite is still running.
122
140
 
123
141
  ```bash
124
142
  # Pre-req: npm test 2>&1 | tee vitest.log was started in another terminal
@@ -142,10 +160,9 @@ a live dashboard in terminal B without building telemetry tooling.
142
160
 
143
161
  **Description.** `autopilot iteration + kill-switch tail`
144
162
 
145
- **timeout_ms.** `3600000` (1 h — the 1 h ceiling this file uses; repo-internal convention, upstream documents no explicit `timeout_ms` maximum)
163
+ **timeout_ms.** Interactive: `1800000` (30 min, the upstream maximum since v2.1.271). Single-prompt `-p`: `600000` (10 min).
146
164
 
147
- **persistent.** `true` (run for the lifetime of the session — autopilot
148
- runs can take hours)
165
+ **Re-arm.** The watch ends at its deadline; autopilot runs can take hours, so re-arm on the expiry notice (see "Deadline and re-arm").
149
166
 
150
167
  ```bash
151
168
  tail -f .orchestrator/metrics/autopilot.jsonl | jq -r --line-buffered '
@@ -160,7 +177,8 @@ kill-switch firings (the ten tracked in
160
177
  silent autopilot run means autopilot is not actually writing to the
161
178
  JSONL — that itself is a signal worth surfacing manually.
162
179
 
163
- **Detachment seam (Spike #640).** A headless autopilot run detached via
180
+ **Interactive detachment seam (Spike #640).** In an interactive session,
181
+ a headless autopilot run detached via
164
182
  Bash `run_in_background` (`node scripts/autopilot.mjs --headless … &`)
165
183
  is observed through the returned **task-id**, its **output-file**
166
184
  (`.../tasks/<id>.output`), and the **completion notification** — never
@@ -180,9 +198,9 @@ fires only at session-end / evolve. Surfaces drift before it accumulates.
180
198
 
181
199
  **Description.** `vault 40-learnings/50-sessions backlog`
182
200
 
183
- **timeout_ms.** `3600000` (1 h)
201
+ **timeout_ms.** Interactive: `1800000` (30 min, the upstream maximum since v2.1.271). Single-prompt `-p`: `600000` (10 min).
184
202
 
185
- **persistent.** `true`
203
+ **Re-arm.** Re-arm on the expiry notice while the backlog is still of interest (see "Deadline and re-arm").
186
204
 
187
205
  ```bash
188
206
  prev=0
@@ -198,7 +216,9 @@ done
198
216
 
199
217
  **Coverage.** Emits **only on change** to keep the stream quiet during
200
218
  idle work. A drop to zero is also reported (e.g. when session-end runs
201
- mirror-commit). Silence = no drift, which is the desired idle state. The
219
+ mirror-commit). Silence = no drift, which is the desired idle state. For
220
+ single-prompt `-p` runs, replace `sleep 1800` with `sleep 300` so the
221
+ watch can observe another sample before its 10-minute deadline. Interactive
202
222
  30-min sleep matches the `1200s+` idle-tick band from
203
223
  `.claude/rules/loop-and-monitor.md` LM-003 (idle observation-rate; under the
204
224
  1-hour subscription cache TTL there is no cache penalty here anyway).
@@ -214,9 +234,7 @@ parity bit the operator a day later.
214
234
 
215
235
  **Description.** `github mirror parity vs local main`
216
236
 
217
- **timeout_ms.** `300000` (5 min — push usually completes in seconds; this is the wall-clock ceiling **for this watch**, **not** the `/loop` cadence band that LM-003 in `.claude/rules/loop-and-monitor.md` warns against)
218
-
219
- **persistent.** `false`
237
+ **timeout_ms.** `300000` (5 min, valid for both interactive and single-prompt `-p` runs — push usually completes in seconds; this is the wall-clock ceiling **for this watch**, **not** the `/loop` cadence band that LM-003 in `.claude/rules/loop-and-monitor.md` warns against)
220
238
 
221
239
  ```bash
222
240
  local_sha=$(git rev-parse main)
@@ -301,7 +319,7 @@ discipline:
301
319
 
302
320
  ---
303
321
 
304
- ## Pattern — `/tmux-layout` (operator-side persistent visualization)
322
+ ## Pattern — `/tmux-layout` (operator-side standing visualization)
305
323
 
306
324
  > Per ADR-0007 + GitLab #561 #562 #563. Opt-in skill, NOT Monitor/loop replacement.
307
325
 
@@ -309,9 +327,9 @@ discipline:
309
327
 
310
328
  | Primitive | Purpose | When to use |
311
329
  |---|---|---|
312
- | **`Monitor` tool** | Event-driven stream → coordinator reaction | The coordinator must REACT to each terminal-state line (CI fails → take action, build error → patch). Each stdout line = one coordinator notification. |
330
+ | **`Monitor` tool** | Event-driven stream → coordinator reaction | The coordinator must REACT to each terminal-state line (CI fails → take action, build error → patch). Each output or exit event produces one coordinator notification; output may contain multiple lines. |
313
331
  | **`/loop` skill** | Periodic coordinator-side polling | "Check vault-staleness every 30 minutes while session runs." Lives inside the coordinator's turn budget. |
314
- | **`/tmux-layout` skill** | Operator-side persistent visualization (4-pane) | The OPERATOR (human) wants to peripherally observe side-channels — STATE.md tail, CI watch, events.jsonl — in a SECOND terminal without coordinator reaction. Pure observability. |
332
+ | **`/tmux-layout` skill** | Operator-side standing visualization (4-pane) | The OPERATOR (human) wants to peripherally observe side-channels — STATE.md tail, CI watch, events.jsonl — in a SECOND terminal without coordinator reaction. Pure observability. |
315
333
 
316
334
  **Key distinction:** `/tmux-layout` visualizes the *outputs* of `Monitor` and `/loop` peripherally so the coordinator pane stays focused on decisions (AUQ-001). It does NOT replace either — Pane 3 of the default layout, for example, runs a `glab ci status` poll-loop equivalent to a `/loop` cadence, but the coordinator does not see those refreshes (the operator does).
317
335
 
@@ -326,9 +344,10 @@ discipline:
326
344
  spams notifications and gets auto-stopped by Monitor's volume guard.
327
345
  - **Forgetting `--line-buffered`** in `grep` pipes — pipe buffering
328
346
  delays events by minutes, which usually masks itself as "no events".
329
- - **Unbounded `tail -f` for one-shot signals** — use Bash with
330
- `run_in_background` and an `until` loop instead. See the Monitor tool
331
- docs.
347
+ - **Unbounded `tail -f` for one-shot signals** — use a bounded foreground
348
+ wait in single-prompt `-p` runs and inspect the actual exit code. Interactive
349
+ sessions may use a Bash background task with a completion notification;
350
+ do not carry that detachment pattern into unattended `-p` runs.
332
351
  - **Using Monitor as a `/loop` replacement for periodic scans without a
333
352
  stream** (e.g. polling `glab issue list`). Use `/loop` dynamic mode.
334
353
 
@@ -15,6 +15,13 @@ harness expose those exact tools. Use the current runtime's available tools.
15
15
  Measured in Codex Desktop 0.153.4 on 2026-09-19: `exec_command` runs shell
16
16
  commands (`cat`, `rg`, `rg --files` for Read/Grep/Glob); `apply_patch` performs
17
17
  file edits. These may be exposed through a `functions.exec` tools namespace.
18
+ Hook boundary, measured 2026-10-20 on `codex-cli 0.160.1` (`codex exec`, #1669):
19
+ a PreToolUse hook sees a shell call as `tool_name: "Bash"` with
20
+ `tool_input.command` as a string, and `matcher: "Bash"` fires. Codex honours a
21
+ PreToolUse `deny` (measured 2026-10-20 on `codex-cli 0.160.1`, #1691): the
22
+ blocked command does not run. The Bash guards are wired on Codex except
23
+ `pre-bash-templates-first` (it needs `transcript_path`, which Codex sends as
24
+ `null`); see `docs/codex-setup.md`.
18
25
  Never call an unavailable `Read`, `Bash`, or `Skill` tool by name. An instruction
19
26
  to invoke `session-orchestrator:<name>` means read and follow the canonical
20
27
  `skills/<name>/SKILL.md` relative to the plugin root when no Skill tool exists.
@@ -26,7 +26,7 @@ session-start-ref: <sha> # git ref at session start
26
26
  ### Required vs. optional fields
27
27
 
28
28
  - `schema-version`, `session-type`, `branch`, `issues`, `started_at`, `status`, `current-wave`, `total-waves` — **required** in every session-owned STATE.md.
29
- - `session-id` — **optional**, additive under `schema-version: 1` (#1368). The RAW/native harness session id, taken from `.orchestrator/session.lock` via `resolveSessionIds()` (`scripts/lib/state-md.mjs`). Writers OMIT the key when the lock yields none; readers MUST tolerate its absence. It exists so `/close`'s #429 pre-check can join STATE.md to sessions.jsonl on a NATIVE identity (`findRecordedSession`'s UUID fast path) instead of falling through to the semantic label. Like `session`, it grants no lock or registry ownership.
29
+ - `session-id` — **optional**, additive under `schema-version: 1` (#1368). The RAW/native harness session id, taken from `.orchestrator/session.lock` via `resolveSessionIds()` (`scripts/lib/state-md.mjs`), and only when the lock id is this process's own (`readProcessLocalSessionIds()`, #1663) — a lock naming a peer yields `null`. Writers OMIT the key when the lock yields none; readers MUST tolerate its absence. It exists so `/close`'s #429 pre-check can join STATE.md to sessions.jsonl on a NATIVE identity (`findRecordedSession`'s UUID fast path) instead of falling through to the semantic label. Like `session`, it grants no lock or registry ownership.
30
30
  - `started_at` is SOURCED from the same lock (`resolveSessionStartedAt()`), never from the writer's clock — see `skills/wave-executor/references/wave-executor-state-init.md` § Pre-Wave 1b for the template and the 48-minute drift that motivated it (#1368). On the READ side `started_at` is a CORROBORATING signal, never an identity key: `findRecordedSession()` (`scripts/lib/session-close-backfill.mjs`) joins STATE.md to `sessions.jsonl` on the native `session-id` FIRST and never consults `started_at` on that path — only the legacy-LABEL path compares the two timestamps, and it tolerates up to `STARTED_AT_DRIFT_TOLERANCE_MS` = **6 h** of drift (`session-close-backfill.mjs:559`, the single definition) before vetoing a label match: wider than any plausible write-lag (the 48 minutes above), narrower than the day the label's own date component already distinguishes.
31
31
  - `updated`, `session`, `session-start-ref` — **optional**. Added by #184. STATE.md files without these fields remain valid and should be treated as `updated: null` / `session: null`. Writers SHOULD populate these fields but readers MUST tolerate their absence. `session` is an attribution/history label, normally `<branch>-<YYYY-MM-DD>-<mode>-<n>` since #573 (Epic #568 Parallel-Aware Sessions P2.2); pre-#573 files may contain a UUID-v4 — both formats are read via `parseSessionId()` from `scripts/lib/session-id.mjs` per PRD §3 P2 row 3 (backward-compat). Neither form grants lock or registry ownership.
32
32
 
@@ -40,7 +40,7 @@ The `session-type: none` + `status: idle` combination is used only for bootstrap
40
40
  | `## Wave History` | Completed wave records | wave-executor (post-wave) |
41
41
  | `## Deviations` | Plan adaptation log | wave-executor (step 3) |
42
42
  | `## What Not To Retry` | Failed/abandoned approaches not to repeat (#623) | session-end (Phase 1.6) |
43
- | `## Open Questions` | Unresolved user-facing questions (agent → gate → next session) | wave-executor (inter-wave) + session-end (marks answered) |
43
+ | `## Open Questions` | Unresolved user-facing questions (agent → gate → next session) | wave-executor (inter-wave) + session-end (marks answered; appends one vault-orphan entry at Phase 3.7e, #1563) |
44
44
 
45
45
  Wave History lines MAY include a `→ issue #NNN` suffix (or `→ existing #NNN` when a duplicate was detected) for SPIRAL/FAILED agents, linking to the auto-created carryover issue (#261). This is optional and backward-compatible; readers that do not recognize the notation can skip it. Session-end Phase 1.6 uses the presence of this suffix to decide whether to retro-file a carryover as a fallback safety net.
46
46
 
@@ -139,8 +139,8 @@ growing across sessions is the CCU-009 anti-pattern.
139
139
  | Skill | Access | Operations |
140
140
  |-------|--------|------------|
141
141
  | **wave-executor** | Read + Write (owner) | Creates STATE.md (Pre-Wave 1b), updates after each wave (current-wave, Wave History, Deviations); appends deduped `## Open Questions` at inter-wave checkpoints via `appendOpenQuestionOnDisk` (see `wave-loop.md` § 3e + Post-Wave step 6). |
142
- | **session-end** | Read + Status-only write | Reads for metrics extraction (Phase 1.7), sets `status: completed` (Phase 3.4). Exception: only fields modified are `status` in frontmatter and marking entries answered in `## Open Questions` via `markOpenQuestionAnsweredOnDisk` (Close Handover-Alignment-Gate). |
143
- | **session-start** | Read + conditional reset | Reads for continuity checks (Phase 1.5): inspects `status` field to detect crashed/paused sessions. Surfaces `## What Not To Retry` as a forced-read HISTORICAL block (Phase 6.5.1). May reset STATE.md to idle at the boundary between a completed session and a new session — only when prior `status: completed`. The reset clears `current-wave` (→ 0), sets `status: idle`, demotes `## Wave History` into `## Previous Session`, and empties `## Deviations` — but PRESERVES `## What Not To Retry` (cross-session continuity, #623) and `## Open Questions` (Close Handover-Alignment-Gate, PRD 2026-07-07). Never resets on `active` or `paused` (those paths are user-interactive). |
142
+ | **session-end** | Read + Status-only write | Reads for metrics extraction (Phase 1.7), sets `status: completed` (Phase 3.4, `markStateMdCompletedOnDisk`: same locked write also sets `updated` and `current-wave` and re-stamps `session-id` to the closing process's own raw id, #1640) and the five recommendation keys (Phase 3.7a, same explicit `statePath`). Exception: only fields modified are these frontmatter keys and marking entries answered in `## Open Questions` via `markOpenQuestionAnsweredOnDisk` (Close Handover-Alignment-Gate), plus at most one appended `## Open Questions` entry naming vault-orphan candidates via `appendOpenQuestionOnDisk` (Phase 3.7e, #1563). |
143
+ | **session-start** | Read + conditional reset | Reads for continuity checks (Phase 1.5): inspects `status` field to detect crashed/paused sessions. Surfaces `## What Not To Retry` as a forced-read HISTORICAL block (Phase 6.5.1). May reset STATE.md to idle at the boundary between a completed session and a new session — only when prior `status: completed`, via `scripts/state-md-idle-reset.mjs` (#1560). The reset keeps the five recommendation keys in the frontmatter for the Phase 7.5 Mode-Selector, clears `current-wave` (→ 0), sets `status: idle`, demotes `## Wave History` into `## Previous Session`, and empties `## Deviations` — but PRESERVES `## What Not To Retry` (cross-session continuity, #623) and `## Open Questions` (Close Handover-Alignment-Gate, PRD 2026-07-07). Never resets on `active` or `paused` (those paths are user-interactive). |
144
144
  | **evolve** | Read-only | Reads `## Deviations` section for deviation pattern extraction (Step 2.2, pattern 5) |
145
145
 
146
146
  ### Shared-File Single-Writer Rule (`isolation: none` waves)
@@ -246,6 +246,7 @@ The `.orchestrator/session.lock` file is written mechanically by `hooks/_lib/loc
246
246
  | `pid` | v1 | **Forensic only — do NOT use for liveness.** Records the writer's process PID (the hook subprocess, ~500ms lifetime). Dead PIDs are expected and normal. See D2 / D3 notes below. |
247
247
  | `host` | v1 | `os.hostname()` of the machine that wrote the lock. Cross-host locks skip PID checks. |
248
248
  | `ttl_hours` | v1 | Maximum age before the lock is considered stale regardless of other signals. Default 4h. |
249
+ | `claude_pid` | optional (#1641) | The Claude Code process id from `CLAUDE_PID`, written only when that process is the writer hook's DIRECT parent (a Codex child of a Claude session inherits the variable and must not carry it); absent otherwise (Codex, Cursor). Not a liveness signal either: it is the witness that survives `/clear`, where the raw id and the label are minted anew. A `clear`/`resume` start whose own admitted pid equals it on the same host treats the lock as its own predecessor — it takes it over (`reclaimed: own-process`) or, on a #1635 lead yield, releases it. Ceilings: two pid namespaces with one hostname (WSL2 distros, container and host on one checkout). |
249
250
 
250
251
  ### Liveness rule (v2)
251
252
 
@@ -3,7 +3,7 @@
3
3
  > Reference material for the `architecture` skill — **not a skill of its own.**
4
4
  > Merged here in v4.0.0 from the former `skills/domain-model/` (retired: zero
5
5
  > telemetry, zero fleet invocations, reference-only usage — see
6
- > `docs/audits/2026-09-06-360-audit.md` § 5A). Invoke it by reading this file
6
+ > § 5A of the 2026-09-06 360° audit, an internal report not in the public mirror). Invoke it by reading this file
7
7
  > from `/architecture`, not via a slash command.
8
8
  >
9
9
  > Adapted from [`mattpocock/skills@90ea8ee`](https://github.com/mattpocock/skills/tree/main/domain-model), MIT — Copyright (c) 2026 Matt Pocock. See the repo-root `NOTICE`.
@@ -249,8 +249,9 @@ import { detectPeers } from '$PLUGIN_ROOT/scripts/lib/session-registry.mjs';
249
249
  const flags = parseFlags(process.argv.slice(2));
250
250
 
251
251
  const modeSelector = async () => {
252
- // Each iteration rebuilds signals from current disk state. STATE.md will be
253
- // freshly idle-reset by the previous /close, sessions.jsonl will have the
252
+ // Each iteration rebuilds signals from current disk state. STATE.md will
253
+ // carry the recommendation the previous /close wrote (the idle reset at the
254
+ // next session-start keeps those keys, #1560), sessions.jsonl will have the
254
255
  // new tail entry, etc. This is the contract: live signals every iteration.
255
256
  // `repoRoot` is passed explicitly (#1071) rather than left to the helper's
256
257
  // cwd default. Do NOT hand-write a `backlogLimit` here — the window default
@@ -124,6 +124,8 @@ Present exactly one `AskUserQuestion` unless:
124
124
  - `$ARGUMENTS` includes `--fast`, `--standard`, or `--deep` (tier pre-selected, skip question)
125
125
  - `--retroactive` flag (no scaffolding at all, skip to Phase 4)
126
126
 
127
+ **Language (#1562).** The question texts in this skill are written in German. Render every question, option description and report line in the operator's language: `owner.language` from `~/.config/session-orchestrator/owner.yaml` when that file exists (`de` or `en`), otherwise the language the operator writes in this session. Tier labels (`fast`, `standard`, `deep`) and archetype ids stay verbatim, because they are values; `(Empfohlen)` and `Abbrechen` follow the language (`(Recommended)`, `Cancel`).
128
+
127
129
  ```
128
130
  AskUserQuestion({
129
131
  questions: [{
@@ -272,7 +274,7 @@ selection, scaffolding and initial commit. Rule selection may read the lock ID.
272
274
  export PLUGIN_ROOT CONFIRMED_ARCHETYPE DRY_RUN RULES_CATEGORIES
273
275
  node --input-type=module <<'NODE'
274
276
  import { pathToFileURL } from 'node:url';
275
- const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
277
+ const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
276
278
  const categories = (process.env.RULES_CATEGORIES || '').split(',').map(value => value.trim()).filter(Boolean);
277
279
  const result = await syncBootstrapRules({ repoRoot: process.cwd(), archetype: process.env.CONFIRMED_ARCHETYPE || undefined,
278
280
  dryRun: process.env.DRY_RUN === 'true', categories: categories.length ? categories : null });
@@ -28,7 +28,7 @@ mkdir -p "$REPO_ROOT/.claude"
28
28
  export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE
29
29
  RULES_RESULT=$(node --input-type=module <<'NODE'
30
30
  import { pathToFileURL } from 'node:url';
31
- const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
31
+ const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
32
32
  const result = await syncBootstrapRules({ repoRoot: process.env.REPO_ROOT, archetype: process.env.CONFIRMED_ARCHETYPE || undefined });
33
33
  process.stdout.write(`${JSON.stringify(result)}\n`);
34
34
  if (result.status === 'error') process.exitCode = 2;
@@ -151,7 +151,7 @@ if [[ "${PATH_TYPE:-public}" = "private" ]]; then
151
151
  export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE
152
152
  BASELINE_RULES_RESULT=$(node --input-type=module <<'NODE'
153
153
  import { pathToFileURL } from 'node:url';
154
- const { applyBaselineRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
154
+ const { applyBaselineRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
155
155
  const result = await applyBaselineRules({
156
156
  repoRoot: process.env.REPO_ROOT,
157
157
  archetype: process.env.CONFIRMED_ARCHETYPE,
@@ -200,7 +200,7 @@ MANIFEST
200
200
  import { readFileSync, writeFileSync } from 'node:fs';
201
201
  import path from 'node:path';
202
202
  import { pathToFileURL } from 'node:url';
203
- const { pluginRuleTargets } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
203
+ const { pluginRuleTargets } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
204
204
  const owned = new Set(pluginRuleTargets(process.env.PLUGIN_ROOT));
205
205
  const files = readFileSync(process.env.RULES_MANIFEST, 'utf8').split('\n')
206
206
  .filter(file => file && !owned.has(path.posix.basename(file)));
@@ -281,7 +281,7 @@ if [[ "${PATH_TYPE:-public}" = private ]]; then
281
281
  export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE
282
282
  POLICY_RESULT=$(node --input-type=module <<'NODE'
283
283
  import { pathToFileURL } from 'node:url';
284
- const { writeBaselineQualityPolicy } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
284
+ const { writeBaselineQualityPolicy } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
285
285
  const result = await writeBaselineQualityPolicy({ repoRoot: process.env.REPO_ROOT, archetype: process.env.CONFIRMED_ARCHETYPE });
286
286
  process.stdout.write(`${JSON.stringify(result)}\n`);
287
287
  if (result.status === 'error') process.exitCode = 2;
@@ -195,7 +195,7 @@ mkdir -p "$REPO_ROOT/.claude"
195
195
  export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE
196
196
  RULES_RESULT=$(node --input-type=module <<'NODE'
197
197
  import { pathToFileURL } from 'node:url';
198
- const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
198
+ const { syncBootstrapRules } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
199
199
  const result = await syncBootstrapRules({ repoRoot: process.env.REPO_ROOT,
200
200
  archetype: process.env.CONFIRMED_ARCHETYPE || undefined, minimal: !process.env.CONFIRMED_ARCHETYPE });
201
201
  process.stdout.write(`${JSON.stringify(result)}\n`);
@@ -41,7 +41,7 @@ interactive setup script, package installation, Git, or a remote service.
41
41
  export PLUGIN_ROOT REPO_ROOT CONFIRMED_ARCHETYPE REPO_NAME
42
42
  SCAFFOLD_RESULT=$(node --input-type=module <<'NODE'
43
43
  import { pathToFileURL } from 'node:url';
44
- const { scaffoldBaselineArchetype } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`));
44
+ const { scaffoldBaselineArchetype } = await import(pathToFileURL(`${process.env.PLUGIN_ROOT}/scripts/lib/baseline-archetypes.mjs`).href);
45
45
  const result = await scaffoldBaselineArchetype({
46
46
  repoRoot: process.env.REPO_ROOT,
47
47
  archetype: process.env.CONFIRMED_ARCHETYPE,
@@ -49,13 +49,24 @@ Entered when `$ARGUMENTS` contains `--retroactive`. Writes the lock file and, pe
49
49
  plugin-version: <current plugin version from $PLUGIN_ROOT/package.json>
50
50
  ```
51
51
 
52
- 6. **Patch Session Config (#182).** Run the validator against the current `## Session Config` block; append any missing mandatory fields with defaults. The 7 mandatory fields (per `scripts/lib/config-schema.mjs`) are: `test-command`, `typecheck-command`, `lint-command`, `agents-per-wave`, `waves`, `persistence`, `enforcement`.
52
+ 6. **Patch Session Config (#182, #1567).** Find the mandatory fields the `## Session Config` block does not carry and append them with defaults. The mandatory fields are the keys of the FIRST `## Session Config` block in `$PLUGIN_ROOT/docs/session-config-template.md` (today the 7 validated by `scripts/lib/config-schema.mjs`): `test-command`, `typecheck-command`, `lint-command`, `agents-per-wave`, `waves`, `persistence`, `enforcement`.
53
+
54
+ Presence is read from the FILE, not from the validator: `parseSessionConfig()` fills every mandatory field with its default, so `parse-config.mjs` / `validate-config.mjs` never report an ABSENT field (a pnpm repo without `test-command` would silently run `npm test`). `missingStarterKeys()` (`scripts/lib/config/template-keys.mjs`) compares the template's starter keys against `collectTopLevelKeyLines()` — the top-level keys the runtime reads, in every accepted spelling (`key:`, `- key:`, `- **key:**`).
53
55
 
54
56
  ```bash
55
- CONFIG_OUT="$(node "$PLUGIN_ROOT/scripts/parse-config.mjs" 2>&1 >/dev/null)"
56
- # parse-config.mjs emits validation warnings to stderr when enforcement=warn.
57
- # Grep for 'must be' lines (issued by validate-config.mjs) to detect missing fields.
58
- MISSING_FIELDS="$(echo "$CONFIG_OUT" | grep -oE '(test-command|typecheck-command|lint-command|agents-per-wave|waves|persistence|enforcement)' | sort -u || true)"
57
+ CONFIG_FILE="CLAUDE.md"
58
+ [[ -f "AGENTS.md" ]] && CONFIG_FILE="AGENTS.md"
59
+
60
+ MISSING_FIELDS="$(node --input-type=module -e "
61
+ import { readFileSync } from 'node:fs';
62
+ import { missingStarterKeys } from '$PLUGIN_ROOT/scripts/lib/config/template-keys.mjs';
63
+ const missing = missingStarterKeys(
64
+ readFileSync(process.argv[1], 'utf8'),
65
+ readFileSync('$PLUGIN_ROOT/docs/session-config-template.md', 'utf8'),
66
+ );
67
+ if (missing === null) { console.error('template has no Session Config block — mandatory-field check did not run'); process.exit(1); }
68
+ console.log(missing.join(' '));
69
+ " "$CONFIG_FILE")"
59
70
  if [[ -n "$MISSING_FIELDS" ]]; then
60
71
  # Detect package manager to pick sensible defaults for commands.
61
72
  PM_DEFAULTS="$(node --input-type=module -e "
@@ -67,9 +78,6 @@ Entered when `$ARGUMENTS` contains `--retroactive`. Writes the lock file and, pe
67
78
  console.log('lint-command: ' + cmds.lint.command);
68
79
  " 2>/dev/null)"
69
80
 
70
- CONFIG_FILE="CLAUDE.md"
71
- [[ -f "AGENTS.md" ]] && CONFIG_FILE="AGENTS.md"
72
-
73
81
  # Append each missing field under the ## Session Config block.
74
82
  for field in $MISSING_FIELDS; do
75
83
  case "$field" in
@@ -89,7 +97,7 @@ Entered when `$ARGUMENTS` contains `--retroactive`. Writes the lock file and, pe
89
97
  fi
90
98
  ```
91
99
 
92
- This patch is best-effort: existing fields are never overwritten. If no fields are missing, this step is a no-op.
100
+ This patch is best-effort: existing fields are never overwritten, and an INVALID value of a present field is left for `parse-config.mjs` to report. If no fields are missing, this step is a no-op; if the check did not run (exit 1), report that line instead of `No config changes.`.
93
101
 
94
102
  7. **Commit.** Stage the lock file (and the patched config file, if it changed) and commit:
95
103
  ```bash
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: project-code-review
3
- description: Use this agent when you need to review code changes for convention compliance, security issues, or correctness before merging. <example>Context: A wave of implementation work has completed and the coordinator needs a review pass before committing. user: "Review the auth module changes" assistant: "I'll use the project-code-review agent to check convention compliance and surface any security concerns." <commentary>Convention enforcement and security review are the project-code-review agent's responsibilities.</commentary></example>
3
+ description: Use this agent when you need to review code changes for convention compliance, security issues, or correctness before merging.
4
4
  model: inherit
5
5
  color: green
6
6
  tools: Read, Grep, Glob
@@ -16,3 +16,7 @@ Performs read-only review of code changes. Use this agent to:
16
16
  - Verify adherence to naming conventions and file structure
17
17
 
18
18
  Edit this file to add project-specific review checklists, e.g. banned patterns, required linting rules, security invariants, or architecture constraints.
19
+
20
+ ## Examples
21
+
22
+ <example>Context: A wave of implementation work has completed and the coordinator needs a review pass before committing. user: "Review the auth module changes" assistant: "I'll use the project-code-review agent to check convention compliance and surface any security concerns." <commentary>Convention enforcement and security review are the project-code-review agent's responsibilities.</commentary></example>
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: project-discovery
3
- description: Use this agent when you need to audit project state, map affected modules, or verify assumptions before implementation. <example>Context: Before adding a new feature, the coordinator needs to understand existing code paths. user: "Audit the auth flow" assistant: "I'll use the project-discovery agent to map auth modules and identify dependencies." <commentary>Read-only audit work is the project-discovery agent's sweet spot.</commentary></example>
3
+ description: Use this agent when you need to audit project state, map affected modules, or verify assumptions before implementation.
4
4
  model: inherit
5
5
  color: cyan
6
6
  tools: Read, Grep, Glob, Bash
@@ -16,3 +16,7 @@ Performs read-only audits of the project codebase. Use this agent to:
16
16
  - Surface potential conflicts or constraints
17
17
 
18
18
  Edit this file to add project-specific discovery queries, e.g. common file paths, known patterns to grep for, or project-specific terminology to watch for.
19
+
20
+ ## Examples
21
+
22
+ <example>Context: Before adding a new feature, the coordinator needs to understand existing code paths. user: "Audit the auth flow" assistant: "I'll use the project-discovery agent to map auth modules and identify dependencies." <commentary>Read-only audit work is the project-discovery agent's sweet spot.</commentary></example>