session-orchestrator 5.11.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (394) hide show
  1. package/.claude-plugin/marketplace.json +12 -1
  2. package/.claude-plugin/plugin.json +4 -1
  3. package/.codex-plugin/agents/explorer.toml +1 -1
  4. package/.codex-plugin/agents/session-reviewer.toml +2 -2
  5. package/.codex-plugin/agents/wave-worker.toml +1 -1
  6. package/.codex-plugin/plugin.json +1 -1
  7. package/.cursor-plugin/plugin.json +1 -1
  8. package/.orchestrator/policy/blocked-commands.json +8 -0
  9. package/.orchestrator/policy/public-export.json +30 -0
  10. package/CHANGELOG.md +180 -3
  11. package/README.md +126 -117
  12. package/agents/analyst.md +7 -2
  13. package/agents/architect-reviewer.md +7 -2
  14. package/agents/code-implementer.md +4 -2
  15. package/agents/db-specialist.md +9 -2
  16. package/agents/dialectic-deriver.md +9 -3
  17. package/agents/docs-writer.md +7 -2
  18. package/agents/eval-judge.md +7 -1
  19. package/agents/qa-strategist.md +7 -2
  20. package/agents/security-reviewer.md +9 -2
  21. package/agents/session-reviewer.md +18 -2
  22. package/agents/skill-applied-judge.md +7 -1
  23. package/agents/test-writer.md +9 -2
  24. package/agents/ui-developer.md +9 -2
  25. package/agents/ux-evaluator.md +6 -1
  26. package/commands/session.md +4 -2
  27. package/commands/templates-ack.md +89 -18
  28. package/docs/agent-authoring.md +30 -11
  29. package/docs/ci-setup.md +38 -2
  30. package/docs/codex-setup.md +33 -9
  31. package/docs/components.md +13 -2
  32. package/docs/cursor-setup.md +3 -3
  33. package/docs/events-schema.md +5 -4
  34. package/docs/evidence-candidates.md +63 -0
  35. package/docs/fleet-checkin-audit.md +7 -4
  36. package/docs/github-mirror-protection.md +150 -3
  37. package/docs/install.md +102 -25
  38. package/docs/instruction-delivery.md +1 -1
  39. package/docs/migration-v4.md +2 -2
  40. package/docs/mods.md +118 -0
  41. package/docs/owner-config-schema.md +1 -0
  42. package/docs/plugin-architecture-v3.md +1 -1
  43. package/docs/pm-skills-marketplace.md +4 -3
  44. package/docs/rule-authoring.md +24 -13
  45. package/docs/scope-collision-guard.md +2 -1
  46. package/docs/session-config-reference.md +55 -21
  47. package/docs/session-config-template.md +32 -24
  48. package/docs/sessions-ledger-repair.md +137 -0
  49. package/docs/vault-docs-architecture.md +1 -1
  50. package/hooks/_lib/hook-import-set.json +406 -73
  51. package/hooks/_lib/hook-root.mjs +301 -0
  52. package/hooks/_lib/lock-bootstrap.mjs +434 -4
  53. package/hooks/_lib/orchestrator-ignore.mjs +3 -0
  54. package/hooks/_lib/subagent-transcript.mjs +2 -2
  55. package/hooks/_lib/vcs-create-matcher.mjs +13 -17
  56. package/hooks/cwd-change-restore.mjs +5 -1
  57. package/hooks/enforce-commands.mjs +4 -3
  58. package/hooks/enforce-scope.mjs +11 -1
  59. package/hooks/hooks-codex.json +48 -2
  60. package/hooks/hooks.json +31 -31
  61. package/hooks/on-session-end.mjs +38 -15
  62. package/hooks/on-session-start.mjs +158 -59
  63. package/hooks/on-stop.mjs +11 -6
  64. package/hooks/post-bash-issue-budget-refund.mjs +6 -1
  65. package/hooks/post-bash-write-verify.mjs +8 -4
  66. package/hooks/post-edit-validate.mjs +45 -52
  67. package/hooks/post-subagent-discovery-validator.mjs +2 -2
  68. package/hooks/post-tool-batch-wave-signal.mjs +8 -4
  69. package/hooks/post-tool-failure-corrective-context.mjs +5 -1
  70. package/hooks/pre-bash-destructive-guard.mjs +220 -8
  71. package/hooks/pre-bash-issue-budget.mjs +6 -1
  72. package/hooks/pre-bash-sessions-ledger-guard.mjs +691 -123
  73. package/hooks/pre-bash-staging-fence.mjs +258 -14
  74. package/hooks/pre-bash-templates-first.mjs +28 -27
  75. package/hooks/run-node.sh +1 -1
  76. package/hooks/skill-invocation-telemetry.mjs +15 -8
  77. package/hooks/subagent-telemetry.mjs +77 -14
  78. package/hooks/wave-scope-commit-guard.mjs +143 -14
  79. package/mods/so-hud/.claude-plugin/plugin.json +11 -0
  80. package/mods/so-hud/README.md +57 -0
  81. package/mods/so-hud/hooks/beacon-io.mjs +101 -0
  82. package/mods/so-hud/hooks/heredoc-scan.ts +394 -0
  83. package/mods/so-hud/hooks/hooks.json +1 -0
  84. package/mods/so-hud/hooks/logic.ts +182 -0
  85. package/mods/so-hud/hooks/register.tsx +670 -0
  86. package/mods/so-hud/hooks/rules.ts +2998 -0
  87. package/mods/so-hud/tsconfig.json +8 -0
  88. package/mods/so-hud/types/index.d.ts +36 -0
  89. package/package.json +4 -3
  90. package/rules/_index.md +1 -1
  91. package/rules/always-on/ask-via-tool.md +1 -1
  92. package/rules/always-on/loop-and-monitor.md +17 -194
  93. package/rules/always-on/parallel-sessions.md +3 -1
  94. package/rules/opt-in-stack/backend-data.md +1 -1
  95. package/rules/opt-in-stack/backend.md +1 -1
  96. package/rules/opt-in-stack/security-web.md +5 -1
  97. package/scripts/agent-usage-census.mjs +79 -0
  98. package/scripts/apply-session-learnings.mjs +34 -6
  99. package/scripts/archive-closed-prds.mjs +21 -5
  100. package/scripts/autopilot.mjs +11 -5
  101. package/scripts/backfill-abandoned-sessions.mjs +13 -3
  102. package/scripts/backfill-evidence-digest.mjs +2 -1
  103. package/scripts/backfill-learnings-from-vault.mjs +61 -6
  104. package/scripts/backfill-sessions.mjs +16 -2
  105. package/scripts/check-package-manager.mjs +26 -8
  106. package/scripts/check-sessions-integrity.mjs +4 -1
  107. package/scripts/ci/assert-vitest-green.mjs +3 -0
  108. package/scripts/ci/windows-smoke.mjs +201 -0
  109. package/scripts/close-precheck.mjs +55 -0
  110. package/scripts/dialectic-deriver.mjs +20 -12
  111. package/scripts/emit-event.mjs +2 -2
  112. package/scripts/emit-session.mjs +239 -20
  113. package/scripts/eval-session.mjs +17 -3
  114. package/scripts/export-hw-learnings.mjs +29 -2
  115. package/scripts/fleet-checkin-audit.mjs +8 -4
  116. package/scripts/fleet-checkin.mjs +73 -3
  117. package/scripts/gc-stale-worktrees.mjs +6 -1
  118. package/scripts/github-export.mjs +128 -0
  119. package/scripts/github-protection-audit.mjs +3 -1
  120. package/scripts/handover-queue-check.mjs +209 -0
  121. package/scripts/harness-audit.mjs +6 -4
  122. package/scripts/lib/agent-frontmatter.mjs +57 -10
  123. package/scripts/lib/agent-status.mjs +125 -7
  124. package/scripts/lib/agent-usage-census.mjs +394 -0
  125. package/scripts/lib/auto-dialectic.mjs +17 -10
  126. package/scripts/lib/auto-dream.mjs +22 -14
  127. package/scripts/lib/autopilot/loop.mjs +3 -1
  128. package/scripts/lib/autopilot/recent-runs.mjs +4 -2
  129. package/scripts/lib/autopilot/stall-sampler.mjs +2 -1
  130. package/scripts/lib/autopilot/telemetry.mjs +5 -1
  131. package/scripts/lib/autopilot/worktree-pipeline.mjs +5 -5
  132. package/scripts/lib/baseline-archetypes.mjs +10 -2
  133. package/scripts/lib/blocked-commands-policy.mjs +4 -3
  134. package/scripts/lib/build-live-signals.mjs +13 -9
  135. package/scripts/lib/ci-status-banner.mjs +329 -24
  136. package/scripts/lib/codex/plugin-contract.mjs +8 -0
  137. package/scripts/lib/cold-start-detector.mjs +5 -2
  138. package/scripts/lib/command-blocker.mjs +603 -43
  139. package/scripts/lib/common.mjs +3 -2
  140. package/scripts/lib/config/cross-repo.mjs +74 -7
  141. package/scripts/lib/config/host-paths.mjs +6 -2
  142. package/scripts/lib/config/remote-hosts.mjs +2 -2
  143. package/scripts/lib/config/section-extractor.mjs +65 -11
  144. package/scripts/lib/config/template-keys.mjs +153 -0
  145. package/scripts/lib/config/vault-integration.mjs +1 -0
  146. package/scripts/lib/config.mjs +3 -3
  147. package/scripts/lib/coordinator-snapshot.mjs +1 -1
  148. package/scripts/lib/discovery/triage-state.mjs +2 -1
  149. package/scripts/lib/dispatcher/rank.mjs +5 -7
  150. package/scripts/lib/ecosystem-health.mjs +2 -2
  151. package/scripts/lib/eval/engine.mjs +3 -2
  152. package/scripts/lib/eval/session-resolve.mjs +6 -2
  153. package/scripts/lib/eval/sink.mjs +4 -3
  154. package/scripts/lib/events-retention-banner.mjs +3 -2
  155. package/scripts/lib/events-schema.mjs +10 -0
  156. package/scripts/lib/events.mjs +23 -12
  157. package/scripts/lib/evolve/autonomy-verdict.mjs +4 -9
  158. package/scripts/lib/evolve/autopilot-effectiveness.mjs +8 -18
  159. package/scripts/lib/fleet-protocol.mjs +21 -0
  160. package/scripts/lib/gates/gate-full.mjs +172 -11
  161. package/scripts/lib/gates/gate-helpers.mjs +236 -23
  162. package/scripts/lib/git-config-drift.mjs +141 -7
  163. package/scripts/lib/github-export.mjs +447 -0
  164. package/scripts/lib/gitlab-portfolio/cli.mjs +16 -5
  165. package/scripts/lib/handover-queue-marks.mjs +159 -0
  166. package/scripts/lib/hardware-pattern-detector.mjs +103 -13
  167. package/scripts/lib/harness-audit/categories/category1.mjs +16 -4
  168. package/scripts/lib/harness-audit/categories/category4.mjs +11 -8
  169. package/scripts/lib/harness-audit/categories/category6.mjs +25 -5
  170. package/scripts/lib/harness-audit/categories/category9.mjs +10 -4
  171. package/scripts/lib/host-identity.mjs +9 -5
  172. package/scripts/lib/http-request.mjs +64 -0
  173. package/scripts/lib/instruction-budget-guard.mjs +30 -22
  174. package/scripts/lib/io.mjs +6 -3
  175. package/scripts/lib/issue-budget-reconcile.mjs +3 -2
  176. package/scripts/lib/issue-budget.mjs +36 -7
  177. package/scripts/lib/learnings/evidence-candidates.mjs +154 -0
  178. package/scripts/lib/learnings/expiry-sweep.mjs +99 -7
  179. package/scripts/lib/learnings/io.mjs +289 -15
  180. package/scripts/lib/learnings/select.mjs +53 -4
  181. package/scripts/lib/learnings/store-role.mjs +209 -0
  182. package/scripts/lib/learnings/surface.mjs +46 -7
  183. package/scripts/lib/ledger-path.mjs +113 -0
  184. package/scripts/lib/maintenance-due-banner.mjs +63 -12
  185. package/scripts/lib/memory-banner.mjs +5 -6
  186. package/scripts/lib/memory-proposals/collector.mjs +5 -2
  187. package/scripts/lib/memory-proposals/sink.mjs +7 -4
  188. package/scripts/lib/memory-proposals/store.mjs +22 -5
  189. package/scripts/lib/mode-selector-accuracy.mjs +2 -1
  190. package/scripts/lib/no-follow-open.mjs +57 -0
  191. package/scripts/lib/orphan-reaper/reaper-audit.mjs +4 -2
  192. package/scripts/lib/own-lock-root.mjs +95 -0
  193. package/scripts/lib/owner-interview.mjs +2 -1
  194. package/scripts/lib/owner-yaml.mjs +70 -7
  195. package/scripts/lib/platform.mjs +161 -9
  196. package/scripts/lib/plugin-update-banner.mjs +15 -11
  197. package/scripts/lib/pre-push-local-partial.mjs +117 -0
  198. package/scripts/lib/pre-push-remote-gate.mjs +151 -25
  199. package/scripts/lib/process-group.mjs +270 -34
  200. package/scripts/lib/project-hygiene.mjs +28 -0
  201. package/scripts/lib/quality-gate.mjs +33 -9
  202. package/scripts/lib/reconcile/backlog.mjs +29 -15
  203. package/scripts/lib/reconcile/engine.mjs +26 -2
  204. package/scripts/lib/reconcile/idempotency.mjs +65 -3
  205. package/scripts/lib/reconcile/rule-expiry-sweep.mjs +53 -12
  206. package/scripts/lib/reconcile/verdict-ledger.mjs +224 -0
  207. package/scripts/lib/reconcile-nudge-banner.mjs +40 -6
  208. package/scripts/lib/resource-probe/evaluate.mjs +32 -9
  209. package/scripts/lib/resource-probe/probe-platform.mjs +3 -1
  210. package/scripts/lib/rule-loader.mjs +20 -10
  211. package/scripts/lib/scope-baseline.mjs +123 -8
  212. package/scripts/lib/scope-echo.mjs +5 -2
  213. package/scripts/lib/scope-gate.mjs +55 -20
  214. package/scripts/lib/session-close-backfill.mjs +75 -7
  215. package/scripts/lib/session-end/close-precheck.mjs +151 -0
  216. package/scripts/lib/session-end/phase-skip.mjs +8 -7
  217. package/scripts/lib/session-end/tail-runner.mjs +7 -2
  218. package/scripts/lib/session-end/vault-orphans.mjs +205 -0
  219. package/scripts/lib/session-id.mjs +9 -1
  220. package/scripts/lib/session-identity/own-session.mjs +63 -0
  221. package/scripts/lib/session-invocation.mjs +14 -3
  222. package/scripts/lib/session-lock.mjs +114 -0
  223. package/scripts/lib/session-record-repair.mjs +245 -35
  224. package/scripts/lib/session-registry.mjs +85 -12
  225. package/scripts/lib/session-schema/constants.mjs +9 -0
  226. package/scripts/lib/session-schema/filters.mjs +56 -1
  227. package/scripts/lib/session-schema/validator.mjs +15 -5
  228. package/scripts/lib/session-start-probes.mjs +149 -22
  229. package/scripts/lib/session-token-rollup.mjs +2 -1
  230. package/scripts/lib/session-work-trees.mjs +166 -0
  231. package/scripts/lib/sessions-canonical.mjs +61 -3
  232. package/scripts/lib/sessions-integrity-banner.mjs +17 -39
  233. package/scripts/lib/sessions-staleness-banner.mjs +8 -5
  234. package/scripts/lib/sh-quote.mjs +1 -0
  235. package/scripts/lib/skill-evidence-window.mjs +5 -1
  236. package/scripts/lib/skill-health/join.mjs +10 -9
  237. package/scripts/lib/skill-invocations-schema.mjs +13 -0
  238. package/scripts/lib/skill-judgments-schema.mjs +6 -2
  239. package/scripts/lib/snapshot-probe.mjs +414 -0
  240. package/scripts/lib/so-hud/collect.mjs +174 -0
  241. package/scripts/lib/so-hud/runtime.mjs +87 -0
  242. package/scripts/lib/spiral-carryover.mjs +8 -1
  243. package/scripts/lib/state-md/frontmatter-mutators.mjs +266 -8
  244. package/scripts/lib/state-md/idle-reset.mjs +248 -0
  245. package/scripts/lib/state-md/mission-status.mjs +5 -1
  246. package/scripts/lib/state-md/recommendations.mjs +26 -4
  247. package/scripts/lib/state-md-peer-guard.mjs +2 -0
  248. package/scripts/lib/state-md.mjs +31 -8
  249. package/scripts/lib/sunset/walker.mjs +4 -3
  250. package/scripts/lib/telemetry/consent.mjs +4 -2
  251. package/scripts/lib/telemetry/queue.mjs +3 -3
  252. package/scripts/lib/telemetry/sync.mjs +45 -9
  253. package/scripts/lib/test-runner/artifact-paths.mjs +10 -2
  254. package/scripts/lib/tmux-layout/layouts.mjs +20 -3
  255. package/scripts/lib/ux-grill/paths.mjs +5 -1
  256. package/scripts/lib/validate/check-agents.mjs +37 -6
  257. package/scripts/lib/validate/check-component-paths.mjs +25 -1
  258. package/scripts/lib/validate/check-guard-requires-parity.mjs +3 -3
  259. package/scripts/lib/validate/check-hooks-symmetry.mjs +53 -32
  260. package/scripts/lib/validate/check-json-files.mjs +3 -1
  261. package/scripts/lib/validate/check-learning-provenance.mjs +3 -2
  262. package/scripts/lib/validate/check-learnings-shell-writes.mjs +10 -4
  263. package/scripts/lib/validate/check-metrics-ledger-root.mjs +234 -0
  264. package/scripts/lib/validate/check-owner-leakage.mjs +159 -11
  265. package/scripts/lib/validate/check-test-posix-shell.mjs +246 -0
  266. package/scripts/lib/validate/check-unwired-features.mjs +4 -2
  267. package/scripts/lib/validate/check-vcs-repo-flag-positional.mjs +58 -0
  268. package/scripts/lib/validate/check-vcs-repo-flag.mjs +259 -73
  269. package/scripts/lib/validate/check-workflow-continue-on-error.mjs +63 -0
  270. package/scripts/lib/validate/confidential-names.mjs +3 -1
  271. package/scripts/lib/vault-mirror/migrate-ids.mjs +321 -0
  272. package/scripts/lib/vault-mirror/namespace.mjs +22 -9
  273. package/scripts/lib/vault-mirror/process.mjs +197 -65
  274. package/scripts/lib/vault-mirror/prune.mjs +5 -2
  275. package/scripts/lib/vault-mirror/render-learnings.mjs +8 -7
  276. package/scripts/lib/vault-mirror/render-sessions.mjs +36 -53
  277. package/scripts/lib/vault-mirror/retention.mjs +2 -2
  278. package/scripts/lib/vault-mirror/utils.mjs +106 -13
  279. package/scripts/lib/vault-staleness-banner.mjs +4 -7
  280. package/scripts/lib/vault-status/board-writer.mjs +34 -5
  281. package/scripts/lib/vault-status/narrative-mirror.mjs +66 -7
  282. package/scripts/lib/wave-executor/foreign-dispatch.mjs +20 -0
  283. package/scripts/lib/win-process-tree.mjs +137 -0
  284. package/scripts/lib/workspace.mjs +1 -1
  285. package/scripts/lib/worktree/constants.mjs +1 -1
  286. package/scripts/lib/worktree/lifecycle.mjs +1 -1
  287. package/scripts/lib/worktree/listing.mjs +1 -1
  288. package/scripts/lib/zx.mjs +50 -0
  289. package/scripts/mcp-server.mjs +16 -7
  290. package/scripts/mcp-server.sh +13 -83
  291. package/scripts/measure-policy-cache-effectiveness.mjs +7 -5
  292. package/scripts/memory-propose.mjs +10 -3
  293. package/scripts/migrate-cold-start-seed.mjs +7 -0
  294. package/scripts/migrate-legacy-learnings.sh +22 -0
  295. package/scripts/migrate-sessions-jsonl.mjs +16 -2
  296. package/scripts/migrate-vault-paths.mjs +29 -13
  297. package/scripts/parse-config.mjs +71 -14
  298. package/scripts/print-learnings-index.mjs +25 -2
  299. package/scripts/release-session-lock.mjs +94 -7
  300. package/scripts/release.mjs +451 -24
  301. package/scripts/relocate-vault-corpus.mjs +11 -7
  302. package/scripts/repair-invalid-sessions.mjs +68 -3
  303. package/scripts/resolve-session-invocation.mjs +57 -8
  304. package/scripts/run-migrate-v2-cross-repo.mjs +56 -1
  305. package/scripts/run-quality-gate.mjs +33 -7
  306. package/scripts/self-update.mjs +56 -7
  307. package/scripts/session-commit-files.mjs +133 -0
  308. package/scripts/site-numbers.mjs +52 -9
  309. package/scripts/snapshot-probe.mjs +156 -0
  310. package/scripts/so-hud.mjs +68 -0
  311. package/scripts/state-md-idle-reset.mjs +82 -0
  312. package/scripts/sweep-expired-learnings.mjs +54 -6
  313. package/scripts/sweep-expired-rules.mjs +4 -1
  314. package/scripts/validate-plugin.mjs +22 -0
  315. package/scripts/vault-integration-watcher.mjs +54 -6
  316. package/scripts/vault-mirror.mjs +9 -0
  317. package/scripts/vault-orphans.mjs +171 -0
  318. package/skills/_shared/fleet-protocol.md +166 -3
  319. package/skills/_shared/instruction-file-resolution.md +1 -1
  320. package/skills/_shared/monitor-patterns.md +44 -25
  321. package/skills/_shared/platform-tools.md +7 -0
  322. package/skills/_shared/state-ownership.md +5 -4
  323. package/skills/architecture/references/domain-model.md +1 -1
  324. package/skills/autopilot/SKILL.md +3 -2
  325. package/skills/bootstrap/SKILL.md +3 -1
  326. package/skills/bootstrap/_shared-template.md +4 -4
  327. package/skills/bootstrap/fast-template.md +1 -1
  328. package/skills/bootstrap/private-contract.md +1 -1
  329. package/skills/bootstrap/references/bootstrap-retroactive-flow.md +17 -9
  330. package/skills/bootstrap/templates/agents/project-code-review.md +5 -1
  331. package/skills/bootstrap/templates/agents/project-discovery.md +5 -1
  332. package/skills/bootstrap/templates/agents/project-quality-gate.md +5 -1
  333. package/skills/claude-md-drift-check/SKILL.md +3 -3
  334. package/skills/claude-md-drift-check/checker.mjs +61 -101
  335. package/skills/close/SKILL.md +20 -7
  336. package/skills/discovery/probes/docs-staleness.mjs +7 -5
  337. package/skills/discovery/probes/frontend-slop.mjs +7 -3
  338. package/skills/discovery/probes/ssot-code-diff.mjs +5 -3
  339. package/skills/discovery/probes/supply-chain-slopcheck.mjs +10 -8
  340. package/skills/discovery/probes/vault-narrative-staleness.mjs +30 -10
  341. package/skills/discovery/probes/vault-staleness.mjs +5 -3
  342. package/skills/discovery/probes-session.md +3 -0
  343. package/skills/discovery/probes-vault.md +2 -0
  344. package/skills/dispatcher/SKILL.md +1 -1
  345. package/skills/eval/SKILL.md +3 -1
  346. package/skills/evolve/SKILL.md +2 -0
  347. package/skills/evolve/references/evolve-analyze-mode.md +3 -3
  348. package/skills/evolve/references/evolve-dialectic-mode.md +1 -1
  349. package/skills/gitlab-ops/SKILL.md +7 -6
  350. package/skills/gitlab-portfolio/SKILL.md +2 -2
  351. package/skills/go/SKILL.md +13 -1
  352. package/skills/npm-publish/SKILL.md +5 -2
  353. package/skills/plan/SKILL.md +23 -10
  354. package/skills/plan/mode-feature.md +13 -8
  355. package/skills/plan/mode-new.md +6 -14
  356. package/skills/plan/prd-feature-template.md +19 -0
  357. package/skills/plan/prd-full-template.md +12 -5
  358. package/skills/plan/prd-premortem-panel.md +48 -0
  359. package/skills/plan/prd-reviewer-prompt.md +11 -3
  360. package/skills/plan/soul.md +1 -1
  361. package/skills/portfolio/SKILL.md +5 -6
  362. package/skills/quality-gates/SKILL.md +2 -4
  363. package/skills/reconcile/SKILL.md +27 -4
  364. package/skills/release/SKILL.md +16 -8
  365. package/skills/session-end/SKILL.md +97 -13
  366. package/skills/session-end/phase-3-2-docs-verification.md +1 -0
  367. package/skills/session-end/phase-3-6-tail.md +11 -7
  368. package/skills/session-end/phase-3-7a-recommendations.md +9 -2
  369. package/skills/session-end/plan-verification.md +16 -1
  370. package/skills/session-end/references/phase-3-7e-vault-orphans.md +63 -0
  371. package/skills/session-end/references/phase-3-documentation-updates.md +25 -13
  372. package/skills/session-end/references/phase-5-issue-cleanup.md +1 -1
  373. package/skills/session-end/references/session-summary-template.md +8 -0
  374. package/skills/session-end/session-metrics-write.md +7 -4
  375. package/skills/session-plan/SKILL.md +5 -3
  376. package/skills/session-start/SKILL.md +10 -4
  377. package/skills/session-start/phase-4-5-resource-health.md +11 -5
  378. package/skills/session-start/phase-7-5-mode-selector.md +3 -1
  379. package/skills/session-start/phase-8-5-express-path.md +4 -3
  380. package/skills/session-start/references/phase-1-2-session-lock.md +7 -5
  381. package/skills/session-start/references/phase-1-5-session-continuity.md +13 -5
  382. package/skills/session-start/references/phase-1-7-vault-status-board.md +1 -1
  383. package/skills/session-start/references/phase-4-ssot-environment-check.md +3 -2
  384. package/skills/tmux-layout/SKILL.md +2 -2
  385. package/skills/vault-sync/validator.mjs +3 -2
  386. package/skills/wave-executor/SKILL.md +5 -4
  387. package/skills/wave-executor/references/wave-executor-state-init.md +3 -3
  388. package/skills/wave-executor/references/wave-loop-dispatch.md +11 -5
  389. package/skills/wave-executor/references/wave-loop-review.md +13 -5
  390. package/skills/wave-executor/references/wave-loop-scope-manifest.md +1 -1
  391. package/AGENTS.md +0 -207
  392. package/assets/og-card.png +0 -0
  393. package/assets/og-card.svg +0 -47
  394. package/assets/wave-lifecycle.svg +0 -98
