session-orchestrator 5.1.0 → 5.3.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 (484) hide show
  1. package/.agents/skills/architecture/SKILL.md +3 -1
  2. package/.agents/skills/autopilot/SKILL.md +6 -1
  3. package/.agents/skills/autopilot/agents/openai.yaml +5 -0
  4. package/.agents/skills/bootstrap/SKILL.md +7 -1
  5. package/.agents/skills/bootstrap/agents/openai.yaml +5 -0
  6. package/.agents/skills/brainstorm/SKILL.md +8 -1
  7. package/.agents/skills/brainstorm/agents/openai.yaml +5 -0
  8. package/.agents/skills/claude-md-drift-check/SKILL.md +3 -1
  9. package/.agents/skills/close/SKILL.md +21 -0
  10. package/.agents/skills/close/agents/openai.yaml +5 -0
  11. package/.agents/skills/convergence-monitoring/SKILL.md +4 -2
  12. package/.agents/skills/debug/SKILL.md +7 -1
  13. package/.agents/skills/debug/agents/openai.yaml +5 -0
  14. package/.agents/skills/discovery/SKILL.md +7 -2
  15. package/.agents/skills/discovery/agents/openai.yaml +5 -0
  16. package/.agents/skills/dispatcher/SKILL.md +7 -1
  17. package/.agents/skills/dispatcher/agents/openai.yaml +5 -0
  18. package/.agents/skills/docs-orchestrator/SKILL.md +3 -1
  19. package/.agents/skills/ecosystem-health/SKILL.md +3 -1
  20. package/.agents/skills/eli5/SKILL.md +7 -1
  21. package/.agents/skills/eli5/agents/openai.yaml +5 -0
  22. package/.agents/skills/eval/SKILL.md +7 -2
  23. package/.agents/skills/eval/agents/openai.yaml +5 -0
  24. package/.agents/skills/evolve/SKILL.md +8 -3
  25. package/.agents/skills/evolve/agents/openai.yaml +5 -0
  26. package/.agents/skills/frontmatter-guard/SKILL.md +3 -1
  27. package/.agents/skills/gitlab-ops/SKILL.md +3 -1
  28. package/.agents/skills/gitlab-portfolio/SKILL.md +3 -1
  29. package/.agents/skills/go/SKILL.md +22 -0
  30. package/.agents/skills/go/agents/openai.yaml +5 -0
  31. package/.agents/skills/grill/SKILL.md +7 -1
  32. package/.agents/skills/grill/agents/openai.yaml +5 -0
  33. package/.agents/skills/harness-audit/SKILL.md +20 -0
  34. package/.agents/skills/harness-audit/agents/openai.yaml +5 -0
  35. package/.agents/skills/hook-development/SKILL.md +3 -1
  36. package/.agents/skills/mcp-builder/SKILL.md +3 -1
  37. package/.agents/skills/memory-cleanup/SKILL.md +6 -1
  38. package/.agents/skills/memory-cleanup/agents/openai.yaml +5 -0
  39. package/.agents/skills/mode-selector/SKILL.md +3 -1
  40. package/.agents/skills/npm-publish/SKILL.md +4 -2
  41. package/.agents/skills/peekaboo-driver/SKILL.md +3 -1
  42. package/.agents/skills/persona-panel/SKILL.md +6 -1
  43. package/.agents/skills/persona-panel/agents/openai.yaml +5 -0
  44. package/.agents/skills/plan/SKILL.md +8 -2
  45. package/.agents/skills/plan/agents/openai.yaml +5 -0
  46. package/.agents/skills/playwright-driver/SKILL.md +3 -1
  47. package/.agents/skills/portfolio/SKILL.md +21 -0
  48. package/.agents/skills/portfolio/agents/openai.yaml +5 -0
  49. package/.agents/skills/quality-gates/SKILL.md +3 -1
  50. package/.agents/skills/reconcile/SKILL.md +6 -1
  51. package/.agents/skills/reconcile/agents/openai.yaml +5 -0
  52. package/.agents/skills/release/SKILL.md +22 -0
  53. package/.agents/skills/release/agents/openai.yaml +5 -0
  54. package/.agents/skills/remote-offload/SKILL.md +3 -1
  55. package/.agents/skills/repo-audit/SKILL.md +6 -1
  56. package/.agents/skills/repo-audit/agents/openai.yaml +5 -0
  57. package/.agents/skills/session/SKILL.md +21 -0
  58. package/.agents/skills/session/agents/openai.yaml +5 -0
  59. package/.agents/skills/session-end/SKILL.md +3 -1
  60. package/.agents/skills/session-plan/SKILL.md +3 -1
  61. package/.agents/skills/session-start/SKILL.md +3 -1
  62. package/.agents/skills/spinout/SKILL.md +6 -1
  63. package/.agents/skills/spinout/agents/openai.yaml +5 -0
  64. package/.agents/skills/sunset-review/SKILL.md +7 -1
  65. package/.agents/skills/sunset-review/agents/openai.yaml +5 -0
  66. package/.agents/skills/templates-ack/SKILL.md +21 -0
  67. package/.agents/skills/templates-ack/agents/openai.yaml +5 -0
  68. package/.agents/skills/test/SKILL.md +21 -0
  69. package/.agents/skills/test/agents/openai.yaml +5 -0
  70. package/.agents/skills/test-runner/SKILL.md +3 -1
  71. package/.agents/skills/tmux-layout/SKILL.md +3 -1
  72. package/.agents/skills/using-orchestrator/SKILL.md +3 -1
  73. package/.agents/skills/ux-grill/SKILL.md +7 -1
  74. package/.agents/skills/ux-grill/agents/openai.yaml +5 -0
  75. package/.agents/skills/vault-mirror/SKILL.md +3 -1
  76. package/.agents/skills/vault-sync/SKILL.md +3 -1
  77. package/.agents/skills/wave-executor/SKILL.md +3 -1
  78. package/.agents/skills/write-executable-plan/SKILL.md +3 -1
  79. package/.claude-plugin/marketplace.json +1 -1
  80. package/.claude-plugin/plugin.json +1 -1
  81. package/.codex-plugin/plugin.json +4 -4
  82. package/.codex-plugin/skills/autopilot/SKILL.md +5 -4
  83. package/.codex-plugin/skills/bootstrap/SKILL.md +8 -4
  84. package/.codex-plugin/skills/brainstorm/SKILL.md +11 -4
  85. package/.codex-plugin/skills/close/SKILL.md +3 -3
  86. package/.codex-plugin/skills/convergence-monitoring/SKILL.md +1 -1
  87. package/.codex-plugin/skills/debug/SKILL.md +11 -4
  88. package/.codex-plugin/skills/discovery/SKILL.md +8 -4
  89. package/.codex-plugin/skills/dispatcher/SKILL.md +4 -4
  90. package/.codex-plugin/skills/eli5/SKILL.md +9 -4
  91. package/.codex-plugin/skills/eval/SKILL.md +9 -4
  92. package/.codex-plugin/skills/evolve/SKILL.md +9 -4
  93. package/.codex-plugin/skills/go/SKILL.md +3 -3
  94. package/.codex-plugin/skills/grill/SKILL.md +11 -4
  95. package/.codex-plugin/skills/harness-audit/SKILL.md +4 -3
  96. package/.codex-plugin/skills/memory-cleanup/SKILL.md +9 -4
  97. package/.codex-plugin/skills/npm-publish/SKILL.md +1 -1
  98. package/.codex-plugin/skills/persona-panel/SKILL.md +5 -5
  99. package/.codex-plugin/skills/plan/SKILL.md +8 -4
  100. package/.codex-plugin/skills/portfolio/SKILL.md +3 -3
  101. package/.codex-plugin/skills/reconcile/SKILL.md +9 -4
  102. package/.codex-plugin/skills/release/SKILL.md +3 -3
  103. package/.codex-plugin/skills/repo-audit/SKILL.md +6 -4
  104. package/.codex-plugin/skills/session/SKILL.md +1 -1
  105. package/.codex-plugin/skills/spinout/SKILL.md +4 -4
  106. package/.codex-plugin/skills/sunset-review/SKILL.md +5 -4
  107. package/.codex-plugin/skills/test/SKILL.md +3 -3
  108. package/.codex-plugin/skills/ux-grill/SKILL.md +11 -4
  109. package/.cursor/commands/autopilot.md +4 -4
  110. package/.cursor/commands/bootstrap.md +5 -4
  111. package/.cursor/commands/brainstorm.md +5 -4
  112. package/.cursor/commands/close.md +4 -3
  113. package/.cursor/commands/debug.md +4 -4
  114. package/.cursor/commands/discovery.md +4 -4
  115. package/.cursor/commands/dispatcher.md +4 -4
  116. package/.cursor/commands/eli5.md +4 -4
  117. package/.cursor/commands/eval.md +4 -4
  118. package/.cursor/commands/evolve.md +4 -4
  119. package/.cursor/commands/go.md +4 -3
  120. package/.cursor/commands/grill.md +4 -4
  121. package/.cursor/commands/harness-audit.md +3 -3
  122. package/.cursor/commands/memory-cleanup.md +4 -4
  123. package/.cursor/commands/persona-panel.md +4 -4
  124. package/.cursor/commands/plan.md +5 -4
  125. package/.cursor/commands/portfolio.md +3 -3
  126. package/.cursor/commands/reconcile.md +4 -4
  127. package/.cursor/commands/release.md +4 -3
  128. package/.cursor/commands/repo-audit.md +4 -4
  129. package/.cursor/commands/session.md +1 -1
  130. package/.cursor/commands/spinout.md +4 -4
  131. package/.cursor/commands/sunset-review.md +4 -4
  132. package/.cursor/commands/test.md +3 -3
  133. package/.cursor/commands/ux-grill.md +4 -4
  134. package/.cursor/rules/000-session-orchestrator.mdc +0 -2
  135. package/.cursor/rules/010-session-workflow.mdc +2 -2
  136. package/.cursor/rules/050-plan.mdc +1 -1
  137. package/.cursor/skills/bootstrap/SKILL.md +1 -0
  138. package/.cursor/skills/close/SKILL.md +13 -0
  139. package/.cursor/skills/convergence-monitoring/SKILL.md +1 -0
  140. package/.cursor/skills/debug/SKILL.md +0 -1
  141. package/.cursor/skills/discovery/SKILL.md +0 -1
  142. package/.cursor/skills/dispatcher/SKILL.md +0 -1
  143. package/.cursor/skills/eli5/SKILL.md +0 -1
  144. package/.cursor/skills/eval/SKILL.md +1 -1
  145. package/.cursor/skills/evolve/SKILL.md +0 -1
  146. package/.cursor/skills/go/SKILL.md +13 -0
  147. package/.cursor/skills/grill/SKILL.md +0 -1
  148. package/.cursor/skills/harness-audit/SKILL.md +12 -0
  149. package/.cursor/skills/npm-publish/SKILL.md +1 -0
  150. package/.cursor/skills/portfolio/SKILL.md +12 -0
  151. package/.cursor/skills/release/SKILL.md +13 -0
  152. package/.cursor/skills/repo-audit/SKILL.md +0 -1
  153. package/.cursor/skills/sunset-review/SKILL.md +0 -1
  154. package/.cursor/skills/test/SKILL.md +12 -0
  155. package/.cursor/skills/ux-grill/SKILL.md +0 -1
  156. package/.cursor-plugin/plugin.json +1 -1
  157. package/.orchestrator/policy/blocked-commands.json +13 -4
  158. package/AGENTS.md +3 -2
  159. package/CHANGELOG.md +197 -0
  160. package/README.md +11 -9
  161. package/SECURITY.md +12 -0
  162. package/agents/dialectic-deriver.md +13 -10
  163. package/agents/eval-judge.md +67 -45
  164. package/agents/skill-applied-judge.md +34 -19
  165. package/commands/session.md +17 -3
  166. package/docs/baseline.md +12 -6
  167. package/docs/ci-setup.md +53 -0
  168. package/docs/codex-setup.md +15 -3
  169. package/docs/components.md +13 -6
  170. package/docs/events-schema.md +59 -9
  171. package/docs/install.md +16 -0
  172. package/docs/persona-panel.md +1 -1
  173. package/docs/pi-setup.md +1 -1
  174. package/docs/rule-authoring.md +135 -14
  175. package/docs/scope-collision-guard.md +2 -0
  176. package/docs/session-config-reference.md +106 -11
  177. package/docs/session-config-template.md +31 -2
  178. package/docs/telemetry.md +2 -0
  179. package/hooks/_lib/hook-import-set.json +125 -8
  180. package/hooks/_lib/subagent-paths.mjs +15 -0
  181. package/hooks/_lib/subagent-transcript.mjs +582 -31
  182. package/hooks/_lib/vcs-create-matcher.mjs +217 -62
  183. package/hooks/config-protection.mjs +11 -3
  184. package/hooks/cwd-change-restore.mjs +11 -3
  185. package/hooks/enforce-commands.mjs +70 -23
  186. package/hooks/enforce-scope.mjs +143 -33
  187. package/hooks/hooks-codex.json +1 -1
  188. package/hooks/hooks.json +1 -1
  189. package/hooks/loop-guard.mjs +11 -3
  190. package/hooks/on-session-end.mjs +72 -25
  191. package/hooks/on-session-start.mjs +48 -11
  192. package/hooks/on-stop.mjs +211 -23
  193. package/hooks/operator-steer.mjs +11 -3
  194. package/hooks/post-bash-issue-budget-refund.mjs +18 -8
  195. package/hooks/post-bash-write-verify.mjs +6 -2
  196. package/hooks/post-edit-import-probe.mjs +17 -9
  197. package/hooks/post-edit-validate.mjs +13 -5
  198. package/hooks/post-subagent-discovery-validator.mjs +98 -13
  199. package/hooks/post-tool-batch-wave-signal.mjs +200 -38
  200. package/hooks/post-tool-failure-corrective-context.mjs +11 -5
  201. package/hooks/post-tooluse-frontend-slop.mjs +10 -4
  202. package/hooks/pre-auq-clarity.mjs +18 -2
  203. package/hooks/pre-bash-destructive-guard.mjs +80 -9
  204. package/hooks/pre-bash-issue-budget.mjs +119 -28
  205. package/hooks/pre-bash-memory-propose-audit.mjs +86 -54
  206. package/hooks/pre-bash-sessions-ledger-guard.mjs +391 -20
  207. package/hooks/pre-bash-staging-fence.mjs +335 -31
  208. package/hooks/pre-bash-templates-first.mjs +19 -14
  209. package/hooks/pre-task-scope-disjoint.mjs +385 -5
  210. package/hooks/skill-invocation-telemetry.mjs +2 -1
  211. package/hooks/subagent-telemetry.mjs +15 -19
  212. package/hooks/wave-scope-commit-guard.mjs +197 -100
  213. package/monitors/monitors.json +1 -1
  214. package/output-styles/wave-summary.md +1 -1
  215. package/package.json +2 -1
  216. package/pi/prompts/autopilot.md +3 -3
  217. package/pi/prompts/bootstrap.md +3 -3
  218. package/pi/prompts/brainstorm.md +3 -3
  219. package/pi/prompts/close.md +2 -2
  220. package/pi/prompts/debug.md +3 -3
  221. package/pi/prompts/discovery.md +3 -3
  222. package/pi/prompts/dispatcher.md +3 -3
  223. package/pi/prompts/eli5.md +3 -3
  224. package/pi/prompts/eval.md +3 -3
  225. package/pi/prompts/evolve.md +3 -3
  226. package/pi/prompts/go.md +2 -2
  227. package/pi/prompts/grill.md +3 -3
  228. package/pi/prompts/harness-audit.md +2 -3
  229. package/pi/prompts/memory-cleanup.md +3 -3
  230. package/pi/prompts/persona-panel.md +3 -3
  231. package/pi/prompts/plan.md +3 -3
  232. package/pi/prompts/portfolio.md +2 -2
  233. package/pi/prompts/reconcile.md +3 -3
  234. package/pi/prompts/release.md +3 -3
  235. package/pi/prompts/repo-audit.md +3 -4
  236. package/pi/prompts/session.md +2 -2
  237. package/pi/prompts/spinout.md +3 -3
  238. package/pi/prompts/sunset-review.md +3 -3
  239. package/pi/prompts/templates-ack.md +1 -1
  240. package/pi/prompts/test.md +3 -3
  241. package/pi/prompts/ux-grill.md +3 -3
  242. package/rules/README.md +1 -1
  243. package/rules/opt-in-domain/prompt-caching.md +1 -1
  244. package/rules/opt-in-stack/backend-data.md +1 -1
  245. package/rules/opt-in-stack/backend.md +3 -3
  246. package/rules/opt-in-stack/frontend.md +1 -1
  247. package/rules/opt-in-stack/security-web.md +3 -3
  248. package/rules/opt-in-stack/swift.md +1 -1
  249. package/scripts/archive-closed-prds.mjs +2 -2
  250. package/scripts/auq-audit.mjs +2 -3
  251. package/scripts/autopilot.mjs +23 -2
  252. package/scripts/backfill-abandoned-sessions.mjs +171 -15
  253. package/scripts/backfill-evidence-digest.mjs +2 -1
  254. package/scripts/backfill-learnings-from-vault.mjs +2 -2
  255. package/scripts/check-package-manager.mjs +2 -2
  256. package/scripts/check-sessions-integrity.mjs +300 -0
  257. package/scripts/ci/assert-vitest-green.mjs +2 -1
  258. package/scripts/dialectic-deriver.mjs +50 -13
  259. package/scripts/emit-session.mjs +77 -32
  260. package/scripts/eval-session.mjs +65 -3
  261. package/scripts/export-hw-learnings.mjs +2 -1
  262. package/scripts/express-path.mjs +1 -1
  263. package/scripts/gc-stale-worktrees.mjs +2 -1
  264. package/scripts/generate-agents-skills.mjs +102 -29
  265. package/scripts/generate-codex-skills.mjs +48 -4
  266. package/scripts/generate-cursor-adapter.mjs +220 -11
  267. package/scripts/generate-hook-import-set.mjs +12 -27
  268. package/scripts/generate-pi-prompts.mjs +183 -13
  269. package/scripts/github-protection-audit.mjs +2 -3
  270. package/scripts/lib/agent-frontmatter.mjs +23 -1
  271. package/scripts/lib/agent-status.mjs +2 -31
  272. package/scripts/lib/auq/clarity.mjs +10 -2
  273. package/scripts/lib/auq/parse.mjs +12 -31
  274. package/scripts/lib/auq/schema.mjs +56 -41
  275. package/scripts/lib/auto-dialectic.mjs +304 -15
  276. package/scripts/lib/autopilot/flags.mjs +12 -1
  277. package/scripts/lib/autopilot/kill-switches.mjs +6 -3
  278. package/scripts/lib/autopilot/loop.mjs +14 -1
  279. package/scripts/lib/autopilot/stall-sampler.mjs +80 -23
  280. package/scripts/lib/ci-status-banner.mjs +376 -16
  281. package/scripts/lib/claude-md-budget-lint.mjs +2 -5
  282. package/scripts/lib/command-blocker.mjs +408 -33
  283. package/scripts/lib/config/dialectic.mjs +12 -3
  284. package/scripts/lib/config/drift-check.mjs +19 -0
  285. package/scripts/lib/config/gate.mjs +74 -0
  286. package/scripts/lib/config/reaper.mjs +162 -0
  287. package/scripts/lib/config.mjs +14 -0
  288. package/scripts/lib/convergence-monitor.mjs +76 -13
  289. package/scripts/lib/cursor-hook-bridge.mjs +2 -2
  290. package/scripts/lib/description-surface.mjs +2 -5
  291. package/scripts/lib/dispatcher/cli.mjs +2 -1
  292. package/scripts/lib/ecosystem-health.mjs +11 -0
  293. package/scripts/lib/ecosystem-wizard.mjs +2 -1
  294. package/scripts/lib/eval/engine.mjs +421 -53
  295. package/scripts/lib/eval/judge.mjs +463 -40
  296. package/scripts/lib/eval/schema.mjs +10 -1
  297. package/scripts/lib/events-rotation.mjs +221 -25
  298. package/scripts/lib/events-schema.mjs +114 -0
  299. package/scripts/lib/events.mjs +524 -5
  300. package/scripts/lib/fetch-baseline.mjs +3 -8
  301. package/scripts/lib/frontmatter-guard.mjs +21 -10
  302. package/scripts/lib/gates/gate-baseline.mjs +27 -2
  303. package/scripts/lib/gates/gate-full.mjs +28 -3
  304. package/scripts/lib/gates/gate-helpers.mjs +243 -21
  305. package/scripts/lib/gates/gate-incremental.mjs +28 -3
  306. package/scripts/lib/gates/gate-per-file.mjs +27 -2
  307. package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +2 -1
  308. package/scripts/lib/gitlab-portfolio/cli.mjs +2 -1
  309. package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +6 -1
  310. package/scripts/lib/instruction-budget-guard.mjs +332 -50
  311. package/scripts/lib/io.mjs +42 -8
  312. package/scripts/lib/is-main-module.mjs +82 -0
  313. package/scripts/lib/issue-close-strip-labels.mjs +207 -49
  314. package/scripts/lib/js-mask.mjs +197 -0
  315. package/scripts/lib/learnings/evolve-telemetry.mjs +11 -7
  316. package/scripts/lib/locks/index.mjs +32 -25
  317. package/scripts/lib/maintenance-due-banner.mjs +122 -91
  318. package/scripts/lib/orphan-reaper.mjs +1588 -0
  319. package/scripts/lib/peer-cards/merger.mjs +48 -10
  320. package/scripts/lib/peer-cards/reader.mjs +78 -2
  321. package/scripts/lib/peer-discovery.mjs +2 -5
  322. package/scripts/lib/playwright-driver/runner.mjs +2 -1
  323. package/scripts/lib/process-group.mjs +899 -0
  324. package/scripts/lib/quality-gate.mjs +107 -28
  325. package/scripts/lib/reconcile/backlog.mjs +368 -0
  326. package/scripts/lib/reconcile/engine.mjs +55 -188
  327. package/scripts/lib/reconcile/rule-expiry-sweep.mjs +884 -0
  328. package/scripts/lib/reconcile/sanitize.mjs +69 -3
  329. package/scripts/lib/reconcile-nudge-banner.mjs +138 -45
  330. package/scripts/lib/resource-probe/parsers.mjs +31 -0
  331. package/scripts/lib/rule-loader.mjs +41 -12
  332. package/scripts/lib/rules-sync.mjs +2 -5
  333. package/scripts/lib/scope-echo.mjs +429 -7
  334. package/scripts/lib/scope-gate.mjs +605 -1
  335. package/scripts/lib/session-close-backfill.mjs +91 -12
  336. package/scripts/lib/session-id.mjs +9 -20
  337. package/scripts/lib/session-invocation.mjs +20 -0
  338. package/scripts/lib/session-schema/constants.mjs +30 -2
  339. package/scripts/lib/session-schema/normalizer.mjs +56 -4
  340. package/scripts/lib/session-schema.mjs +8 -3
  341. package/scripts/lib/session-start-probes.mjs +95 -10
  342. package/scripts/lib/sessions-canonical.mjs +23 -0
  343. package/scripts/lib/sessions-integrity-banner.mjs +7 -1
  344. package/scripts/lib/sessions-staleness-banner.mjs +193 -51
  345. package/scripts/lib/skill-evidence-window.mjs +891 -0
  346. package/scripts/lib/skill-evolution/candidate-intake.mjs +133 -12
  347. package/scripts/lib/skill-evolution/engine.mjs +18 -9
  348. package/scripts/lib/skill-judge.mjs +45 -3
  349. package/scripts/lib/state-md.mjs +84 -3
  350. package/scripts/lib/sunset/walker.mjs +31 -4
  351. package/scripts/lib/tail-window.mjs +56 -0
  352. package/scripts/lib/telemetry/schema.mjs +30 -0
  353. package/scripts/lib/telemetry/sync.mjs +61 -6
  354. package/scripts/lib/telemetry-flush-health-banner.mjs +4 -22
  355. package/scripts/lib/test-runner/issue-reconcile.mjs +48 -16
  356. package/scripts/lib/tests-src-ratio.mjs +2 -6
  357. package/scripts/lib/tmux-layout/telemetry-stats.mjs +74 -14
  358. package/scripts/lib/user-invocable-skills.mjs +205 -0
  359. package/scripts/lib/ux-grill/reconcile.mjs +48 -22
  360. package/scripts/lib/validate/check-agents-skills.mjs +26 -15
  361. package/scripts/lib/validate/check-banner-parity.mjs +2 -2
  362. package/scripts/lib/validate/check-cursor-adapter.mjs +3 -2
  363. package/scripts/lib/validate/check-dead-bridge.mjs +2 -2
  364. package/scripts/lib/validate/check-doc-cli-commands.mjs +2 -2
  365. package/scripts/lib/validate/check-entry-guard.mjs +329 -0
  366. package/scripts/lib/validate/check-guard-requires-parity.mjs +2 -2
  367. package/scripts/lib/validate/check-hook-entry-guards.mjs +636 -0
  368. package/scripts/lib/validate/check-hooks-emit-event-guard.mjs +2 -2
  369. package/scripts/lib/validate/check-learning-provenance.mjs +2 -2
  370. package/scripts/lib/validate/check-pi-prompts.mjs +1 -0
  371. package/scripts/lib/validate/check-rules.mjs +7 -5
  372. package/scripts/lib/validate/check-skill-links.mjs +35 -6
  373. package/scripts/lib/validate/check-skill-script-paths.mjs +241 -29
  374. package/scripts/lib/validate/check-test-git-config-target.mjs +26 -36
  375. package/scripts/lib/validate/check-unicode-safety.mjs +2 -2
  376. package/scripts/lib/validate/check-untracked-test-deps.mjs +9 -104
  377. package/scripts/lib/validate/check-unwired-features.mjs +220 -33
  378. package/scripts/lib/validate/check-validator-registration.mjs +36 -12
  379. package/scripts/lib/validate/check-vcs-repo-flag.mjs +2 -2
  380. package/scripts/lib/validate/confidential-names.mjs +10 -0
  381. package/scripts/lib/validate-vendored-rules.mjs +39 -12
  382. package/scripts/lib/vault-mirror/namespace.mjs +46 -8
  383. package/scripts/lib/vault-mirror/process.mjs +10 -3
  384. package/scripts/lib/vault-mirror/render-sessions.mjs +12 -2
  385. package/scripts/lib/vault-status/narrative-mirror.mjs +31 -7
  386. package/scripts/lib/vault-yaml.mjs +118 -0
  387. package/scripts/lib/wave-transcript-tail.mjs +2 -2
  388. package/scripts/lib/worktree/lifecycle.mjs +153 -1
  389. package/scripts/lock-reaper.mjs +2 -1
  390. package/scripts/materialize-wave-scope.mjs +87 -4
  391. package/scripts/migrate-sessions-jsonl.mjs +2 -1
  392. package/scripts/migrate-vault-paths.mjs +2 -3
  393. package/scripts/release-session-lock.mjs +305 -0
  394. package/scripts/release.mjs +109 -39
  395. package/scripts/relocate-vault-corpus.mjs +2 -3
  396. package/scripts/repair-invalid-sessions.mjs +2 -2
  397. package/scripts/resolve-session-invocation.mjs +59 -0
  398. package/scripts/run-quality-gate.mjs +156 -17
  399. package/scripts/session-shape.mjs +2 -2
  400. package/scripts/site-numbers.mjs +35 -11
  401. package/scripts/sweep-expired-rules.mjs +227 -0
  402. package/scripts/validate-plugin.mjs +21 -0
  403. package/scripts/validate-wave-scope.mjs +32 -105
  404. package/scripts/vault-consolidate.mjs +2 -2
  405. package/scripts/vault-mirror.mjs +11 -4
  406. package/scripts/wave-scope-binding.mjs +2 -3
  407. package/skills/_shared/bootstrap-gate.md +1 -1
  408. package/skills/_shared/monitor-patterns.md +1 -1
  409. package/skills/_shared/platform-tools.md +23 -11
  410. package/skills/_shared/research-evidence.md +53 -0
  411. package/skills/_shared/state-ownership.md +3 -0
  412. package/skills/autopilot/SKILL.md +80 -11
  413. package/skills/bootstrap/SKILL.md +51 -1
  414. package/skills/brainstorm/SKILL.md +16 -0
  415. package/skills/claude-md-drift-check/SKILL.md +1 -1
  416. package/skills/claude-md-drift-check/checker.mjs +49 -11
  417. package/{commands/close.md → skills/close/SKILL.md} +9 -3
  418. package/skills/convergence-monitoring/README.md +8 -1
  419. package/skills/convergence-monitoring/SIGNALS.md +50 -6
  420. package/skills/convergence-monitoring/SKILL.md +15 -6
  421. package/skills/debug/SKILL.md +10 -0
  422. package/skills/discovery/SKILL.md +24 -1
  423. package/skills/discovery/probes-session.md +2 -2
  424. package/skills/dispatcher/SKILL.md +38 -7
  425. package/skills/eli5/SKILL.md +11 -0
  426. package/skills/eval/SKILL.md +52 -23
  427. package/skills/eval/rubric-v1.md +1 -0
  428. package/skills/eval/rubric-v2.md +457 -0
  429. package/skills/evolve/SKILL.md +9 -2
  430. package/skills/evolve/references/evolve-dialectic-mode.md +46 -25
  431. package/skills/gitlab-ops/SKILL.md +3 -2
  432. package/{commands/go.md → skills/go/SKILL.md} +9 -1
  433. package/skills/grill/SKILL.md +19 -0
  434. package/{commands/harness-audit.md → skills/harness-audit/SKILL.md} +7 -2
  435. package/skills/hook-development/SKILL.md +46 -41
  436. package/skills/memory-cleanup/SKILL.md +7 -0
  437. package/skills/npm-publish/SKILL.md +2 -2
  438. package/skills/persona-panel/SKILL.md +56 -1
  439. package/skills/persona-panel/persona-format.md +1 -1
  440. package/skills/plan/SKILL.md +28 -1
  441. package/{commands/portfolio.md → skills/portfolio/SKILL.md} +8 -2
  442. package/skills/reconcile/SKILL.md +21 -0
  443. package/{commands/release.md → skills/release/SKILL.md} +16 -2
  444. package/skills/repo-audit/SKILL.md +7 -0
  445. package/skills/session-end/SKILL.md +13 -16
  446. package/skills/session-end/discovery-scan.md +1 -1
  447. package/skills/session-end/phase-3-6-tail.md +55 -9
  448. package/skills/session-end/plan-verification.md +2 -2
  449. package/skills/session-end/references/phase-5-issue-cleanup.md +9 -14
  450. package/skills/session-end/session-metrics-write.md +10 -0
  451. package/skills/session-plan/SKILL.md +18 -6
  452. package/skills/session-plan/references/session-plan-task-classification.md +2 -2
  453. package/skills/session-start/SKILL.md +5 -4
  454. package/skills/session-start/phase-8-5-express-path.md +6 -6
  455. package/skills/session-start/references/phase-1-5-session-continuity.md +1 -1
  456. package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +1 -1
  457. package/skills/session-start/references/phase-4-ssot-environment-check.md +6 -4
  458. package/skills/spinout/SKILL.md +12 -1
  459. package/skills/sunset-review/SKILL.md +13 -0
  460. package/{commands/test.md → skills/test/SKILL.md} +10 -4
  461. package/skills/ux-grill/SKILL.md +20 -2
  462. package/skills/wave-executor/SKILL.md +14 -7
  463. package/skills/wave-executor/circuit-breaker.md +2 -0
  464. package/skills/wave-executor/references/wave-executor-state-init.md +18 -4
  465. package/skills/wave-executor/references/wave-loop-dispatch.md +5 -2
  466. package/skills/wave-executor/references/wave-loop-review.md +17 -1
  467. package/commands/autopilot.md +0 -80
  468. package/commands/bootstrap.md +0 -56
  469. package/commands/brainstorm.md +0 -48
  470. package/commands/debug.md +0 -36
  471. package/commands/discovery.md +0 -32
  472. package/commands/dispatcher.md +0 -59
  473. package/commands/eli5.md +0 -33
  474. package/commands/eval.md +0 -28
  475. package/commands/evolve.md +0 -10
  476. package/commands/grill.md +0 -45
  477. package/commands/memory-cleanup.md +0 -26
  478. package/commands/persona-panel.md +0 -121
  479. package/commands/plan.md +0 -15
  480. package/commands/reconcile.md +0 -23
  481. package/commands/repo-audit.md +0 -24
  482. package/commands/spinout.md +0 -15
  483. package/commands/sunset-review.md +0 -27
  484. package/commands/ux-grill.md +0 -51
