session-orchestrator 5.12.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 (385) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  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 +162 -4
  11. package/README.md +126 -127
  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 +1 -1
  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 +90 -17
  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 +49 -15
  47. package/docs/session-config-template.md +30 -22
  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 +139 -49
  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 -2
  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 +39 -27
  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/section-extractor.mjs +65 -11
  143. package/scripts/lib/config/template-keys.mjs +153 -0
  144. package/scripts/lib/config/vault-integration.mjs +1 -0
  145. package/scripts/lib/config.mjs +2 -2
  146. package/scripts/lib/coordinator-snapshot.mjs +1 -1
  147. package/scripts/lib/discovery/triage-state.mjs +2 -1
  148. package/scripts/lib/dispatcher/rank.mjs +5 -7
  149. package/scripts/lib/ecosystem-health.mjs +2 -2
  150. package/scripts/lib/eval/engine.mjs +3 -2
  151. package/scripts/lib/eval/session-resolve.mjs +6 -2
  152. package/scripts/lib/eval/sink.mjs +4 -3
  153. package/scripts/lib/events-retention-banner.mjs +3 -2
  154. package/scripts/lib/events-schema.mjs +10 -0
  155. package/scripts/lib/events.mjs +23 -12
  156. package/scripts/lib/evolve/autonomy-verdict.mjs +4 -9
  157. package/scripts/lib/evolve/autopilot-effectiveness.mjs +8 -18
  158. package/scripts/lib/fleet-protocol.mjs +4 -0
  159. package/scripts/lib/gates/gate-full.mjs +172 -11
  160. package/scripts/lib/gates/gate-helpers.mjs +236 -23
  161. package/scripts/lib/git-config-drift.mjs +141 -7
  162. package/scripts/lib/github-export.mjs +447 -0
  163. package/scripts/lib/gitlab-portfolio/cli.mjs +16 -5
  164. package/scripts/lib/handover-queue-marks.mjs +159 -0
  165. package/scripts/lib/hardware-pattern-detector.mjs +103 -13
  166. package/scripts/lib/harness-audit/categories/category1.mjs +16 -4
  167. package/scripts/lib/harness-audit/categories/category4.mjs +11 -8
  168. package/scripts/lib/harness-audit/categories/category6.mjs +25 -5
  169. package/scripts/lib/harness-audit/categories/category9.mjs +10 -4
  170. package/scripts/lib/host-identity.mjs +9 -5
  171. package/scripts/lib/http-request.mjs +64 -0
  172. package/scripts/lib/instruction-budget-guard.mjs +30 -22
  173. package/scripts/lib/io.mjs +6 -3
  174. package/scripts/lib/issue-budget-reconcile.mjs +3 -2
  175. package/scripts/lib/issue-budget.mjs +36 -7
  176. package/scripts/lib/learnings/evidence-candidates.mjs +154 -0
  177. package/scripts/lib/learnings/expiry-sweep.mjs +99 -7
  178. package/scripts/lib/learnings/io.mjs +289 -15
  179. package/scripts/lib/learnings/select.mjs +53 -4
  180. package/scripts/lib/learnings/store-role.mjs +209 -0
  181. package/scripts/lib/learnings/surface.mjs +46 -7
  182. package/scripts/lib/ledger-path.mjs +113 -0
  183. package/scripts/lib/maintenance-due-banner.mjs +63 -12
  184. package/scripts/lib/memory-banner.mjs +5 -6
  185. package/scripts/lib/memory-proposals/collector.mjs +5 -2
  186. package/scripts/lib/memory-proposals/sink.mjs +7 -4
  187. package/scripts/lib/memory-proposals/store.mjs +22 -5
  188. package/scripts/lib/mode-selector-accuracy.mjs +2 -1
  189. package/scripts/lib/no-follow-open.mjs +57 -0
  190. package/scripts/lib/orphan-reaper/reaper-audit.mjs +4 -2
  191. package/scripts/lib/own-lock-root.mjs +95 -0
  192. package/scripts/lib/owner-interview.mjs +2 -1
  193. package/scripts/lib/owner-yaml.mjs +70 -7
  194. package/scripts/lib/platform.mjs +161 -9
  195. package/scripts/lib/plugin-update-banner.mjs +15 -11
  196. package/scripts/lib/pre-push-local-partial.mjs +117 -0
  197. package/scripts/lib/pre-push-remote-gate.mjs +151 -25
  198. package/scripts/lib/process-group.mjs +270 -34
  199. package/scripts/lib/project-hygiene.mjs +28 -0
  200. package/scripts/lib/quality-gate.mjs +33 -9
  201. package/scripts/lib/reconcile/backlog.mjs +29 -15
  202. package/scripts/lib/reconcile/engine.mjs +26 -2
  203. package/scripts/lib/reconcile/idempotency.mjs +65 -3
  204. package/scripts/lib/reconcile/rule-expiry-sweep.mjs +53 -12
  205. package/scripts/lib/reconcile/verdict-ledger.mjs +224 -0
  206. package/scripts/lib/reconcile-nudge-banner.mjs +40 -6
  207. package/scripts/lib/resource-probe/evaluate.mjs +32 -9
  208. package/scripts/lib/resource-probe/probe-platform.mjs +3 -1
  209. package/scripts/lib/rule-loader.mjs +20 -10
  210. package/scripts/lib/scope-baseline.mjs +123 -8
  211. package/scripts/lib/scope-echo.mjs +5 -2
  212. package/scripts/lib/scope-gate.mjs +55 -20
  213. package/scripts/lib/session-close-backfill.mjs +75 -7
  214. package/scripts/lib/session-end/close-precheck.mjs +151 -0
  215. package/scripts/lib/session-end/phase-skip.mjs +8 -7
  216. package/scripts/lib/session-end/tail-runner.mjs +7 -2
  217. package/scripts/lib/session-id.mjs +9 -1
  218. package/scripts/lib/session-identity/own-session.mjs +63 -0
  219. package/scripts/lib/session-lock.mjs +114 -0
  220. package/scripts/lib/session-record-repair.mjs +245 -35
  221. package/scripts/lib/session-registry.mjs +72 -9
  222. package/scripts/lib/session-schema/constants.mjs +9 -0
  223. package/scripts/lib/session-schema/filters.mjs +56 -1
  224. package/scripts/lib/session-schema/validator.mjs +15 -5
  225. package/scripts/lib/session-start-probes.mjs +149 -22
  226. package/scripts/lib/session-token-rollup.mjs +2 -1
  227. package/scripts/lib/session-work-trees.mjs +166 -0
  228. package/scripts/lib/sessions-canonical.mjs +61 -3
  229. package/scripts/lib/sessions-integrity-banner.mjs +17 -39
  230. package/scripts/lib/sessions-staleness-banner.mjs +8 -5
  231. package/scripts/lib/sh-quote.mjs +1 -0
  232. package/scripts/lib/skill-evidence-window.mjs +5 -1
  233. package/scripts/lib/skill-health/join.mjs +10 -9
  234. package/scripts/lib/skill-invocations-schema.mjs +13 -0
  235. package/scripts/lib/skill-judgments-schema.mjs +6 -2
  236. package/scripts/lib/snapshot-probe.mjs +414 -0
  237. package/scripts/lib/so-hud/collect.mjs +49 -5
  238. package/scripts/lib/so-hud/runtime.mjs +15 -4
  239. package/scripts/lib/spiral-carryover.mjs +8 -1
  240. package/scripts/lib/state-md/frontmatter-mutators.mjs +266 -8
  241. package/scripts/lib/state-md/idle-reset.mjs +14 -5
  242. package/scripts/lib/state-md/mission-status.mjs +5 -1
  243. package/scripts/lib/state-md-peer-guard.mjs +2 -0
  244. package/scripts/lib/state-md.mjs +31 -8
  245. package/scripts/lib/sunset/walker.mjs +4 -3
  246. package/scripts/lib/telemetry/consent.mjs +4 -2
  247. package/scripts/lib/telemetry/queue.mjs +3 -3
  248. package/scripts/lib/telemetry/sync.mjs +45 -9
  249. package/scripts/lib/test-runner/artifact-paths.mjs +10 -2
  250. package/scripts/lib/tmux-layout/layouts.mjs +20 -3
  251. package/scripts/lib/ux-grill/paths.mjs +5 -1
  252. package/scripts/lib/validate/check-agents.mjs +37 -6
  253. package/scripts/lib/validate/check-component-paths.mjs +25 -1
  254. package/scripts/lib/validate/check-guard-requires-parity.mjs +3 -3
  255. package/scripts/lib/validate/check-hooks-symmetry.mjs +53 -32
  256. package/scripts/lib/validate/check-json-files.mjs +3 -1
  257. package/scripts/lib/validate/check-learning-provenance.mjs +3 -2
  258. package/scripts/lib/validate/check-learnings-shell-writes.mjs +10 -4
  259. package/scripts/lib/validate/check-metrics-ledger-root.mjs +234 -0
  260. package/scripts/lib/validate/check-owner-leakage.mjs +159 -11
  261. package/scripts/lib/validate/check-test-posix-shell.mjs +246 -0
  262. package/scripts/lib/validate/check-unwired-features.mjs +4 -2
  263. package/scripts/lib/validate/check-vcs-repo-flag-positional.mjs +58 -0
  264. package/scripts/lib/validate/check-vcs-repo-flag.mjs +259 -73
  265. package/scripts/lib/validate/check-workflow-continue-on-error.mjs +63 -0
  266. package/scripts/lib/validate/confidential-names.mjs +3 -1
  267. package/scripts/lib/vault-mirror/migrate-ids.mjs +321 -0
  268. package/scripts/lib/vault-mirror/namespace.mjs +19 -7
  269. package/scripts/lib/vault-mirror/process.mjs +56 -27
  270. package/scripts/lib/vault-mirror/prune.mjs +5 -2
  271. package/scripts/lib/vault-mirror/render-learnings.mjs +3 -3
  272. package/scripts/lib/vault-mirror/render-sessions.mjs +36 -53
  273. package/scripts/lib/vault-mirror/retention.mjs +2 -2
  274. package/scripts/lib/vault-mirror/utils.mjs +79 -0
  275. package/scripts/lib/vault-staleness-banner.mjs +4 -7
  276. package/scripts/lib/vault-status/board-writer.mjs +2 -1
  277. package/scripts/lib/vault-status/narrative-mirror.mjs +66 -7
  278. package/scripts/lib/wave-executor/foreign-dispatch.mjs +20 -0
  279. package/scripts/lib/win-process-tree.mjs +137 -0
  280. package/scripts/lib/workspace.mjs +1 -1
  281. package/scripts/lib/worktree/constants.mjs +1 -1
  282. package/scripts/lib/worktree/lifecycle.mjs +1 -1
  283. package/scripts/lib/worktree/listing.mjs +1 -1
  284. package/scripts/lib/zx.mjs +50 -0
  285. package/scripts/mcp-server.mjs +16 -7
  286. package/scripts/mcp-server.sh +13 -83
  287. package/scripts/measure-policy-cache-effectiveness.mjs +7 -5
  288. package/scripts/memory-propose.mjs +10 -3
  289. package/scripts/migrate-cold-start-seed.mjs +7 -0
  290. package/scripts/migrate-legacy-learnings.sh +22 -0
  291. package/scripts/migrate-sessions-jsonl.mjs +16 -2
  292. package/scripts/migrate-vault-paths.mjs +29 -13
  293. package/scripts/parse-config.mjs +71 -14
  294. package/scripts/print-learnings-index.mjs +25 -2
  295. package/scripts/release-session-lock.mjs +94 -7
  296. package/scripts/release.mjs +451 -24
  297. package/scripts/relocate-vault-corpus.mjs +11 -7
  298. package/scripts/repair-invalid-sessions.mjs +68 -3
  299. package/scripts/resolve-session-invocation.mjs +10 -17
  300. package/scripts/run-migrate-v2-cross-repo.mjs +56 -1
  301. package/scripts/run-quality-gate.mjs +33 -7
  302. package/scripts/self-update.mjs +56 -7
  303. package/scripts/session-commit-files.mjs +133 -0
  304. package/scripts/site-numbers.mjs +52 -9
  305. package/scripts/snapshot-probe.mjs +156 -0
  306. package/scripts/so-hud.mjs +29 -6
  307. package/scripts/state-md-idle-reset.mjs +2 -1
  308. package/scripts/sweep-expired-learnings.mjs +54 -6
  309. package/scripts/sweep-expired-rules.mjs +4 -1
  310. package/scripts/validate-plugin.mjs +22 -0
  311. package/scripts/vault-integration-watcher.mjs +54 -6
  312. package/scripts/vault-mirror.mjs +9 -0
  313. package/skills/_shared/fleet-protocol.md +142 -1
  314. package/skills/_shared/instruction-file-resolution.md +1 -1
  315. package/skills/_shared/monitor-patterns.md +44 -25
  316. package/skills/_shared/platform-tools.md +7 -0
  317. package/skills/_shared/state-ownership.md +3 -2
  318. package/skills/architecture/references/domain-model.md +1 -1
  319. package/skills/bootstrap/SKILL.md +3 -1
  320. package/skills/bootstrap/_shared-template.md +4 -4
  321. package/skills/bootstrap/fast-template.md +1 -1
  322. package/skills/bootstrap/private-contract.md +1 -1
  323. package/skills/bootstrap/references/bootstrap-retroactive-flow.md +17 -9
  324. package/skills/bootstrap/templates/agents/project-code-review.md +5 -1
  325. package/skills/bootstrap/templates/agents/project-discovery.md +5 -1
  326. package/skills/bootstrap/templates/agents/project-quality-gate.md +5 -1
  327. package/skills/claude-md-drift-check/SKILL.md +3 -3
  328. package/skills/claude-md-drift-check/checker.mjs +61 -101
  329. package/skills/close/SKILL.md +20 -7
  330. package/skills/discovery/probes/docs-staleness.mjs +7 -5
  331. package/skills/discovery/probes/frontend-slop.mjs +7 -3
  332. package/skills/discovery/probes/ssot-code-diff.mjs +5 -3
  333. package/skills/discovery/probes/supply-chain-slopcheck.mjs +10 -8
  334. package/skills/discovery/probes/vault-narrative-staleness.mjs +30 -10
  335. package/skills/discovery/probes/vault-staleness.mjs +5 -3
  336. package/skills/discovery/probes-session.md +3 -0
  337. package/skills/discovery/probes-vault.md +2 -0
  338. package/skills/dispatcher/SKILL.md +1 -1
  339. package/skills/eval/SKILL.md +3 -1
  340. package/skills/evolve/SKILL.md +2 -0
  341. package/skills/evolve/references/evolve-analyze-mode.md +3 -3
  342. package/skills/evolve/references/evolve-dialectic-mode.md +1 -1
  343. package/skills/gitlab-ops/SKILL.md +7 -6
  344. package/skills/gitlab-portfolio/SKILL.md +2 -2
  345. package/skills/go/SKILL.md +13 -1
  346. package/skills/npm-publish/SKILL.md +5 -2
  347. package/skills/plan/SKILL.md +23 -10
  348. package/skills/plan/mode-feature.md +13 -8
  349. package/skills/plan/mode-new.md +6 -14
  350. package/skills/plan/prd-feature-template.md +19 -0
  351. package/skills/plan/prd-full-template.md +12 -5
  352. package/skills/plan/prd-premortem-panel.md +48 -0
  353. package/skills/plan/prd-reviewer-prompt.md +11 -3
  354. package/skills/plan/soul.md +1 -1
  355. package/skills/portfolio/SKILL.md +5 -6
  356. package/skills/quality-gates/SKILL.md +2 -4
  357. package/skills/reconcile/SKILL.md +27 -4
  358. package/skills/release/SKILL.md +16 -8
  359. package/skills/session-end/SKILL.md +94 -11
  360. package/skills/session-end/phase-3-2-docs-verification.md +1 -0
  361. package/skills/session-end/phase-3-6-tail.md +11 -7
  362. package/skills/session-end/phase-3-7a-recommendations.md +9 -2
  363. package/skills/session-end/plan-verification.md +16 -1
  364. package/skills/session-end/references/phase-3-documentation-updates.md +14 -12
  365. package/skills/session-end/references/phase-5-issue-cleanup.md +1 -1
  366. package/skills/session-end/references/session-summary-template.md +4 -0
  367. package/skills/session-end/session-metrics-write.md +7 -4
  368. package/skills/session-plan/SKILL.md +5 -3
  369. package/skills/session-start/SKILL.md +9 -3
  370. package/skills/session-start/phase-4-5-resource-health.md +11 -5
  371. package/skills/session-start/phase-8-5-express-path.md +4 -3
  372. package/skills/session-start/references/phase-1-2-session-lock.md +7 -5
  373. package/skills/session-start/references/phase-1-5-session-continuity.md +2 -2
  374. package/skills/session-start/references/phase-1-7-vault-status-board.md +1 -1
  375. package/skills/session-start/references/phase-4-ssot-environment-check.md +3 -2
  376. package/skills/tmux-layout/SKILL.md +2 -2
  377. package/skills/vault-sync/validator.mjs +3 -2
  378. package/skills/wave-executor/SKILL.md +5 -4
  379. package/skills/wave-executor/references/wave-executor-state-init.md +3 -3
  380. package/skills/wave-executor/references/wave-loop-dispatch.md +11 -5
  381. package/skills/wave-executor/references/wave-loop-review.md +13 -5
  382. package/skills/wave-executor/references/wave-loop-scope-manifest.md +1 -1
  383. package/assets/og-card.png +0 -0
  384. package/assets/og-card.svg +0 -47
  385. package/assets/wave-lifecycle.svg +0 -98
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * check-test-posix-shell.mjs — tests must not spawn a POSIX shell by bare name.
4
+ *
5
+ * WHY. On native Windows `sh` is not on PATH and `bash` resolves to
6
+ * C:\Windows\System32\bash.exe, which is WSL and cannot see Windows paths
7
+ * (measured 2026-10-22 on the Windows 11 test PC, `where sh & where bash`,
8
+ * SO#1613). A test that runs `spawnSync('sh', …)` or `execFileSync('/bin/bash', …)`
9
+ * is therefore red on Windows for a reason that has nothing to do with the code
10
+ * under test. The native run at fd8d3673 counted 301 red tests in exactly this
11
+ * class; the same session moved ~25 test files to `posixShell()` from
12
+ * `tests/_helpers/posix-shell.mjs`, which returns the name unchanged off Windows
13
+ * and Git Bash's sh.exe/bash.exe on win32. This check keeps the class from
14
+ * coming back.
15
+ *
16
+ * RULE. In tracked `tests/**\/*.mjs`, a finding is:
17
+ * - a call to `spawn` / `spawnSync` / `execFile` / `execFileSync` (bare or as a
18
+ * member, e.g. `cp.spawnSync`) whose FIRST argument is the string literal
19
+ * `sh`, `bash`, `/bin/sh` or `/bin/bash` in any quote style;
20
+ * - a call to `exec` / `execSync` whose command string literal starts with
21
+ * `sh `, `bash `, `/bin/sh ` or `/bin/bash `.
22
+ * A call through `posixShell(...)` is never a finding (its first argument is not
23
+ * a literal). `tests/_helpers/posix-shell.mjs` itself is exempt.
24
+ *
25
+ * METHOD. Textual, over the shared lexer `scripts/lib/js-mask.mjs`: the call
26
+ * name and its opening quote are matched on the fully masked source (comments
27
+ * and literal interiors blanked), so a commented-out spawn and fixture source
28
+ * embedded in a template literal are not scanned as code; the literal VALUE is
29
+ * then read at the same offset from the comments-only mask (offsets are
30
+ * preserved by both modes).
31
+ * Named ceiling (BV-004): a shell name passed through a variable
32
+ * (`const SH = 'sh'; spawnSync(SH, …)`) is not seen. REVISIT if a native
33
+ * Windows run shows that shape red.
34
+ *
35
+ * BASELINE. Three files are changed by open merge requests (!239/!237, !240) at the
36
+ * time this check landed, so the #1613 session left them untouched; each is
37
+ * baselined below (WARN, not FAIL) and gets converted after those MRs land. An
38
+ * entry whose file no longer has a finding FAILs as `baseline-stale` so a
39
+ * converted file does not leave a permanent exemption behind; an entry with an
40
+ * empty reason FAILs as `baseline-missing-reason` (same discipline as
41
+ * `check-hooks-emit-event-guard.mjs`). Every other site FAILs.
42
+ *
43
+ * Usage: check-test-posix-shell.mjs <repo-root>
44
+ * Output: ` PASS: …` / ` WARN: …` / ` FAIL: …` lines, then
45
+ * `Results: N passed, M failed`. Exit 0 = clean (baselined WARNs allowed),
46
+ * 1 = at least one new finding or baseline defect, 2 = tool error.
47
+ *
48
+ * Import-safety: importing this module executes nothing — the isMain guard at
49
+ * the bottom is the only side-effecting path.
50
+ */
51
+
52
+ import { readFileSync } from 'node:fs';
53
+ import path from 'node:path';
54
+ import { maskSource } from '../js-mask.mjs';
55
+ import { listRepoFiles } from './repo-files.mjs';
56
+ import { isMainModule } from '../is-main-module.mjs';
57
+
58
+ const SCAN_DIR = 'tests';
59
+
60
+ /** The helper that resolves the shell; it may name the shells itself. */
61
+ const EXEMPT_FILES = new Set(['tests/_helpers/posix-shell.mjs']);
62
+
63
+ /**
64
+ * Baseline — Map<repo-relative file, reason>. Keyed per file, not per line:
65
+ * the open MRs reshape these files, and a line key would silently stop matching.
66
+ */
67
+ const BASELINE_FILES = new Map([
68
+ [
69
+ 'tests/skills/tmux-layout.test.mjs',
70
+ '#1613: file is changed by an open MR (!240); convert to posixShell() after it lands',
71
+ ],
72
+ [
73
+ 'tests/so-hud/rules.test.mjs',
74
+ '#1613: file is changed by an open MR (!239/!237); convert to posixShell() after it lands',
75
+ ],
76
+ [
77
+ 'tests/scripts/sweep-expired-learnings-cli.test.mjs',
78
+ '#1613: file is changed by an open MR (!239/!237); convert to posixShell() after it lands',
79
+ ],
80
+ ]);
81
+
82
+ const SHELL_NAMES = new Set(['sh', 'bash', '/bin/sh', '/bin/bash']);
83
+ const SHELL_COMMAND_PREFIX_RE = /^(?:\/bin\/)?(?:sh|bash) /;
84
+
85
+ /** Call name plus open paren plus a quote, on the masked source. */
86
+ const CALL_RE = /\b(spawn|spawnSync|execFile|execFileSync|exec|execSync)\s*\(\s*(['"`])/g;
87
+
88
+ /**
89
+ * Read the string literal that opens at `start` (a quote char) in `text`.
90
+ *
91
+ * @param {string} text comments-only masked source
92
+ * @param {number} start offset of the opening quote
93
+ * @returns {string | null} the literal's value, or null when it is not a
94
+ * single-line literal without `${` interpolation
95
+ */
96
+ function literalAt(text, start) {
97
+ const quote = text[start];
98
+ const end = text.indexOf(quote, start + 1);
99
+ if (end === -1) return null;
100
+ const value = text.slice(start + 1, end);
101
+ if (value.includes('\n') || value.includes('${')) return null;
102
+ return value;
103
+ }
104
+
105
+ /**
106
+ * Find bare-shell spawn call sites in one source text.
107
+ *
108
+ * @param {string} source
109
+ * @returns {{line: number, call: string, shell: string}[]}
110
+ */
111
+ export function findBareShellCalls(source) {
112
+ const masked = maskSource(source);
113
+ const literals = maskSource(source, { keepLiterals: true });
114
+ /** @type {{line: number, call: string, shell: string}[]} */
115
+ const calls = [];
116
+ for (const m of masked.matchAll(CALL_RE)) {
117
+ const call = m[1];
118
+ const quoteAt = m.index + m[0].length - 1;
119
+ const value = literalAt(literals, quoteAt);
120
+ if (value === null) continue;
121
+ const isExecFamily = call === 'exec' || call === 'execSync';
122
+ const hit = isExecFamily ? SHELL_COMMAND_PREFIX_RE.test(value) : SHELL_NAMES.has(value);
123
+ if (!hit) continue;
124
+ const line = source.slice(0, m.index).split('\n').length;
125
+ calls.push({ line, call, shell: isExecFamily ? value.split(' ')[0] : value });
126
+ }
127
+ return calls;
128
+ }
129
+
130
+ /**
131
+ * @typedef {{kind: 'bare-shell', file: string, line: number, call: string, shell: string, baselined: boolean}} ShellFinding
132
+ * @typedef {{kind: 'baseline-stale' | 'baseline-missing-reason', file: string, message: string}} BaselineFinding
133
+ */
134
+
135
+ /**
136
+ * Scan tracked `tests/**\/*.mjs` under `repoRoot`.
137
+ *
138
+ * @param {string} repoRoot
139
+ * @param {{baseline?: Map<string, string>}} [options] `baseline` defaults to the
140
+ * shipped {@link BASELINE_FILES}; injectable so tests exercise the baseline
141
+ * paths against a tmp fixture.
142
+ * @returns {{findings: (ShellFinding | BaselineFinding)[], readErrors: {file: string, message: string}[]}}
143
+ */
144
+ export function scanTestPosixShell(repoRoot, { baseline = BASELINE_FILES } = {}) {
145
+ const files = listRepoFiles(repoRoot, { dirs: [SCAN_DIR], exts: ['mjs'] });
146
+ /** @type {(ShellFinding | BaselineFinding)[]} */
147
+ const findings = [];
148
+ /** @type {{file: string, message: string}[]} */
149
+ const readErrors = [];
150
+ /** @type {Set<string>} */
151
+ const matchedBaseline = new Set();
152
+
153
+ for (const absFile of files) {
154
+ const rel = path.relative(repoRoot, absFile).split(path.sep).join('/');
155
+ if (EXEMPT_FILES.has(rel)) continue;
156
+ let source;
157
+ try {
158
+ source = readFileSync(absFile, 'utf8');
159
+ } catch (err) {
160
+ readErrors.push({ file: rel, message: `unreadable: ${err?.message ?? String(err)}` });
161
+ continue;
162
+ }
163
+ if (!/\b(?:spawn|exec)/.test(source)) continue; // cheap textual pre-filter
164
+
165
+ const calls = findBareShellCalls(source);
166
+ if (calls.length === 0) continue;
167
+ const baselined = baseline.has(rel);
168
+ if (baselined) {
169
+ matchedBaseline.add(rel);
170
+ if (String(baseline.get(rel) ?? '').trim() === '') {
171
+ findings.push({
172
+ kind: 'baseline-missing-reason',
173
+ file: rel,
174
+ message: 'baseline entry has no reason — name the linked issue or remove the entry',
175
+ });
176
+ }
177
+ }
178
+ for (const c of calls) findings.push({ kind: 'bare-shell', file: rel, ...c, baselined });
179
+ }
180
+
181
+ for (const file of baseline.keys()) {
182
+ if (matchedBaseline.has(file)) continue;
183
+ findings.push({
184
+ kind: 'baseline-stale',
185
+ file,
186
+ message: 'baseline entry no longer has a bare shell spawn (converted or removed) — remove the entry',
187
+ });
188
+ }
189
+
190
+ return { findings, readErrors };
191
+ }
192
+
193
+ /**
194
+ * Run the check and print the validate-plugin line vocabulary.
195
+ *
196
+ * @param {string} repoRoot
197
+ * @param {{baseline?: Map<string, string>}} [options] forwarded to {@link scanTestPosixShell}
198
+ * @returns {number} 0 = clean, 1 = new finding(s), 2 = tool error
199
+ */
200
+ export function runCheckTestPosixShell(repoRoot, options) {
201
+ console.log('--- Check: tests spawn a POSIX shell via posixShell(), not by bare name (#1613) ---');
202
+
203
+ const { findings, readErrors } = scanTestPosixShell(repoRoot, options);
204
+ if (readErrors.length > 0) {
205
+ for (const e of readErrors) console.log(` FAIL: ${e.file} — ${e.message}`);
206
+ console.log('');
207
+ console.log(`Results: 0 passed, ${readErrors.length} failed`);
208
+ return 2;
209
+ }
210
+
211
+ const shellFindings = /** @type {ShellFinding[]} */ (findings.filter((f) => f.kind === 'bare-shell'));
212
+ const baselineIssues = /** @type {BaselineFinding[]} */ (findings.filter((f) => f.kind !== 'bare-shell'));
213
+ const fresh = shellFindings.filter((f) => !f.baselined);
214
+ const old = shellFindings.filter((f) => f.baselined);
215
+
216
+ if (fresh.length === 0 && baselineIssues.length === 0) {
217
+ console.log(
218
+ old.length === 0
219
+ ? ' PASS: no test spawns sh/bash by bare name'
220
+ : ` PASS: no NEW bare sh/bash spawn in tests/ (${old.length} pre-existing, baselined — see #1613)`,
221
+ );
222
+ }
223
+ for (const f of old) {
224
+ console.log(` WARN: ${f.file}:${f.line} — ${f.call}('${f.shell}' …) by bare name (baselined #1613, file is in an open MR)`);
225
+ }
226
+ for (const f of fresh) {
227
+ console.log(
228
+ ` FAIL: ${f.file}:${f.line} — ${f.call}('${f.shell}' …) by bare name; on native Windows sh is not on PATH and bash is WSL — use posixShell() from tests/_helpers/posix-shell.mjs`,
229
+ );
230
+ }
231
+ for (const f of baselineIssues) console.log(` FAIL: ${f.file} — ${f.message} (${f.kind})`);
232
+
233
+ const failCount = fresh.length + baselineIssues.length;
234
+ console.log('');
235
+ console.log(`Results: ${failCount === 0 ? 1 : 0} passed, ${failCount} failed`);
236
+ return failCount > 0 ? 1 : 0;
237
+ }
238
+
239
+ if (isMainModule(import.meta.url)) {
240
+ const root = process.argv[2];
241
+ if (!root) {
242
+ console.error('Usage: check-test-posix-shell.mjs <repo-root>');
243
+ process.exit(2);
244
+ }
245
+ process.exit(runCheckTestPosixShell(path.resolve(root)));
246
+ }
@@ -292,6 +292,8 @@ import path from 'node:path';
292
292
 
293
293
  import { sizingSubject } from '../learnings/sizing-subject.mjs';
294
294
  import { isMainModule } from '../is-main-module.mjs';
295
+ import { resolveLedgerPath } from '../ledger-path.mjs';
296
+ import { resolveEventsLedgerRoot } from '../platform.mjs';
295
297
 
296
298
  /** Documented config surface — every `yaml` fence in this file is a declaration. */
297
299
  const TEMPLATE_REL = 'docs/session-config-template.md';
@@ -1248,7 +1250,7 @@ export function collectHandKeyedLearningSubjects(pluginRoot) {
1248
1250
  let judged = 0;
1249
1251
  let unattributed = 0;
1250
1252
 
1251
- const learnings = readJsonl(path.join(pluginRoot, LEARNINGS_REL));
1253
+ const learnings = readJsonl(resolveLedgerPath(LEARNINGS_REL, pluginRoot));
1252
1254
  if (learnings.length === 0) return { findings, scanned: { judged, unattributed } };
1253
1255
 
1254
1256
  // A session record can be addressed by either identity form (see
@@ -1257,7 +1259,7 @@ export function collectHandKeyedLearningSubjects(pluginRoot) {
1257
1259
  // a resolvable record is never mis-counted as unattributed.
1258
1260
  /** @type {Map<string, Record<string, unknown>>} */
1259
1261
  const sessionsById = new Map();
1260
- for (const record of readJsonl(path.join(pluginRoot, SESSIONS_REL))) {
1262
+ for (const record of readJsonl(path.join(resolveEventsLedgerRoot(pluginRoot), SESSIONS_REL))) {
1261
1263
  for (const field of ['session_id', 'semantic_session_id']) {
1262
1264
  const id = record[field];
1263
1265
  if (typeof id === 'string' && id !== '' && !sessionsById.has(id)) sessionsById.set(id, record);
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Separate WARN-only check for gh pr commands rejected with --repo/-R (#1024).
4
+ * Shares corpus discovery and call-shape parsing with the bare-repo census,
5
+ * but its findings advise naming the PR or dropping the flag, never adding it.
6
+ * Coverage ceilings (literal argv, shell fences/strings) are shared with that census.
7
+ */
8
+ import path from 'node:path';
9
+ import { inspectVcsRepoFlag } from './check-vcs-repo-flag.mjs';
10
+ import { isMainModule } from '../is-main-module.mjs';
11
+
12
+ /** @param {string} pluginRoot independent check envelope */
13
+ export function inspectVcsRepoFlagPositional(pluginRoot) {
14
+ const result = inspectVcsRepoFlag(pluginRoot, { rejected: true });
15
+ return {
16
+ ok: result.ok,
17
+ toolError: result.toolError,
18
+ summary: {
19
+ filesScanned: result.summary.filesScanned,
20
+ unresolvedArgv: result.summary.unresolvedArgv,
21
+ findings: result.findings.length,
22
+ byKind: result.summary.byKind,
23
+ },
24
+ findings: result.findings,
25
+ };
26
+ }
27
+
28
+ if (isMainModule(import.meta.url)) {
29
+ const args = process.argv.slice(2);
30
+ const usage =
31
+ 'Usage: check-vcs-repo-flag-positional.mjs [<plugin-root>] [--json]\n' +
32
+ 'Exit: 0 check completed (findings WARN-only) · 1 usage error · 2 tool error';
33
+ const unknown = args.filter((arg) => arg.startsWith('-') && !['--json', '--help'].includes(arg));
34
+ const roots = args.filter((arg) => !arg.startsWith('-'));
35
+ if (unknown.length || roots.length > 1) {
36
+ console.error(usage);
37
+ process.exitCode = 1;
38
+ } else if (args.includes('--help')) {
39
+ console.log(usage);
40
+ } else {
41
+ const result = inspectVcsRepoFlagPositional(path.resolve(roots[0] ?? process.cwd()));
42
+ if (args.includes('--json')) console.log(JSON.stringify(result, null, 2));
43
+ else {
44
+ console.log('--- Check: --repo/-R requiring a PR positional (WARN-only) ---');
45
+ for (const finding of result.findings) {
46
+ console.log(
47
+ ` ${result.toolError ? 'FAIL' : 'WARN'}: [${finding.kind}] ${finding.file}:${finding.line} — ${finding.message}`,
48
+ );
49
+ }
50
+ if (!result.toolError)
51
+ console.log(
52
+ ` PASS: scanned ${result.summary.filesScanned} file(s), ${result.findings.length} rejected repo flag(s), ${result.summary.unresolvedArgv} variable argv array(s) unjudged`,
53
+ );
54
+ console.log(`Results: ${result.toolError ? '0 passed, 1 failed' : '1 passed, 0 failed'}`);
55
+ }
56
+ process.exitCode = result.toolError ? 2 : 0;
57
+ }
58
+ }