@@ -26,8 +26,18 @@ import { existsSync, statSync } from 'node:fs';
26
26
  import path from 'node:path';
27
27
  import { atomicWriteText, envelopeToError } from './io.mjs';
28
28
 
29
- import { readCanonicalSessions } from './sessions-canonical.mjs';
30
- import { filterRealSessions } from './session-schema.mjs';
29
+ import { readCanonicalSessions, isMeasuredSession } from './sessions-canonical.mjs';
30
+ import { resolveEventsLedgerRoot } from './platform.mjs';
31
+
32
+ /**
33
+ * Tolerated skew (ms) between the system clock (`generated_at`) and filesystem
34
+ * timestamps (MEMORY.md mtime) in the #788 drift check. Windows was measured
35
+ * stamping mtimes up to 1 ms AFTER the clock reading that preceded the write.
36
+ * Ceiling (BV-004): a real MEMORY.md write within this window after the sidecar
37
+ * is indistinguishable from skew and is not refused. Revisit if a measured skew
38
+ * above the tolerance appears or a writer needs sub-5-ms freshness.
39
+ */
40
+ const CLOCK_SKEW_TOLERANCE_MS = 5;
31
41
 
32
42
  // ---------------------------------------------------------------------------
33
43
  // Signal reader — MEMORY.md size + sessions-since-last-cleanup