@@ -18,6 +18,7 @@ total-waves: <N>
18
18
  # Optional fields (schema-version 1, additive for backward-compat):
19
19
  updated: <ISO 8601 UTC> # last write timestamp, touched by any writer
20
20
  session: <session-label> # attribution/history label; normally semantic since #573, legacy UUID-v4 remains readable; never a lock/registry ownership key
21
+ session-id: <raw id> # the RAW/native harness session id from session.lock (#1368); omit when absent; never a lock/registry ownership key
21
22
  session-start-ref: <sha> # git ref at session start
22
23
  ---
23
24
  ```
@@ -25,6 +26,8 @@ session-start-ref: <sha> # git ref at session start
25
26
  ### Required vs. optional fields
26
27
 
27
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.
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.
28
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.
29
32
 
30
33
  The `session-type: none` + `status: idle` combination is used only for bootstrap-scaffolded placeholder files (no active session).
@@ -9,12 +9,47 @@ description: >
9
9
  record per loop run. Phase C scaffold (issue #277); implementation lives in
10
10
  scripts/lib/autopilot.mjs (Phase C-1 follow-up).
11
11
  user-invocable: true
12
+ argument-hint: "[--headless] [--verbose] [--max-sessions=N] [--max-hours=H] [--confidence-threshold=0.X] [--dry-run]"
12
13
  tags: [phase-c, autopilot, autonomous, loop]
13
14
  model: sonnet
14
15
  ---
15
16
 
16
17
  # Autopilot Skill
17
18
 
19
+ ## Invocation
20
+
21
+ The user invokes `/autopilot` with arguments: **$ARGUMENTS**. This is autonomous
22
+ session-orchestration mode — a top-level invocation only, never from inside a running
23
+ session.
24
+
25
+ Parse `$ARGUMENTS` before anything else. Unrecognized flags are ignored; out-of-range
26
+ values silently clamp to bounds. Use `parseFlags` from `scripts/lib/autopilot.mjs` for
27
+ canonical parsing — never re-implement clamping inline. The loop flags
28
+ (`--max-sessions`, `--max-hours`, `--confidence-threshold`, `--dry-run`) and their
29
+ defaults/bounds are tabled once in § Command Surface below. Two further flags belong to
30
+ the invocation surface only:
31
+
32
+ | Flag | Default | Meaning |
33
+ |------|---------|---------|
34
+ | `--headless` | `false` | Run via the standalone driver `scripts/autopilot.mjs`, which spawns `claude -p '/session <mode>'` as a child process per iteration. Required for unattended walk-away mode. Without it, `/autopilot` runs the in-process driver inside the current chat session (see § Production Wiring). |
35
+ | `--verbose` | `false` | Verbose driver output. |
36
+
37
+ ### Headless (`claude -p`)
38
+
39
+ Headless requirements:
40
+
41
+ - Anthropic API key configured for `claude -p` (Claude Code CLI auth).
42
+ - `scripts/autopilot.mjs` reads `sessions.jsonl` tail after each child exit to construct
43
+ the `sessionRunner` return shape — the spawned session must complete cleanly and append
44
+ its record (session-end Phase 3.7 handles this).
45
+ - `AUTOPILOT_RUN_ID` env var is propagated to the child so session-end stamps it onto the
46
+ per-iteration `sessions.jsonl` record.
47
+
48
+ Do NOT re-implement loop logic inline — this skill and `scripts/lib/autopilot.mjs` are
49
+ authoritative. Kill-switches are enforced by `scripts/lib/autopilot.mjs`, not inline by
50
+ Claude. The runtime writes ONE record to `.orchestrator/metrics/autopilot.jsonl` per
51
+ invocation via atomic tmp+rename; no other code path appends to that file.
52
+
18
53
  ## Phase 0.5: Parallel-Aware Preamble
19
54
 
20
55
  > Skip silently when `persistence: false` in Session Config.
@@ -177,7 +212,8 @@ Phase C-1 ships `runLoop` as a pure controller. Phase C-1.c ships `buildLiveSign
177
212
  the canonical signals-assembly helper. This section documents the **in-process driver