@@ -53,7 +63,7 @@ import { filterRealSessions } from './session-schema.mjs';
53
63
  */
54
64
  export async function readDreamSignals({ repoRoot, memoryDir }) {
55
65
  const memoryPath = path.join(memoryDir, 'MEMORY.md');
56
- const sessionsFilePath = path.join(repoRoot, '.orchestrator', 'metrics', 'sessions.jsonl');
66
+ const sessionsFilePath = path.join(resolveEventsLedgerRoot(repoRoot), '.orchestrator', 'metrics', 'sessions.jsonl');
57
67
 
58
68
  // 1. Line count of MEMORY.md (missing → 0)
59
69
  let memoryLines = 0;
@@ -80,13 +90,10 @@ export async function readDreamSignals({ repoRoot, memoryDir }) {
80
90
 
81
91
  const entries = readCanonicalSessions({ filePath: sessionsFilePath });
82
92
 
83
- // Abandoned-session filter (#834): sessions.jsonl carries phantom
84
- // `status: 'abandoned'` stubs (session-close-backfill records for
85
- // sessions that ended without a real close). They are legitimate DATA
86
- // but not legitimate SIGNAL — a burst of abandoned stubs must not fire
87
- // /memory-cleanup off zero real work. filterRealSessions() is the
88
- // shared, tested implementation (scripts/lib/session-schema/filters.mjs).
89
- const realEntries = filterRealSessions(entries);
93
+ // Count only canonical measured work (#1584), including legacy waves and
94
+ // known non-synthetic abandoned sessions; synthetic completed stubs do not
95
+ // advance maintenance cadence or supply a cleanup anchor.
96
+ const realEntries = entries.filter(isMeasuredSession);
90
97
 
91
98
  // Find the most recent memory_cleanup_at timestamp across all REAL entries.
92
99
  for (const entry of realEntries) {
@@ -438,12 +445,13 @@ export async function applyPendingDream({ repoRoot, memoryDir, maxAgeDays = 14 }
438
445
  // (nanosecond) precision on APFS/ext4. Comparing them raw makes a
439
446
  // MEMORY.md written in the SAME millisecond as the sidecar (mtimeMs
440
447
  // fractionally > the floored generatedMs) look like drift. Floor mtimeMs
441
- // to the resolution `generated_at` actually has, then apply strict `>`
442
- // (mirrors `ageDays > maxAgeDays`): same-millisecond = clock-resolution
443
- // noise, not a drift signal; a later write (≥1ms) is a real signal.
448
+ // to the resolution `generated_at` actually has. The system clock and
449
+ // the filesystem clock can also disagree by a millisecond (Windows), so
450
+ // drift is signalled only beyond CLOCK_SKEW_TOLERANCE_MS: up to the
451
+ // tolerance = clock noise, tolerance + 1 ms or later = a real write.
444
452
  if (existsSync(memoryPath)) {
445
453
  const memoryMtimeMs = statSync(memoryPath).mtimeMs;
446
- if (Math.floor(memoryMtimeMs) > generatedMs) {
454
+ if (Math.floor(memoryMtimeMs) > generatedMs + CLOCK_SKEW_TOLERANCE_MS) {
447
455
  return { applied: false, reason: 'stale-index', driftMs: Math.round(memoryMtimeMs - generatedMs) };
448
456
  }
449
457
  }
@@ -21,6 +21,7 @@ import {
21
21
  } from './telemetry.mjs';
22
22
  import { durableCommit } from './durable-telemetry.mjs';
23
23
  import { getStateDir } from '../platform.mjs';
24
+ import { resolveLedgerPath } from '../ledger-path.mjs';
24
25
 
25
26
  // Internal clamp — mirrors flags.mjs internal; not re-exported there.
26
27
  function clampNumber(value, { min, max, fallback }) {
@@ -91,7 +92,7 @@ export async function runLoop(opts = {}) {
91
92
  const nowMs = typeof opts.nowMs === 'function' ? opts.nowMs : () => Date.now();
92
93
  const jsonlPath = typeof opts.jsonlPath === 'string' && opts.jsonlPath.length > 0
93
94
  ? opts.jsonlPath
94
- : DEFAULT_JSONL_PATH;
95
+ : resolveLedgerPath(DEFAULT_JSONL_PATH, process.cwd()); // #1722: linked worktree → main checkout when ignored
95
96
  const peerAbortThreshold = typeof opts.peerAbortThreshold === 'number'
96
97
  ? opts.peerAbortThreshold
97
98
  : DEFAULT_PEER_ABORT_THRESHOLD;
@@ -342,6 +343,7 @@ export async function runLoop(opts = {}) {
342
343
  sessionId: state.autopilot_run_id,
343
344
  files: [
344
345
  jsonlPath.replace(process.cwd() + '/', ''),
346
+ // ledger-root: durableCommit file list (disabled), not a sink
345
347
  '.orchestrator/metrics/sessions.jsonl',
346
348
  `${getStateDir()}/STATE.md`,
347
349
  ],
@@ -43,12 +43,14 @@
43
43
  * - Corrupt lines are SKIPPED (not fatal): one malformed JSON line does not
44
44
  * discard the rest of the history.
45
45
  *
46
- * No imports beyond node builtins. ESM. eslint-clean (eqeqeq, no-throw).
46
+ * Imports node builtins plus the #1722 ledger resolver. ESM. eslint-clean (eqeqeq, no-throw).
47
47
  */
48
48
 
49
49
  import { readFileSync } from 'node:fs';
50
50
  import path from 'node:path';
51
51
 
52
+ import { resolveLedgerPath } from '../ledger-path.mjs';
53
+
52
54
  /** Canonical per-repo autopilot telemetry path (relative to repoRoot). */
53
55
  const AUTOPILOT_JSONL_RELPATH = path.join('.orchestrator', 'metrics', 'autopilot.jsonl');
54
56
 
@@ -80,7 +82,7 @@ export function readRecentAutopilotRuns({ repoRoot, limit = DEFAULT_LIMIT } = {}
80
82
 
81
83
  let raw;
82
84
  try {
83
- raw = readFileSync(path.join(repoRoot, AUTOPILOT_JSONL_RELPATH), 'utf8');
85
+ raw = readFileSync(resolveLedgerPath(AUTOPILOT_JSONL_RELPATH, repoRoot), 'utf8');
84
86
  } catch {
85
87
  // Missing / unreadable file ⇒ no history ⇒ [] (G2 gate omitted with a warning).
86
88
  return [];
@@ -36,6 +36,7 @@
36
36
  */
37
37
 
38
38
  import { readFileSync, statSync } from 'node:fs';
39
+ import { resolveLedgerPath } from '../ledger-path.mjs';
39
40
 
40
41
  // ---------------------------------------------------------------------------
41
42
  // Constants
@@ -114,7 +115,7 @@ function readHeartbeatMs(sessionLockPath) {
114
115
  * }}
115
116
  */
116
117
  export function sampleProgress(opts = {}) {
117
- const autopilotJsonlPath = opts.autopilotJsonlPath ?? DEFAULT_AUTOPILOT_JSONL;
118
+ const autopilotJsonlPath = opts.autopilotJsonlPath ?? resolveLedgerPath(DEFAULT_AUTOPILOT_JSONL, process.cwd());
118
119
  // stallTimeoutSeconds is currently informational — the caller decides if
119
120
  // stallSeconds exceeds threshold. We read it (with default) so the signature
120
121
  // stays stable when (future) clamp logic moves here. Underscore prefix marks
@@ -21,6 +21,7 @@ import { mkdirSync, readFileSync } from 'node:fs';
21
21
  import path from 'node:path';
22
22
 
23
23
  import { atomicWriteWithBackup, envelopeToError } from '../io.mjs';
24
+ import { resolveLedgerPath } from '../ledger-path.mjs';
24
25
 
25
26
  // ---------------------------------------------------------------------------
26
27
  // Schema version
@@ -183,7 +184,10 @@ const DEFAULT_AUTOPILOT_JSONL = '.orchestrator/metrics/autopilot.jsonl';
183
184
  * @param {string} [jsonlPath] - defaults to .orchestrator/metrics/autopilot.jsonl
184
185
  * @returns {void}
185
186
  */
186
- export function writeMultiStoryCoordinatorEntry(entry, jsonlPath = DEFAULT_AUTOPILOT_JSONL) {
187
+ export function writeMultiStoryCoordinatorEntry(
188
+ entry,
189
+ jsonlPath = resolveLedgerPath(DEFAULT_AUTOPILOT_JSONL, process.cwd()),
190
+ ) {
187
191
  // Defensive: ensure metrics directory exists
188
192
  const dir = path.dirname(jsonlPath);
189
193
  try { mkdirSync(dir, { recursive: true }); } catch { /* idempotent — directory may already exist */ }
@@ -21,9 +21,9 @@
21
21
  // - scripts/lib/worktree/lifecycle.mjs (substrate: validateWorkspacePath)
22
22
 
23
23
  // NOTE: zx is imported LAZILY inside functions that need it (see lazyZx() helper).
24
- // Top-level `import { $ as realZx } from 'zx'` caused fork-pool fragility — when this
24
+ // Top-level `import { $ as realZx } from '../zx.mjs'` caused fork-pool fragility — when this
25
25
  // module is loaded in a worker fork before tests like tests/lib/worktree/constants.test.mjs
26
- // run, vi.mock('zx', ...) factories in those test files cannot re-route the cached
26
+ // run, vi.mock('@lib/zx.mjs', ...) factories in those test files cannot re-route the cached
27
27
  // import. Pipeline 3848 (commit 1347c7a) failed for this reason. Lazy import preserves
28
28
  // module-load order isolation. Pattern matches deep-2 #367 DI-seam migration.
29
29
  import path from 'node:path';
@@ -200,7 +200,7 @@ export async function setupWorktree(context, opts = {}) {
200
200
  worktreeRoot = WORKTREE_ROOT_DEFAULT,
201
201
  } = context;
202
202
 
203
- const exec = opts.$ ?? (await import('zx')).$;
203
+ const exec = opts.$ ?? (await import('../zx.mjs')).$;
204
204
 
205
205
  // CWE-59 hardening (#375): resolve symlinks in worktreeRoot ONCE so that
206
206
  // validateWorkspacePath comparisons use a fully-resolved parent path.
@@ -748,7 +748,7 @@ function writePromotionMarker({ wtPath, sourceRoot, sessionId, branch }) {
748
748
  * recorded verbatim in the `orchestrator.session.root_left` payload. Only used
749
749
  * when `rawSessionId` is given.
750
750
  * @param {object} [opts]
751
- * @param {Function} [opts.$] - zx-like template-tag executor (DI seam); falls back to lazy `await import('zx')`.
751
+ * @param {Function} [opts.$] - zx-like template-tag executor (DI seam); falls back to lazy `await import('../zx.mjs')`.
752
752
  * Every freshly created worktree also gets a `.orchestrator/promoted-from.json`
753
753
  * marker (see {@link PROMOTION_MARKER_RELPATH}) so session-end Phase 4a can
754
754
  * still recognise it after the #1069 process boundary hands the worktree to a
@@ -817,7 +817,7 @@ export async function enterWorktree({
817
817
  // -------------------------------------------------------------------------
818
818
  // Step 2: Lazy zx DI (Pipeline 3848 commit 1347c7a — mandatory for vi.mock).
819
819
  // -------------------------------------------------------------------------
820
- const exec = opts.$ ?? (await import('zx')).$;
820
+ const exec = opts.$ ?? (await import('../zx.mjs')).$;
821
821
 
822
822
  // -------------------------------------------------------------------------
823
823
  // Step 3: Path resolution + boundary check (mirrors setupWorktree lines 154-187).
@@ -71,7 +71,11 @@ export function validateBaselineContract(value) {
71
71
  check(typeof item.id === 'string' && ID.test(item.id));
72
72
  check(Number.isSafeInteger(item.order) && item.order >= 1);
73
73
  relative(item.templatePath); check(item.templatePath === `templates/${item.id}`);
74
- for (const key of ['runtimes', 'packageManagers']) array(item[key], (runtime) => { shape(runtime, ['name', 'version']); text(runtime.name); text(runtime.version); }, 1);
74
+ // projects-baseline docs/ARCHETYPE-CONTRACT.md: "`pkm-vault` is the only archetype
75
+ // allowed to have empty runtime and package-manager arrays" (#1607). Every other
76
+ // archetype still needs at least one entry.
77
+ const runtimeMinimum = item.id === 'pkm-vault' ? 0 : 1;
78
+ for (const key of ['runtimes', 'packageManagers']) array(item[key], (runtime) => { shape(runtime, ['name', 'version']); text(runtime.name); text(runtime.version); }, runtimeMinimum);
75
79
  shape(item.ui, ['mode', 'framework', 'tailwind']); text(item.ui.mode); text(item.ui.framework); check(typeof item.ui.tailwind === 'boolean');
76
80
  shape(item.api, ['mode', 'framework']); text(item.api.mode); text(item.api.framework);
77
81
  shape(item.deploy, ['default', 'alternatives']); text(item.deploy.default); strings(item.deploy.alternatives);
@@ -136,10 +140,14 @@ export function baselineSourcePath(root, source, directory = false, { missingRea
136
140
  try { realRoot = realpathSync(root); } catch { fail('unsafe-source'); }
137
141
  let current = root;
138
142
  let stat;
139
- for (const component of source.split('/')) {
143
+ const components = source.split('/');
144
+ for (const [index, component] of components.entries()) {
140
145
  current = path.join(current, component);
141
146
  try { stat = lstatSync(current); } catch (error) { fail(error?.code === 'ENOENT' ? missingReason : 'unsafe-source'); }
142
147
  if (stat.isSymbolicLink()) fail('unsafe-source');
148
+ // A path below a non-directory is unsafe on every platform: POSIX lstat
149
+ // throws ENOTDIR, Windows ENOENT (which would read as "missing").
150
+ if (index < components.length - 1 && !stat.isDirectory()) fail('unsafe-source');
143
151
  }
144
152
  if (directory ? !stat.isDirectory() : !stat.isFile()) fail('unsafe-source');
145
153
  let real;
@@ -19,9 +19,10 @@
19
19
  * `{}`, `{"rules":[]}`, malformed JSON, and a missing file) — every overlay
20
20
  * failure mode fails TO THE FLOOR, not open.
21
21
  *
22
- * All exported functions are TOTAL: they never throw. The consuming hook keeps
23
- * its documented `main().catch → exit 0` fail-open for internal errors, so any
24
- * throw here would silently disarm the guard — totality is load-bearing.
22
+ * All exported functions are TOTAL: they never throw. The consuming hook now
23
+ * DENIES on an error inside main() (fail-closed, #1671); only a module-load
24
+ * failure stays fail-open (#992). A throw here would therefore block every Bash
25
+ * call instead of disarming the guard — totality is still load-bearing.
25
26
  */
26
27
 
27
28
  import { existsSync, promises as fsp } from 'node:fs';
@@ -17,10 +17,11 @@
17
17
  import { existsSync, readFileSync } from 'node:fs';
18
18
  import { resolve } from 'node:path';
19
19
  import { parseStateMd, parseRecommendations, resolveStateMdPath } from './state-md.mjs';
20
- import { normalizeSession, tailRealSessions } from './session-schema.mjs';
20
+ import { normalizeSession } from './session-schema.mjs';
21
21
  import { parseBootstrapLock } from './bootstrap-lock-freshness.mjs';
22
22
  import { scanBacklog, DEFAULT_BACKLOG_LIMIT } from './backlog-scan.mjs';
23
- import { readCanonicalSessions } from './sessions-canonical.mjs';
23
+ import { isMeasuredSession, readCanonicalSessions } from './sessions-canonical.mjs';
24
+ import { resolveEventsLedgerRoot } from './platform.mjs';
24
25
 
25
26
  // ---------------------------------------------------------------------------
26
27
  // Public API
@@ -65,7 +66,7 @@ export async function buildLiveSignals(opts = {}) {
65
66
  ? resolve(repoRoot, opts.statePath)
66
67
  : resolveStateMdPath(repoRoot);
67
68
  const sessionsPath = resolve(
68
- repoRoot,
69
+ typeof opts.sessionsPath === 'string' ? repoRoot : resolveEventsLedgerRoot(repoRoot),
69
70
  typeof opts.sessionsPath === 'string'
70
71
  ? opts.sessionsPath
71
72
  : '.orchestrator/metrics/sessions.jsonl'
@@ -129,12 +130,15 @@ export async function buildLiveSignals(opts = {}) {
129
130
  // handling (ENOENT vs EACCES/EISDIR, #1188) is delegated to the shared
130
131
  // reader; both still degrade to `[]` here, matching Branch 3's contract.
131
132
  const canonical = readCanonicalSessions({ filePath: sessionsPath });
132
- const parsed = canonical.map((obj) => normalizeSession(obj));
133
- // #834: `status: 'abandoned'` phantom stubs must still be filtered out
134
- // BEFORE the tail is taken, or sessionTailN silently means "last N LINES"
135
- // instead of "last N REAL sessions". tailRealSessions() does the filter +
136
- // tail.
137
- recentSessions = tailRealSessions(parsed, sessionTailN);
133
+ // Audit E1: drop synthetic backfill stubs (incl. non-abandoned
134
+ // `state-md-completed` ones `isRealSession` lets through) BEFORE normalizing
135
+ // — they would otherwise count toward the mode-selector's session-type
136
+ // history. Filtered on the raw record so normalization cannot mask markers.
137
+ const parsed = canonical.filter(isMeasuredSession).map((obj) => normalizeSession(obj));
138
+ // Take the tail AFTER measured filtering, using the same population as
139
+ // site-numbers and dispatcher; a status-only filter would narrow it again.
140
+ recentSessions = Number.isFinite(sessionTailN) && sessionTailN > 0
141
+ ? parsed.slice(-Math.floor(sessionTailN)) : [];
138
142
  } catch {
139
143
  // Branch 3: file unreadable — recentSessions stays [] (readCanonicalSessions
140
144
  // itself never throws, but the graceful-null contract is kept as a backstop).