178
213
  protocol** (Option B from #301): how Claude — running as the coordinator in a chat
179
214
  session — drives `runLoop` between manual `/session` invocations. The headless wrapper
180
- (Option A, `scripts/autopilot.mjs` CLI spawning `claude -p`) is reserved for Phase C-5.
215
+ (Option A, `scripts/autopilot.mjs` CLI spawning `claude -p`) is selected with `--headless`
216
+ — see § Invocation.
181
217
 
182
218
  ### Dependency-Injection Contract
183
219
 
@@ -187,8 +223,8 @@ session — drives `runLoop` between manual `/session` invocations. The headless
187
223
  |---|---|---|
188
224
  | `modeSelector` | `() => Promise<{mode, confidence, rationale?}>` | wraps `selectMode(await buildLiveSignals())` |
189
225
  | `sessionRunner` | `({mode, autopilotRunId}) => Promise<{session_id, agent_summary?, effectiveness?}>` | wraps a `/session <mode>` invocation; reads `sessions.jsonl` tail to construct return value |
190
- | `resourceEvaluator` | `() => {verdict}` | wraps `evaluate(await probe(), thresholds)` from `resource-probe.mjs` |
191
- | `peerCounter` | `() => number` | reads `claude_processes_count` from a fresh `probe()` snapshot |
226
+ | `resourceEvaluator` | `() => {verdict}` | calls `evaluate(cachedProbeSnapshot, thresholds)` from `resource-probe.mjs` over a snapshot `peerCounter` refreshed on the prior iteration — never calls `probe()` itself, which is what keeps it synchronous |
227
+ | `peerCounter` | `() => Promise<number>` | returns `peers.length` from `detectPeers({ sessionId, freshnessMin: 15 })` (a SESSION count, not a process count — see `host-resources.md` HR-103) while refreshing the cached `probe()` snapshot `resourceEvaluator` reads |
192
228
 
193
229
  `abortSignal` is optional (Ctrl+C / Esc → `user-abort` kill-switch).
194
230
 
@@ -199,6 +235,7 @@ import { runLoop, parseFlags } from '$PLUGIN_ROOT/scripts/lib/autopilot.mjs';
199
235
  import { buildLiveSignals } from '$PLUGIN_ROOT/scripts/lib/build-live-signals.mjs';
200
236
  import { selectMode } from '$PLUGIN_ROOT/scripts/lib/mode-selector.mjs';
201
237
  import { probe, evaluate } from '$PLUGIN_ROOT/scripts/lib/resource-probe.mjs';
238
+ import { detectPeers } from '$PLUGIN_ROOT/scripts/lib/session-registry.mjs';
202
239
 
203
240
  const flags = parseFlags(process.argv.slice(2));
204
241
 
@@ -214,14 +251,27 @@ const modeSelector = async () => {
214
251
  return selectMode(signals);
215
252
  };
216
253
 
254
+ let cachedProbeSnapshot = null; // written by peerCounter, read by resourceEvaluator
255
+
217
256
  const resourceEvaluator = () => {
218
- const snapshot = probeSync(); // or cached snapshot if probe is async
219
- return evaluate(snapshot, thresholds);
257
+ // Synchronous by contract: never calls probe() itself (it is async) — reads
258
+ // the snapshot peerCounter refreshed on the prior iteration.
259
+ if (cachedProbeSnapshot === null) {
260
+ return { verdict: 'warn', reasons: ['probe not yet available'], recommended_agents_per_wave_cap: null };
261
+ }
262
+ return evaluate(cachedProbeSnapshot, thresholds);
220
263
  };
221
264
 
222
- const peerCounter = () => {
223
- // Synchronous-friendly count from a recent probe snapshot.
224
- return latestSnapshot.claude_processes_count ?? 0;
265
+ const peerCounter = async () => {
266
+ // A SESSION count, not a process count (host-resources.md HR-103) —
267
+ // claude_processes_count runs ~6 processes per session. `ownSessionId` is
268
+ // this coordinator's registry id, so detectPeers() excludes it.
269
+ const [peers, snapshot] = await Promise.all([
270
+ detectPeers({ sessionId: ownSessionId, freshnessMin: 15 }),
271
+ probe(),
272
+ ]);
273
+ cachedProbeSnapshot = snapshot;
274
+ return peers.length;
225
275
  };
226
276
 
227
277
  const sessionRunner = async ({ mode, autopilotRunId }) => {
@@ -253,8 +303,28 @@ The in-process driver has Claude (the coordinator) call `/session <mode>` betwee
253
303
  - **Pro:** zero new infra. Reuses canonical kill-switch logic. Validates `buildLiveSignals`
254
304
  against real Phase 7.5 swap before headless complexity. Each iteration carries
255
305
  inter-session memory through STATE.md / sessions.jsonl / learnings.
256
- - **Con:** not truly autonomous — Claude must stay in the chat. Doesn't deliver
257
- walk-away UX. That's Phase C-5's job.
306
+ - **Con:** not truly autonomous — Claude must stay in the chat. The in-process
307
+ driver does not deliver walk-away UX; that is the shipped headless driver
308
+ (`--headless`, `scripts/autopilot.mjs`, Phase C-5; see § Headless Driver Wiring).
309
+
310
+ ### Headless Driver Wiring (Option A — `scripts/autopilot.mjs`)
311
+
312
+ The standalone headless driver invoked via `--headless` (see § Invocation) wires all
313
+ four required `runLoop` dependencies (`modeSelector`, `sessionRunner`,
314
+ `resourceEvaluator`, `peerCounter`) plus the optional `abortSignal` to production
315
+ sources — distinct from, and more concrete than, the in-process skeleton above:
316
+
317
+ - `sessionRunner` — spawns `claude -p '/session <mode>'` as a child process; after it
318
+ exits cleanly, reads the `sessions.jsonl` tail to construct the return shape
319
+ `{session_id, agent_summary?, effectiveness?}` (`scripts/autopilot.mjs` `sessionRunner`).
320
+ - `resourceEvaluator` — calls `evaluate(cachedProbeSnapshot, thresholds)` from
321
+ `scripts/lib/resource-probe.mjs`, reading a snapshot refreshed by `peerCounter` on the
322
+ prior iteration so the function itself stays synchronous, per the `runLoop` contract
323
+ (`scripts/autopilot.mjs` `resourceEvaluator`).
324
+ - `peerCounter` — calls `detectPeers({ sessionId: autopilotRunId, freshnessMin: 15 })` from
325
+ `scripts/lib/session-registry.mjs` AND refreshes the cached `probe()` snapshot in the
326
+ same call, returning `peers.length` (`scripts/autopilot.mjs` `makePeerCounter`).
327
+ - `abortSignal` — an `AbortController` aborted on the process's `SIGINT` handler.
258
328
 
259
329
  ### `autopilot_run_id` Propagation
260
330
 
@@ -387,7 +457,6 @@ Single-story `/autopilot` takes no Session Config block. Multi-story
387
457
  - PRD: "Autopilot Loop" (#277; archived in the private Meta-Vault)
388
458
  - Implementation (Phase C-1 + C-1.b): `scripts/lib/autopilot.mjs` — exports `runLoop`, `parseFlags`, `writeAutopilotJsonl`, `KILL_SWITCHES`, `FLAG_BOUNDS`, `SCHEMA_VERSION`, `DEFAULT_PEER_ABORT_THRESHOLD`, `DEFAULT_JSONL_PATH`, `DEFAULT_CARRYOVER_THRESHOLD`
389
459
  - Tests (Phase C-1 + C-1.b): `tests/lib/autopilot.test.mjs`
390
- - Command file: `commands/autopilot.md`
391
460
  - Mode-Selector contract: `skills/mode-selector/SKILL.md`
392
461
  - Resource probe: `scripts/lib/resource-probe.mjs`
393
462
  - Session registry: `scripts/lib/session-registry.mjs`
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: bootstrap
3
3
  user-invocable: true
4
+ disable-model-invocation: true
5
+ argument-hint: "[--upgrade <tier>]"
4
6
  tags: [bootstrap, setup, scaffold, init]
5
7
  model: sonnet
6
8
  model-preference: sonnet
@@ -15,6 +17,54 @@ description: >
15
17
 
16
18
  # Bootstrap Skill
17
19
 
20
+ ## Invocation
21
+
22
+ The user invokes `/bootstrap` with arguments: **$ARGUMENTS**. Direct invocation runs with
23
+ `INVOCATION_MODE = direct` (see § Invocation Context) and is standalone: after bootstrap
24
+ completes, report the files created and the git commit hash, and do NOT automatically
25
+ continue into any other skill.
26
+
27
+ **TL;DR — for first-time users:** Run `/bootstrap` with no flags. The skill auto-detects the right tier (fast/standard/deep) from your repo, recommends one with a one-line reason, then walks a **fixed questionnaire** — tier/stack (1–2 prompts), owner persona (5), dispatcher autonomy (1); **7–9 prompts** on a first-run full bootstrap. Bestätigen → fertig. Keine weiteren Schritte.
28
+
29
+ The flags below cover special cases (re-adopting an existing repo, upgrading a tier, syncing rules). If you don't recognize the case in the description, you don't need the flag.
30
+
31
+ > **Instruction file alias:** Bootstrap creates and reads `CLAUDE.md` (or `AGENTS.md` on Codex CLI). The two are transparent aliases — pick one, never both. Resolution rule: see `skills/_shared/instruction-file-resolution.md`.
32
+
33
+ ### Standard usage (no flags)
34
+
35
+ This is the path 95 % of users want.
36
+
37
+ | Invocation | Behavior |
38
+ |------------|----------|
39
+ | `/bootstrap` | Auto-detect tier (fast / standard / deep) from repo context. Present recommendation via `AskUserQuestion` with options to confirm or override. Tier/stack: 1–2 questions; first-run full bootstrap adds owner interview (5, `owner-interview.mjs`) + dispatcher-autonomy capture (1). Then scaffold files + commit. |
40
+
41
+ What the user sees:
42
+
43
+ ```
44
+ Skill: "Repo leer. Empfehle 'standard' weil <reason>. Passt das?"
45
+ User: [Enter on "standard (Empfohlen)"]
46
+ Skill: <writes files, commits, prints summary>
47
+ ```
48
+
49
+ ### Flag reference (special cases)
50
+
51
+ Only use a flag if you have one of the situations described. Parsed flags decide the mode
52
+ dispatch in § Invocation Context — `--fast` / `--standard` / `--deep` skip the tier
53
+ confirmation question, while `--retroactive`, `--refresh-lock`, `--sync-rules` and
54
+ `--ecosystem-health` are standalone short-circuit flows that run to completion in this
55
+ skill without dispatching to a tier template.
56
+
57
+ | Flag | When to use it |
58
+ |------|----------------|
59
+ | `--upgrade <tier>` | You bootstrapped `fast` earlier and now need `standard` or `deep`. Idempotent — writes only the delta. Refuses downgrade. Valid: `fast → standard`, `fast → deep`, `standard → deep`. |
60
+ | `--retroactive` | The repo already has `CLAUDE.md` (or `AGENTS.md` on Codex CLI) + `## Session Config` but no `bootstrap.lock` (manually bootstrapped before the gate existed). Writes the lock based on file inventory; **makes no scaffolding changes**. Commit: `chore: bootstrap lock (retroactive)`. |
61
+ | `--refresh-lock` | Your `bootstrap.lock` already has valid `version`/`tier` fields but the freshness probe flags it as stale or plugin-version-drifted — `--retroactive` is a no-op here. Acknowledges the current plugin version and resets the freshness clock (`refreshed-at` + `refreshed-plugin-version`) without touching the lock's original bootstrap provenance. No scaffolding, no auto-commit. |
62
+ | `--sync-rules` | Pull canonical rules from the plugin's `rules/` library into `.claude/rules/`. Preserves local rules (files without the plugin source header). Standalone — does not touch `bootstrap.lock`. |
63
+ | `--ecosystem-health` | Run the ecosystem-health wizard: detects CI provider + package manager, prompts for health endpoints, pipelines, and critical issue labels. Writes the config block + `.orchestrator/policy/ecosystem.json`. No scaffolding, no auto-commit. |
64
+ | `--fast` / `--standard` / `--deep` | Skip the tier confirmation question (e.g., for scripted runs). Equivalent to running `/bootstrap` and selecting that option. |
65
+
66
+ All flag-driven flows are idempotent — running twice with no upstream change is a no-op.
67
+
18
68
  ## Overview
19
69
 
20
70
  This skill runs when the Bootstrap Gate is closed (missing CLAUDE.md, Session Config, or `.orchestrator/bootstrap.lock`) or when the user invokes `/bootstrap` directly. It scaffolds the minimum structure required by all session-orchestrator skills, commits it, and writes the lock file that opens the gate for all future invocations.
@@ -26,7 +76,7 @@ This skill runs when the Bootstrap Gate is closed (missing CLAUDE.md, Session Co
26
76
  Before starting, determine how this skill was invoked:
27
77
 
28
78
  - **Transitive (gate-closed):** Invoked from another skill's Phase 0. The user's original intent (their first prompt) is available in context. After bootstrap completes, execution must return to the original skill's Phase 1.
29
- - **Direct (`/bootstrap`):** User invoked manually. Parse `$ARGUMENTS` for flags: `--fast`, `--standard`, `--deep`, `--upgrade <tier>`, `--retroactive`. See `commands/bootstrap.md` for flag semantics.
79
+ - **Direct (`/bootstrap`):** User invoked manually. Parse `$ARGUMENTS` for flags: `--fast`, `--standard`, `--deep`, `--upgrade <tier>`, `--retroactive`. See § Invocation above for flag semantics.
30
80
 
31
81
  Store `INVOCATION_MODE = transitive | direct`.
32
82
 
@@ -3,6 +3,9 @@ name: brainstorm
3
3
  description: Use when you have a feature idea but the scope or UX is still ambiguous — runs a lightweight Socratic design dialogue (3-5 AUQ rounds) and writes a spec markdown file. Use BEFORE /plan feature when product intent needs validation; skip to /plan feature when scope is already clear. HARD-GATE prevents any code work until the design is user-approved.
4
4
  model: inherit
5
5
  color: cyan
6
+ user-invocable: true
7
+ disable-model-invocation: true
8
+ argument-hint: "[topic-or-feature-slug]"
6
9
  tools: Read, Grep, Glob, Bash, Write
7
10
  ---
8
11
 
@@ -10,6 +13,19 @@ tools: Read, Grep, Glob, Bash, Write
10
13
 
11
14
  > Lightweight Socratic design dialogue for per-feature exploration. Sibling to `/plan feature`, not a replacement. Produces `docs/specs/YYYY-MM-DD-<slug>-design.md` after the user approves an approach.
12
15
 
16
+ ## Invocation
17
+
18
+ The user invokes `/brainstorm` with arguments: **$ARGUMENTS**.
19
+
20
+ The optional argument is a topic or feature slug used in the spec filename (lowercase, hyphens, no special characters). If absent, the skill derives a slug from the user's Phase 1 answer.
21
+
22
+ Examples:
23
+ - `/brainstorm` — no slug; skill prompts for the problem in Phase 1
24
+ - `/brainstorm export-to-csv` — slug pre-set to `export-to-csv`
25
+ - `/brainstorm "user notification system"` — normalize to `user-notification-system`
26
+
27
+ The HARD-GATE in Phase 0 below prevents any Edit, Write (code), or Bash (implementation) call until the user approves the design in Phase 6 — the only Write permitted before approval is the spec file itself in Phase 4.
28
+
13
29
  ## Soul Reference
14
30
 
15
31
  Read `soul.md` in this skill directory before anything else. It defines WHO you are — a Design Facilitator who shapes vague ideas into approved designs through Socratic questioning. Every interaction in this skill should reflect that identity.
@@ -65,7 +65,7 @@ Check 7 (issue #600) is the **only** check that intentionally reads BOTH instruc
65
65
 
66
66
  The same predicate guards Check 9's probe 2a, which iterates `['CLAUDE.md', 'AGENTS.md']`: with an aliased `AGENTS.md` it scans `CLAUDE.md` only, because otherwise every dangling `.claude/rules/*.md` citation would be reported TWICE — one defect, two errors, and in `--mode strict` a doubled blocking surface against a file the operator is not allowed to edit.
67
67
 
68
- Check 9 (`rule-scoping`) validates `.claude/rules/*.md` frontmatter against the `scripts/lib/rule-loader.mjs` contract, catching the class of defect where a rule silently drifts out of the activation pipeline the loader actually implements. Six probes: **(1) paths-presence** — a top-level `paths:` frontmatter key is not a key `rule-loader.mjs` recognises (it only reads `globs:`), so a rule with `paths:` silently loads ALWAYS-ON regardless of intended file scope; flagged as an error. **(2) cited-but-missing** — `(a)` `.claude/rules/<name>.md` citations inside `CLAUDE.md`/`AGENTS.md` that don't resolve to a file on disk, and `(b)` bare `<name>.md` tokens in a rule's own `## See Also` footer that don't exist as sibling rule files (tokens carrying a path separator, e.g. `../../skills/_shared/state-ownership.md`, are cross-directory references and explicitly out of scope); both flagged as errors. **(3) zero-match-globs** — a `globs:` pattern matching zero files in `git ls-files` (falls back to a manual directory walk when git is unavailable); flagged as a WARNING, not an error, because library/exemplar repos legitimately carry dead stack rules. **(4) foreign-glob** — a glob pattern containing a PascalCase product-like token (regex `[A-Z][a-z]+[A-Z]`, e.g. `WalkAITalkieTests`) — a likely copy-paste leftover from another project's rule scope; flagged as a WARNING. **(5) unreadable-file** — a rule file that could not be read (permissions, a race with a concurrent delete); flagged as a WARNING rather than silently skipped, so a completeness audit does not drop files, and so an unreadable file cannot brick the gate under `mode: hard`. **(6) fleet-intent-glob** — a `globs:` pattern DECLARED as fleet intent goes to `notes[]` (see below), never to `warnings[]`, and the declaration also settles probe 4 for that same pattern: a pattern the rule author declared is by construction not a copy-paste leftover. Glob matching reuses the same picomatch-with-inline-fallback resolution `scripts/lib/rule-loader.mjs` uses (`parseGlobsFrontmatter` is imported directly; the picomatch resolution itself is duplicated locally since `rule-loader.mjs` does not export a public matcher function). The check is skipped silently (no `checks_run` entry, no `checks_skipped` entry) when `.claude/rules/` is absent, or explicitly via `--skip-rule-scoping`.
68
+ Check 9 (`rule-scoping`) validates `.claude/rules/*.md` frontmatter against the `scripts/lib/rule-loader.mjs` contract, catching the class of defect where a rule silently drifts out of the activation pipeline the loader actually implements. Six probes: **(1) paths-presence** — since #795 `paths:` is a full same-shape alias for `globs:` in `rule-loader.mjs` (`globs:` wins silently when both are present), so a well-formed `paths:`-only rule loads correctly SCOPED and is NOT flagged (#840). The probe fires only when the frontmatter textually carries a top-level `paths:` key AND `parseGlobsFrontmatter` — the loader's own parser, imported rather than re-derived returns `globs === null` (e.g. a malformed frontmatter line makes it throw); that parse mismatch means the rule may silently load ALWAYS-ON, and is flagged as an error. **(2) cited-but-missing** — `(a)` `.claude/rules/<name>.md` citations inside `CLAUDE.md`/`AGENTS.md` that don't resolve to a file on disk, and `(b)` bare `<name>.md` tokens in a rule's own `## See Also` footer that don't exist as sibling rule files (tokens carrying a path separator, e.g. `../../skills/_shared/state-ownership.md`, are cross-directory references and explicitly out of scope); both flagged as errors. **(3) zero-match-globs** — a `globs:` pattern matching zero files in `git ls-files` (falls back to a manual directory walk when git is unavailable); flagged as a WARNING, not an error, because library/exemplar repos legitimately carry dead stack rules. **(4) foreign-glob** — a glob pattern containing a PascalCase product-like token (regex `[A-Z][a-z]+[A-Z]`, e.g. `WalkAITalkieTests`) — a likely copy-paste leftover from another project's rule scope; flagged as a WARNING. **(5) unreadable-file** — a rule file that could not be read (permissions, a race with a concurrent delete); flagged as a WARNING rather than silently skipped, so a completeness audit does not drop files, and so an unreadable file cannot brick the gate under `mode: hard`. **(6) fleet-intent-glob** — a `globs:` pattern DECLARED as fleet intent goes to `notes[]` (see below), never to `warnings[]`, and the declaration also settles probe 4 for that same pattern: a pattern the rule author declared is by construction not a copy-paste leftover. Glob matching reuses the same picomatch-with-inline-fallback resolution `scripts/lib/rule-loader.mjs` uses (`parseGlobsFrontmatter` is imported directly; the picomatch resolution itself is duplicated locally since `rule-loader.mjs` does not export a public matcher function). The check is skipped silently (no `checks_run` entry, no `checks_skipped` entry) when `.claude/rules/` is absent, or explicitly via `--skip-rule-scoping`.
69
69
 
70
70
  **Fleet-intent declaration (Check 9, probe 6).** A rule may declare that a `globs:` pattern is aimed at CONSUMER repos rather than this one, via its own frontmatter key `fleet-intent-globs:`. Accepted forms are block style (`fleet-intent-globs:` plus indented ` - "<pattern>"` lines), flow style (`fleet-intent-globs: ["a", "b"]`) and a single inline value; surrounding quotes are stripped, blank and `#` comment lines are ignored. The key is inert for rule loading — `rule-loader.mjs`'s `parseGlobsFrontmatter` skips unknown top-level keys and their continuation lines. A declared pattern is reported in `notes[]` with its file, the pattern, whether it matches `≥1` or `0` tracked files here, and the declaration `source` (`frontmatter`). The grain is per pattern AND per rule file: declaring one glob amnesties neither a sibling glob in the same rule nor the same pattern in another rule. There is deliberately NO checker-side exemption list: a rule that does not declare the pattern itself is not exempt, so the declaration always sits with the rule it describes.
71
71
 
@@ -38,6 +38,7 @@ import { _parseDriftCheck } from '../../scripts/lib/config/drift-check.mjs';
38
38
  import { isSessionConfigHeading } from '../../scripts/lib/config/section-extractor.mjs';
39
39
  import { parseGlobsFrontmatter } from '../../scripts/lib/rule-loader.mjs';
40
40
  import { resolveRepoSpec } from '../../scripts/lib/vcs-repo-spec.mjs';
41
+ import { userInvocableSkills } from '../../scripts/lib/user-invocable-skills.mjs';
41
42
 
42
43
  const FORWARD_HEADING_RE =
43
44
  /(?:^|\b)(what'?s?\s+next|backlog|open\s+issues?|offene\s+(?:issues?|themen)|todo|next\s+steps?|roadmap)(?:$|\b)/i;
@@ -412,6 +413,45 @@ function countTestFiles(vaultDir) {
412
413
  return n;
413
414
  }
414
415
 
416
+ /**
417
+ * The product's slash-command count: `commands/*.md` ∪ skills carrying an
418
+ * explicit `user-invocable: true`, deduplicated by name — the same union
419
+ * `scripts/site-numbers.mjs` and
420
+ * `tests/commands/headless-bare-command-availability.test.mjs` use. In a
421
+ * consumer repo without `skills/` (or without `commands/`) the union
422
+ * collapses to whichever side is present, so nothing changes there.
423
+ *
424
+ * ONE implementation shared by the `command-count` surface (Check 5) and the
425
+ * `docs-parity` sub-check (a) `commands` actual (Check 10) — the two counters
426
+ * drifted independently before this extraction (#1370 fold left the
427
+ * docs-parity side on a raw `commands/` `readdirSync`, undercounting after 24
428
+ * `commands/*.md` files were folded into skills).
429
+ *
430
+ * Returns `null` when NEITHER `commands/` NOR `skills/` exists — the caller's
431
+ * "artifact absent" skip path. A `skills/` directory that exists but contains
432
+ * zero `user-invocable: true` skills is a measured `0`, not a skip — matching
433
+ * `scripts/site-numbers.mjs` `countCommands`, whose gate is
434
+ * `isDir(commands) || isDir(skills)` (#1370 follow-up: the old gate skipped on
435
+ * `fromSkills.length === 0`, which conflated "no skills/ dir" with "skills/
436
+ * dir present, nothing user-invocable yet").
437
+ *
438
+ * @param {string} vaultDir
439
+ * @param {string|null} [commandsDir] `--commands-dir` override
440
+ * @returns {number|null}
441
+ */
442
+ function countSlashCommands(vaultDir, commandsDir) {
443
+ const dir = commandsDir || join(vaultDir, 'commands');
444
+ const dirExists = existsSync(dir) && statSync(dir).isDirectory();
445
+ const fromDir = dirExists
446
+ ? readdirSync(dir).filter((f) => f.endsWith('.md') && !f.startsWith('.')).map((f) => f.replace(/\.md$/, ''))
447
+ : [];
448
+ const fromSkills = userInvocableSkills(vaultDir);
449
+ const skillsDir = join(vaultDir, 'skills');
450
+ const skillsDirExists = existsSync(skillsDir) && statSync(skillsDir).isDirectory();
451
+ if (!dirExists && !skillsDirExists) return null;
452
+ return new Set([...fromDir, ...fromSkills]).size;
453
+ }
454
+
415
455
  /**
416
456
  * Build the surface-count descriptor table for the given vault. `hookCounts`
417
457
  * is computed once and shared by the two hook surfaces. Each descriptor's
@@ -427,14 +467,13 @@ function buildSurfaceDescriptors(vaultDir, commandsDir) {
427
467
  {
428
468
  id: 'command-count',
429
469
  noun: 'commands',
430
- actual: (() => {
431
- const dir = commandsDir || join(vaultDir, 'commands');
432
- if (!existsSync(dir) || !statSync(dir).isDirectory()) return null;
433
- return readdirSync(dir).filter((f) => f.endsWith('.md') && !f.startsWith('.')).length;
434
- })(),
470
+ // A slash command is a `commands/*.md` file OR a skill whose frontmatter
471
+ // says `user-invocable: true` see countSlashCommands() for the shared
472
+ // union derivation (also used by docs-parity sub-check (a) below).
473
+ actual: countSlashCommands(vaultDir, commandsDir),
435
474
  // "8 commands", "8 /commands", "8 slash commands"
436
475
  claimRe: /\b(\d+)\s+(?:\/)?commands?\b/gi,
437
- skipMsg: 'command-count: no commands/ directory found (use --commands-dir to override)',
476
+ skipMsg: 'command-count: no commands/ or skills/ directory found (use --commands-dir to override)',
438
477
  },
439
478
  {
440
479
  id: 'skill-count',
@@ -1485,11 +1524,10 @@ function main() {
1485
1524
  },
1486
1525
  {
1487
1526
  noun: 'commands',
1488
- actual: (() => {
1489
- const dir = commandsDir || join(vaultDir, 'commands');
1490
- if (!existsSync(dir) || !statSync(dir).isDirectory()) return null;
1491
- return readdirSync(dir).filter((f) => f.endsWith('.md') && !f.startsWith('.')).length;
1492
- })(),
1527
+ // Shared with the command-count surface (Check 5) see
1528
+ // countSlashCommands() doc-comment for why this must be ONE
1529
+ // implementation, not a second `commands/` readdirSync.
1530
+ actual: countSlashCommands(vaultDir, commandsDir),
1493
1531
  re: /^##\s+Commands\s+\((\d+)\)/i,
1494
1532
  },
1495
1533
  {
@@ -1,17 +1,23 @@
1
1
  ---
2
+ name: close
2
3
  description: End session with verification, commits, and documentation
4
+ user-invocable: true
3
5
  disable-model-invocation: true
6
+ model: inherit
4
7
  ---
5
-
6
8
  # Close Session
7
9
 
10
+ ## Invocation
11
+
12
+ The user invokes `/close` (arguments: **$ARGUMENTS** — none are interpreted; anything passed is context only) to end the current session. Run the STATE.md pre-check below, then hand off to `skills/session-end/SKILL.md`. Do NOT skip any verification step — evidence before assertions.
13
+
8
14
  The user wants to end the current session.
9
15
 
10
16
  **Pre-check before invoking session-end:** Determine `<state-dir>` from the current platform (`.claude/`, `.codex/`, `.cursor/`, or `.pi/`). Check if `<state-dir>/STATE.md` exists and read its `status` field. Three exit conditions:
11
17
 
12
18
  1. **STATE.md does not exist:** Read Session Config to check `persistence`. If `persistence: false`, inform the user: "Session completed (persistence is off — STATE.md was never created). Use `/session` to start a new session." If `persistence: true` (or Session Config unavailable), inform the user: "No active session found. Use `/session` to start a session first." Either way, stop.
13
- 2. **STATE.md exists and `status: completed`:** `status: completed` alone is NOT proof that session-end's Phase 3.7 writer ever ran (#429) — the field can be set by hand, or by any path that stops short of that write. Parse STATE.md with `parseStateMd` and parse `.orchestrator/metrics/sessions.jsonl` as JSONL. Import `findRecordedSession` from the plugin's `scripts/lib/session-close-backfill.mjs` and call it with the parsed records and `{ sessionId: frontmatter['session-id'], semanticSessionId: frontmatter.session, startedAt: frontmatter.started_at }`. This is the shared backfill identity reader: native UUIDs take precedence, conflicting native IDs never match through a label, and legacy semantic records remain readable. Do not substitute a text grep or compare the semantic label only against `session_id`. A missing ledger means no record; an unreadable or malformed ledger is inconclusive — report the read/parse failure and stop before repeating close side effects.
14
- - **A matching completed record exists (including a legacy authoritative record without a `status` field):** Inform the user: "Previous session was already finalized by session-end. Start a new session with `/session`, or inspect `<state-dir>/STATE.md` to review the prior close. (Note: if this is unexpected after an Express Path session, `commands/go.md` should have auto-invoked /close — check that STATE.md `## Deviations` contains an `Express path:` entry.)" and stop.
19
+ 2. **STATE.md exists and `status: completed`:** `status: completed` alone is NOT proof that session-end's Phase 3.7 writer ever ran (#429) — the field can be set by hand, or by any path that stops short of that write. Parse STATE.md with `parseStateMd` and parse `.orchestrator/metrics/sessions.jsonl` as JSONL. Import `findRecordedSession` from the plugin's `scripts/lib/session-close-backfill.mjs` and call it with the parsed records and `{ sessionId: frontmatter['session-id'] ?? readLock({ repoRoot })?.session_id ?? null, semanticSessionId: frontmatter.session, startedAt: frontmatter.started_at }` (`readLock` from `scripts/lib/session-lock.mjs`). The lock fallback is sound here and ONLY here: `/close` runs inside the very session whose STATE.md it is reading, so the live lock names that same session — it is never a peer's id. STATE.md files written before #1368 carry no `session-id` key at all, and without the fallback every one of them misses the native fast path. This is the shared backfill identity reader: native UUIDs take precedence, conflicting native IDs never match through a label, and legacy semantic records remain readable. Do not substitute a text grep or compare the semantic label only against `session_id`. A missing ledger means no record; an unreadable or malformed ledger is inconclusive — report the read/parse failure and stop before repeating close side effects.
20
+ - **A matching completed record exists (including a legacy authoritative record without a `status` field):** Inform the user: "Previous session was already finalized by session-end. Start a new session with `/session`, or inspect `<state-dir>/STATE.md` to review the prior close. (Note: if this is unexpected after an Express Path session, `skills/go/SKILL.md` should have auto-invoked /close — check that STATE.md `## Deviations` contains an `Express path:` entry.)" and stop.
15
21
  - **No matching completed record exists:** Warn the user: "STATE.md completed ohne passenden Abschluss im Ledger — session-end wird zur Vervollständigung ausgeführt (#429)." An abandoned backfill stub does not prove finalization. Do NOT stop — proceed to invoke the session-end skill exactly as in exit condition 3, so the missing completion gets written this time. (The SessionEnd hook's `backfillCompletedFromStateMd` independently self-heals this same gap on a later session's teardown; this Pre-Check branch covers the case where /close is re-run before that hook has had a chance to fire.)
16
22
  3. **STATE.md exists and `status: active` or `status: paused`:** Proceed to invoke the session-end skill.
17
23
 
@@ -19,7 +19,14 @@ Implemented from spec since upstream skill not yet published as of 2026-04-30.
19
19
 
20
20
  ## Invocation
21
21
 
22
- **Explicit:** `/convergence-monitoring` — standalone assessment from current session history.
22
+ `user-invocable: false` — there is no `/convergence-monitoring` slash command.
23
+
24
+ **Platform-native (primary, CC 2.1.105+):** registered as a plugin monitor
25
+ (`monitors/monitors.json`); auto-starts in the background on `wave-executor`
26
+ invocation and tails `.orchestrator/metrics/events.jsonl` for convergence signals.
27
+
28
+ **Direct/model invocation:** the model dispatches this skill by name for a
29
+ standalone assessment from current session history (fallback for harness < 2.1.105).
23
30
 
24
31
  **Embedded:** Set `convergence-monitoring: true` in Session Config. `wave-executor` and
25
32
  `/autoresearch` will call this skill automatically after each Impl-Core/Impl-Polish wave.
@@ -208,12 +208,56 @@ VEL_LINES_PRIOR=<read from events.jsonl for wave N-1>
208
208
 
209
209
  The `velocity_drop` NDJSON signal counts **one `orchestrator.agent.stopped`
210
210
  record per dispatched agent** (wave read from `wave` or `wave_number`) and fires
211
- when the later wave stopped fewer agents than the earlier one. Measured
212
- 2026-09-05 over `.orchestrator/metrics/events.jsonl`: 11,754
213
- `orchestrator.agent.stopped` records versus **0** for the `agent.dispatched` type
214
- the reader also accepts `agent.stopped` is the only per-agent record this repo
215
- actually emits with a wave number. The git-based `VEL_COMMITS` / `VEL_LINES`
216
- recipe above is the SKILL-level computation and is independent of the monitor.
211
+ when the later wave stopped fewer agents than the earlier one. `agent.stopped`
212
+ is the only per-agent record this repo actually emits with a wave number — but
213
+ the type is BIMODAL (#939/#949), so only records carrying a **non-empty `agent`
214
+ field** are counted; the rest are the phantom-stop class and counting them
215
+ inflated every per-wave count ~10.5x (#1379 P10).
216
+
217
+ Measured 2026-09-18 over `.orchestrator/metrics/events.jsonl` plus the legacy
218
+ `.jsonl.1` backup that then sat beside it — that backup was destroyed on
219
+ 2026-09-19, so the counts below are a record, not something this repo's ledger
220
+ still reproduces.
221
+
222
+ **Read the ledger through `readEventsWithRotations(repoRoot, opts)`**
223
+ (`scripts/lib/events.mjs`), never by `cat`-ing rotation files together. It
224
+ returns the active file plus every archive in time order, counts unreadable
225
+ lines (`malformed_lines`), and — the reason it exists — reports a rotation
226
+ whose archive is no longer on disk as an entry in `gaps` with `complete:
227
+ false`, instead of silently returning a shorter history. Rotation itself no
228
+ longer writes a `.1`..`.N` ring: since #1401 it renames the active file to
229
+ `_archive/events-<firstTs>_<lastTs>.jsonl` and makes an
230
+ `orchestrator.events.rotated` record naming that archive the first line of the
231
+ new active file (`scripts/lib/events-rotation.mjs:230-258`); the reader still
232
+ reads a legacy ring left on disk by older versions
233
+ (`scripts/lib/events.mjs:512-539`).
234
+
235
+ ```bash
236
+ node --input-type=module -e '
237
+ import { readEventsWithRotations } from "./scripts/lib/events.mjs";
238
+ const r = readEventsWithRotations(process.cwd());
239
+ console.error(JSON.stringify({ gaps: r.gaps, malformed_lines: r.malformed_lines, complete: r.complete }));
240
+ for (const e of r.events) process.stdout.write(JSON.stringify(e) + "\n");
241
+ ' | jq -s '{
242
+ total_stopped: [.[]|select(.event=="orchestrator.agent.stopped")]|length,
243
+ with_wave: [.[]|select(.event=="orchestrator.agent.stopped" and ((.wave//.wave_number)!=null))]|length,
244
+ with_wave_no_agent: [.[]|select(.event=="orchestrator.agent.stopped" and ((.wave//.wave_number)!=null) and ((.agent//"")==""))]|length,
245
+ with_wave_and_agent:[.[]|select(.event=="orchestrator.agent.stopped" and ((.wave//.wave_number)!=null) and ((.agent//"")!=""))]|length }'
246
+ # 2026-09-18 (active + `.jsonl.1`):
247
+ # → { total_stopped: 16438, with_wave: 6553, with_wave_no_agent: 5930, with_wave_and_agent: 623 }
248
+ ```
249
+
250
+ i.e. 5930 of 6553 wave-scoped stops (90.5%) are phantoms, against **0** records
251
+ of the `agent.dispatched` type the reader also accepts. The git-based
252
+ `VEL_COMMITS` / `VEL_LINES` recipe above is the SKILL-level computation and is
253
+ independent of the monitor.
254
+
255
+ The `console.error` line is the honesty half of the reading and belongs in every
256
+ re-measurement: a count taken from a ledger whose `gaps` is non-empty is a count
257
+ over an unknown fraction of the history. Its blind spot is bounded and named —
258
+ an archive deleted BEFORE #1401 left no tombstone and is undetectable by
259
+ construction (`scripts/lib/events.mjs:556-561`), which is exactly how the
260
+ 53,896-line `.jsonl.1` vanished on 2026-09-19 without any analysis noticing.
217
261
 
218
262
  ### Thresholds
219
263
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: convergence-monitoring
3
- user-invocable: true
3
+ user-invocable: false
4
4
  tags: [autoresearch, convergence, loop-control, wave-executor]
5
5
  model: haiku
6
6
  model-preference: sonnet
@@ -32,9 +32,17 @@ For harness < 2.1.105 (no monitor support), the skill's manual probes documented
32
32
 
33
33
  ## When to Invoke
34
34
 
35
- **Explicit invocation (`/convergence-monitoring`):** Standalone assessment reads wave
36
- history from `.orchestrator/metrics/events.jsonl`, computes all three signals, reports
37
- verdict + recovery options.
35
+ This skill is `user-invocable: false` there is no `/convergence-monitoring` slash
36
+ command. It is reached two ways:
37
+
38
+ **Platform-native monitor (primary path, CC 2.1.105+):** the background watcher below
39
+ auto-starts on `wave-executor` invocation and streams verdicts as it tails
40
+ `events.jsonl` — no explicit call needed.
41
+
42
+ **Direct/model invocation (fallback, harness < 2.1.105, or a standalone assessment):**
43
+ the model dispatches this skill by name — reads wave history from
44
+ `.orchestrator/metrics/events.jsonl`, computes all three signals, reports verdict +
45
+ recovery options.
38
46
 
39
47
  **Embedded (loop context):** `/autoresearch` and `wave-executor` invoke this skill after
40
48
  each Impl-Core or Impl-Polish wave when `convergence-monitoring: true` is set in Session
@@ -48,9 +56,10 @@ toward done or oscillating/stalling.
48
56
 
49
57
  ## Phase 0: Activation Gate
50
58
 
51
- ### 0.1 Explicit Invocation
59
+ ### 0.1 Direct Invocation
52
60
 
53
- If invoked via `/convergence-monitoring`, skip to Phase 1 unconditionally.
61
+ If invoked directly (not embedded from `wave-executor` or `/autoresearch`), skip to
62
+ Phase 1 unconditionally.
54
63
 
55
64
  ### 0.2 Embedded Invocation
56
65
 
@@ -6,6 +6,8 @@ description: >
6
6
  INVESTIGATION FIRST. Produces a `.orchestrator/debug/` artifact the fixer agent must reference.
7
7
  model: inherit
8
8
  color: red
9
+ user-invocable: true
10
+ argument-hint: "[bug-description-or-issue-ref]"
9
11
  tools: Read, Grep, Glob, Bash, Write
10
12
  ---
11
13
 
@@ -13,6 +15,14 @@ tools: Read, Grep, Glob, Bash, Write
13
15
 
14
16
  > 4-phase root-cause investigation. Iron Law: no fix without root cause.
15
17
 
18
+ ## Invocation
19
+
20
+ The user invokes `/debug` with arguments: **$ARGUMENTS**.
21
+
22
+ The optional argument is a short bug description or issue reference (e.g. `"test timeout in CI"` or `#408`). If absent, inspect recent errors and `git log` to surface the most likely candidate, then confirm it with the user before starting Phase 1.
23
+
24
+ The four phases (Root Cause → Pattern → Impact → Solution) run in order, and the Phase-1 artifact at `.orchestrator/debug/<session-id>-<sequence>.md` is written before any fix code exists — it is a prerequisite for Phase 4, not optional documentation.
25
+
16
26
  ## When to use
17
27
 
18
28
  - Any test failure (unit, integration, E2E)
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  name: discovery
3
- user-invocable: false
3
+ user-invocable: true
4
+ argument-hint: "[all|code|infra|ui|arch|session|audit|vault|feature] [--since <git-ref>] [--full]"
4
5
  tags: [quality, discovery, probes, issues]
5
6
  model: sonnet
6
7
  model-preference: sonnet
@@ -15,6 +16,28 @@ description: >
15
16
 
16
17
  # Discovery Skill
17
18
 
19
+ ## Invocation
20
+
21
+ The user invokes `/discovery` with scope: **$ARGUMENTS** (if empty, default to `all`).
22
+
23
+ Parse `$ARGUMENTS` before doing anything else. Extract the following flags and tokens in any order:
24
+
25
+ - `--since <git-ref>` — restrict discovery to files changed since the given git ref (e.g. `HEAD~5`, `main`, a commit hash). Sets `since_ref = <git-ref>`, which is passed into Phase 3 plumbing.
26
+ - `--full` — explicit full-repo scan. Sets `full_scan = true`.
27
+ - Any remaining tokens are treated as scope specifiers (see the scope enum in § Invocation Modes).
28
+
29
+ **Conflict check:** If BOTH `--since` and `--full` are present, stop immediately and report:
30
+
31
+ ```
32
+ Error: Cannot use --since with --full. Provide one, not both.
33
+ ```
34
+
35
+ Do NOT proceed with discovery when this conflict is present.
36
+
37
+ **Argument validation:** Valid scopes: `all`, `code`, `infra`, `ui`, `arch`, `session`, `audit`, `vault`, `feature` (comma-separated for multiple). If any scope is invalid, inform the user: "Invalid scope '[token]'. Valid scopes: all, code, infra, ui, arch, session, audit, vault, feature." and default that token to `all`.
38
+
39
+ Scan the codebase for quality issues, technical debt, and improvement opportunities within the requested scope. Do NOT skip the interactive triage phase — every finding must be confirmed by the user before issue creation. Evidence before assertions.
40
+
18
41
  ## Invocation Modes
19
42
 
20
43
  Two modes of operation:
@@ -506,11 +506,11 @@ Violations:
506
506
  - tools (no-json-array): tools must be a comma-separated string, not a JSON array
507
507
  - description (no-block-scalar): description must be inline, not a block scalar
508
508
  - color (enum): color must be one of "blue"|"cyan"|"green"|"yellow"|"magenta"|"red"
509
- Recommendation: Run /bootstrap --retroactive to auto-surface violations, or manually fix per CLAUDE.md Agent Authoring Rules.
509
+ Recommendation: Run node scripts/validate-plugin.mjs to surface every violation, or manually fix per CLAUDE.md Agent Authoring Rules.
510
510
  ```
511
511
 
512
512
  **Default Severity:** High — broken agents fail at runtime silently.
513
513
 
514
- **Remediation:** Run `/bootstrap --retroactive` (validator auto-surfaces violations) or manually fix per CLAUDE.md Agent Authoring Rules.
514
+ **Remediation:** Run `node scripts/validate-plugin.mjs` (the agent-frontmatter validator lists every violation; `/bootstrap --retroactive` only writes a missing lock, it does not validate) or manually fix per CLAUDE.md Agent Authoring Rules.
515
515
 
516
516
  **Dependencies:** Requires `${PLUGIN_ROOT}/scripts/lib/agent-frontmatter.mjs` (issue #189). Degrades gracefully when the helper is absent — skip with a note, do not fabricate findings.