session-orchestrator 3.16.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 (762) hide show
  1. package/.claude-plugin/marketplace.json +29 -0
  2. package/.claude-plugin/plugin.json +18 -0
  3. package/.codex-plugin/agents/explorer.toml +14 -0
  4. package/.codex-plugin/agents/session-reviewer.toml +23 -0
  5. package/.codex-plugin/agents/wave-worker.toml +15 -0
  6. package/.codex-plugin/config.toml +20 -0
  7. package/.codex-plugin/plugin.json +37 -0
  8. package/.cursor/rules/000-session-orchestrator.mdc +73 -0
  9. package/.cursor/rules/010-session-workflow.mdc +170 -0
  10. package/.cursor/rules/020-quality-gates.mdc +128 -0
  11. package/.cursor/rules/030-wave-execution.mdc +216 -0
  12. package/.cursor/rules/040-discovery.mdc +242 -0
  13. package/.cursor/rules/050-plan.mdc +235 -0
  14. package/.cursor/rules/060-evolve.mdc +232 -0
  15. package/.cursor/rules/070-gitlab-ops.mdc +246 -0
  16. package/.cursor/rules/080-ecosystem-health.mdc +145 -0
  17. package/.mcp.json +8 -0
  18. package/CHANGELOG.md +1544 -0
  19. package/LICENSE +21 -0
  20. package/NOTICE +64 -0
  21. package/README.md +242 -0
  22. package/SECURITY.md +90 -0
  23. package/agents/AGENTS.md +136 -0
  24. package/agents/analyst.md +99 -0
  25. package/agents/architect-reviewer.md +93 -0
  26. package/agents/code-implementer.md +106 -0
  27. package/agents/db-specialist.md +104 -0
  28. package/agents/dialectic-deriver.md +139 -0
  29. package/agents/docs-writer.md +113 -0
  30. package/agents/eval-judge.md +146 -0
  31. package/agents/memory-proposal-collector.md +297 -0
  32. package/agents/qa-strategist.md +102 -0
  33. package/agents/schemas/analyst.schema.json +46 -0
  34. package/agents/schemas/architect-reviewer.schema.json +50 -0
  35. package/agents/schemas/code-implementer.schema.json +61 -0
  36. package/agents/schemas/db-specialist.schema.json +80 -0
  37. package/agents/schemas/docs-writer.schema.json +56 -0
  38. package/agents/schemas/persona-panel-sidecar.schema.json +245 -0
  39. package/agents/schemas/qa-strategist.schema.json +46 -0
  40. package/agents/schemas/security-reviewer.schema.json +86 -0
  41. package/agents/schemas/session-reviewer.schema.json +69 -0
  42. package/agents/schemas/test-writer.schema.json +69 -0
  43. package/agents/schemas/ui-developer.schema.json +90 -0
  44. package/agents/schemas/ux-evaluator.schema.json +51 -0
  45. package/agents/security-reviewer.md +236 -0
  46. package/agents/session-reviewer.md +201 -0
  47. package/agents/skill-applied-judge.md +122 -0
  48. package/agents/test-writer.md +123 -0
  49. package/agents/ui-developer.md +109 -0
  50. package/agents/ux-evaluator.md +161 -0
  51. package/assets/icon.svg +11 -0
  52. package/assets/og-card.png +0 -0
  53. package/assets/og-card.svg +47 -0
  54. package/commands/autopilot-multi.md +74 -0
  55. package/commands/autopilot.md +80 -0
  56. package/commands/bootstrap.md +56 -0
  57. package/commands/brainstorm.md +48 -0
  58. package/commands/close.md +24 -0
  59. package/commands/debug.md +36 -0
  60. package/commands/discovery.md +32 -0
  61. package/commands/dispatcher.md +59 -0
  62. package/commands/eval.md +28 -0
  63. package/commands/evolve.md +10 -0
  64. package/commands/go.md +41 -0
  65. package/commands/grill.md +45 -0
  66. package/commands/harness-audit.md +26 -0
  67. package/commands/memory-cleanup.md +25 -0
  68. package/commands/persona-panel.md +121 -0
  69. package/commands/plan.md +15 -0
  70. package/commands/portfolio.md +97 -0
  71. package/commands/reconcile.md +23 -0
  72. package/commands/repo-audit.md +24 -0
  73. package/commands/session.md +30 -0
  74. package/commands/spinout.md +15 -0
  75. package/commands/sunset-review.md +27 -0
  76. package/commands/templates-ack.md +96 -0
  77. package/commands/test.md +97 -0
  78. package/docs/README.md +105 -0
  79. package/docs/USER-GUIDE.md +1403 -0
  80. package/docs/ci-setup.md +81 -0
  81. package/docs/codex-setup.md +142 -0
  82. package/docs/components.md +74 -0
  83. package/docs/cursor-setup.md +104 -0
  84. package/docs/events-schema.md +81 -0
  85. package/docs/migration-v3.md +148 -0
  86. package/docs/owner-config-schema.md +154 -0
  87. package/docs/persona-panel.md +433 -0
  88. package/docs/pi-setup.md +115 -0
  89. package/docs/plugin-architecture-v3.md +296 -0
  90. package/docs/pm-skills-marketplace.md +114 -0
  91. package/docs/policy-cache-validation-2026-04-28.md +118 -0
  92. package/docs/rule-authoring.md +316 -0
  93. package/docs/session-config-reference.md +1439 -0
  94. package/docs/session-config-template.md +961 -0
  95. package/docs/vault-docs-architecture.md +297 -0
  96. package/hooks/_lib/lock-bootstrap.mjs +272 -0
  97. package/hooks/_lib/lock-reconcile.mjs +93 -0
  98. package/hooks/_lib/profile-gate.mjs +95 -0
  99. package/hooks/_lib/transcript-history.mjs +211 -0
  100. package/hooks/agent-teams-h3-test.sh +362 -0
  101. package/hooks/config-protection.mjs +0 -0
  102. package/hooks/cwd-change-restore.mjs +131 -0
  103. package/hooks/enforce-commands.mjs +179 -0
  104. package/hooks/enforce-scope.mjs +273 -0
  105. package/hooks/hooks-codex.json +60 -0
  106. package/hooks/hooks-cursor.json +15 -0
  107. package/hooks/hooks-pi.json +115 -0
  108. package/hooks/hooks.json +215 -0
  109. package/hooks/loop-guard.mjs +260 -0
  110. package/hooks/on-session-end.mjs +217 -0
  111. package/hooks/on-session-start.mjs +660 -0
  112. package/hooks/on-stop.mjs +294 -0
  113. package/hooks/operator-steer.mjs +64 -0
  114. package/hooks/post-edit-validate.mjs +225 -0
  115. package/hooks/post-subagent-discovery-validator.mjs +398 -0
  116. package/hooks/post-tool-batch-wave-signal.mjs +328 -0
  117. package/hooks/post-tool-failure-corrective-context.mjs +248 -0
  118. package/hooks/post-tooluse-frontend-slop.mjs +184 -0
  119. package/hooks/pre-bash-destructive-guard.mjs +515 -0
  120. package/hooks/pre-bash-memory-propose-audit.mjs +206 -0
  121. package/hooks/pre-bash-staging-fence.mjs +223 -0
  122. package/hooks/pre-bash-templates-first.mjs +404 -0
  123. package/hooks/run-node.sh +72 -0
  124. package/hooks/skill-invocation-telemetry.mjs +99 -0
  125. package/hooks/subagent-telemetry.mjs +249 -0
  126. package/hooks/wave-scope-commit-guard.mjs +191 -0
  127. package/monitors/monitors.json +14 -0
  128. package/output-styles/finding-report.md +48 -0
  129. package/output-styles/session-report.md +53 -0
  130. package/output-styles/wave-summary.md +38 -0
  131. package/package.json +94 -0
  132. package/pi/extensions/session-orchestrator.ts +25 -0
  133. package/pi/prompts/autopilot-multi.md +12 -0
  134. package/pi/prompts/autopilot.md +12 -0
  135. package/pi/prompts/bootstrap.md +12 -0
  136. package/pi/prompts/brainstorm.md +12 -0
  137. package/pi/prompts/close.md +11 -0
  138. package/pi/prompts/debug.md +12 -0
  139. package/pi/prompts/discovery.md +12 -0
  140. package/pi/prompts/dispatcher.md +12 -0
  141. package/pi/prompts/eval.md +12 -0
  142. package/pi/prompts/evolve.md +12 -0
  143. package/pi/prompts/go.md +12 -0
  144. package/pi/prompts/grill.md +12 -0
  145. package/pi/prompts/harness-audit.md +12 -0
  146. package/pi/prompts/memory-cleanup.md +12 -0
  147. package/pi/prompts/persona-panel.md +12 -0
  148. package/pi/prompts/plan.md +12 -0
  149. package/pi/prompts/portfolio.md +12 -0
  150. package/pi/prompts/reconcile.md +12 -0
  151. package/pi/prompts/repo-audit.md +12 -0
  152. package/pi/prompts/session.md +12 -0
  153. package/pi/prompts/spinout.md +12 -0
  154. package/pi/prompts/sunset-review.md +12 -0
  155. package/pi/prompts/templates-ack.md +12 -0
  156. package/pi/prompts/test.md +12 -0
  157. package/rules/_index.md +51 -0
  158. package/rules/always-on/commit-discipline.md +26 -0
  159. package/rules/always-on/npm-quality-gates.md +26 -0
  160. package/rules/always-on/parallel-sessions.md +43 -0
  161. package/rules/opt-in-domain/prompt-caching.md +270 -0
  162. package/rules/opt-in-stack/backend-data.md +188 -0
  163. package/rules/opt-in-stack/backend.md +390 -0
  164. package/rules/opt-in-stack/frontend.md +98 -0
  165. package/rules/opt-in-stack/security-web.md +194 -0
  166. package/rules/opt-in-stack/swift.md +65 -0
  167. package/scripts/archive-closed-prds.mjs +416 -0
  168. package/scripts/autopilot-multi.mjs +802 -0
  169. package/scripts/autopilot.mjs +383 -0
  170. package/scripts/backfill-abandoned-sessions.mjs +265 -0
  171. package/scripts/backfill-learnings-expires.mjs +196 -0
  172. package/scripts/backfill-learnings.mjs +203 -0
  173. package/scripts/backfill-sessions.mjs +282 -0
  174. package/scripts/check-doc-consistency.sh +279 -0
  175. package/scripts/check-package-manager.mjs +445 -0
  176. package/scripts/ci/assert-vitest-green.mjs +267 -0
  177. package/scripts/codex-install.mjs +435 -0
  178. package/scripts/compute-grounding-injection.sh +186 -0
  179. package/scripts/cursor-install.mjs +113 -0
  180. package/scripts/dialectic-deriver.mjs +573 -0
  181. package/scripts/emit-event.mjs +160 -0
  182. package/scripts/emit-session.mjs +212 -0
  183. package/scripts/eval-session.mjs +262 -0
  184. package/scripts/export-hw-learnings.mjs +437 -0
  185. package/scripts/gc-stale-worktrees.mjs +666 -0
  186. package/scripts/generate-pi-prompts.mjs +127 -0
  187. package/scripts/harness-audit.mjs +287 -0
  188. package/scripts/lib/agent-frontmatter.mjs +266 -0
  189. package/scripts/lib/agent-output-schema.mjs +166 -0
  190. package/scripts/lib/agent-status.mjs +303 -0
  191. package/scripts/lib/ajv-loader.mjs +34 -0
  192. package/scripts/lib/auto-dialectic.mjs +382 -0
  193. package/scripts/lib/auto-dream.mjs +471 -0
  194. package/scripts/lib/autonomy/suitability.mjs +212 -0
  195. package/scripts/lib/autopilot/dep-graph.mjs +417 -0
  196. package/scripts/lib/autopilot/durable-telemetry.mjs +121 -0
  197. package/scripts/lib/autopilot/flags.mjs +104 -0
  198. package/scripts/lib/autopilot/kill-switches.mjs +174 -0
  199. package/scripts/lib/autopilot/loop.mjs +320 -0
  200. package/scripts/lib/autopilot/mr-draft.mjs +520 -0
  201. package/scripts/lib/autopilot/multi-killswitch.mjs +184 -0
  202. package/scripts/lib/autopilot/recent-runs.mjs +106 -0
  203. package/scripts/lib/autopilot/stall-sampler.mjs +97 -0
  204. package/scripts/lib/autopilot/telemetry.mjs +224 -0
  205. package/scripts/lib/autopilot/worktree-pipeline.mjs +605 -0
  206. package/scripts/lib/autopilot-telemetry.mjs +11 -0
  207. package/scripts/lib/autopilot.mjs +39 -0
  208. package/scripts/lib/backlog-scan.mjs +179 -0
  209. package/scripts/lib/bootstrap-lock-freshness.mjs +260 -0
  210. package/scripts/lib/bootstrap-lock-refresh.mjs +186 -0
  211. package/scripts/lib/build-live-signals.mjs +150 -0
  212. package/scripts/lib/ci-status-banner.mjs +425 -0
  213. package/scripts/lib/claude-md-budget-lint.mjs +246 -0
  214. package/scripts/lib/cli-flags.mjs +158 -0
  215. package/scripts/lib/codex/plugin-contract.mjs +610 -0
  216. package/scripts/lib/cold-start-detector.mjs +240 -0
  217. package/scripts/lib/command-blocker.mjs +458 -0
  218. package/scripts/lib/common.mjs +333 -0
  219. package/scripts/lib/config/auto-dream.mjs +77 -0
  220. package/scripts/lib/config/block-header.mjs +94 -0
  221. package/scripts/lib/config/broken-window.mjs +114 -0
  222. package/scripts/lib/config/coercers.mjs +248 -0
  223. package/scripts/lib/config/cold-start.mjs +92 -0
  224. package/scripts/lib/config/config-protection.mjs +120 -0
  225. package/scripts/lib/config/cross-repo.mjs +104 -0
  226. package/scripts/lib/config/custom-phases.mjs +213 -0
  227. package/scripts/lib/config/dialectic.mjs +92 -0
  228. package/scripts/lib/config/discovery-validator.mjs +75 -0
  229. package/scripts/lib/config/dispatcher-autonomy-capture.mjs +240 -0
  230. package/scripts/lib/config/dispatcher-autonomy.mjs +152 -0
  231. package/scripts/lib/config/docs-orchestrator.mjs +90 -0
  232. package/scripts/lib/config/docs-staleness.mjs +96 -0
  233. package/scripts/lib/config/drift-check.mjs +155 -0
  234. package/scripts/lib/config/eval.mjs +130 -0
  235. package/scripts/lib/config/events-rotation.mjs +74 -0
  236. package/scripts/lib/config/evolve.mjs +308 -0
  237. package/scripts/lib/config/frontend-slop-hook.mjs +104 -0
  238. package/scripts/lib/config/gitlab-portfolio.mjs +150 -0
  239. package/scripts/lib/config/handover-gate.mjs +106 -0
  240. package/scripts/lib/config/host-paths.mjs +76 -0
  241. package/scripts/lib/config/io.mjs +54 -0
  242. package/scripts/lib/config/loop-guard.mjs +117 -0
  243. package/scripts/lib/config/memory.mjs +150 -0
  244. package/scripts/lib/config/persona-gate-wave.mjs +258 -0
  245. package/scripts/lib/config/reconcile.mjs +205 -0
  246. package/scripts/lib/config/section-extractor.mjs +100 -0
  247. package/scripts/lib/config/skill-evolution.mjs +112 -0
  248. package/scripts/lib/config/slopcheck.mjs +99 -0
  249. package/scripts/lib/config/state-md-lock.mjs +83 -0
  250. package/scripts/lib/config/templates-first.mjs +94 -0
  251. package/scripts/lib/config/test.mjs +113 -0
  252. package/scripts/lib/config/vault-integration.mjs +201 -0
  253. package/scripts/lib/config/vault-mirror-quality.mjs +99 -0
  254. package/scripts/lib/config/vault-staleness.mjs +84 -0
  255. package/scripts/lib/config/vault-sync.mjs +96 -0
  256. package/scripts/lib/config/verification-auto-fix.mjs +84 -0
  257. package/scripts/lib/config/wave-reviewers.mjs +133 -0
  258. package/scripts/lib/config-schema.mjs +345 -0
  259. package/scripts/lib/config.mjs +474 -0
  260. package/scripts/lib/convergence-monitor.mjs +389 -0
  261. package/scripts/lib/coordinator-snapshot.mjs +371 -0
  262. package/scripts/lib/crypto-digest-utils.mjs +91 -0
  263. package/scripts/lib/discovery/helpers.mjs +127 -0
  264. package/scripts/lib/discovery/triage-state.mjs +279 -0
  265. package/scripts/lib/dispatcher/cli.mjs +257 -0
  266. package/scripts/lib/dispatcher/enumerate.mjs +243 -0
  267. package/scripts/lib/dispatcher/rank.mjs +363 -0
  268. package/scripts/lib/ecosystem-health.mjs +224 -0
  269. package/scripts/lib/ecosystem-wizard/ci-detector.mjs +18 -0
  270. package/scripts/lib/ecosystem-wizard/config-parser.mjs +54 -0
  271. package/scripts/lib/ecosystem-wizard/config-writer.mjs +287 -0
  272. package/scripts/lib/ecosystem-wizard/package-manager-detector.mjs +42 -0
  273. package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +246 -0
  274. package/scripts/lib/ecosystem-wizard.mjs +48 -0
  275. package/scripts/lib/env-check.mjs +89 -0
  276. package/scripts/lib/eval/engine.mjs +605 -0
  277. package/scripts/lib/eval/judge.mjs +433 -0
  278. package/scripts/lib/eval/report.mjs +367 -0
  279. package/scripts/lib/eval/schema.mjs +618 -0
  280. package/scripts/lib/eval/session-resolve.mjs +137 -0
  281. package/scripts/lib/eval/sink.mjs +77 -0
  282. package/scripts/lib/events-rotation.mjs +86 -0
  283. package/scripts/lib/events-schema.mjs +81 -0
  284. package/scripts/lib/events.mjs +80 -0
  285. package/scripts/lib/evolve/autonomy-verdict.mjs +461 -0
  286. package/scripts/lib/evolve/autopilot-effectiveness.mjs +293 -0
  287. package/scripts/lib/exclusivity-matrix.mjs +68 -0
  288. package/scripts/lib/fetch-baseline.mjs +311 -0
  289. package/scripts/lib/file-lock.mjs +512 -0
  290. package/scripts/lib/frontend-detect/detect.mjs +138 -0
  291. package/scripts/lib/frontend-detect/rules.mjs +295 -0
  292. package/scripts/lib/frontmatter-guard.mjs +241 -0
  293. package/scripts/lib/gates/echo-stub-detect.mjs +39 -0
  294. package/scripts/lib/gates/gate-baseline.mjs +42 -0
  295. package/scripts/lib/gates/gate-full.mjs +85 -0
  296. package/scripts/lib/gates/gate-helpers.mjs +231 -0
  297. package/scripts/lib/gates/gate-incremental.mjs +76 -0
  298. package/scripts/lib/gates/gate-per-file.mjs +55 -0
  299. package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +447 -0
  300. package/scripts/lib/gitlab-portfolio/aggregator.mjs +383 -0
  301. package/scripts/lib/gitlab-portfolio/cli.mjs +428 -0
  302. package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +289 -0
  303. package/scripts/lib/gitlab-portfolio/vcs-detect.mjs +182 -0
  304. package/scripts/lib/handover-gate.mjs +222 -0
  305. package/scripts/lib/hardening.mjs +43 -0
  306. package/scripts/lib/hardware-pattern-detector.mjs +238 -0
  307. package/scripts/lib/harness-audit/categories/category1.mjs +123 -0
  308. package/scripts/lib/harness-audit/categories/category2.mjs +145 -0
  309. package/scripts/lib/harness-audit/categories/category3.mjs +143 -0
  310. package/scripts/lib/harness-audit/categories/category4.mjs +202 -0
  311. package/scripts/lib/harness-audit/categories/category5.mjs +152 -0
  312. package/scripts/lib/harness-audit/categories/category6.mjs +211 -0
  313. package/scripts/lib/harness-audit/categories/category7.mjs +125 -0
  314. package/scripts/lib/harness-audit/categories/category8.mjs +328 -0
  315. package/scripts/lib/harness-audit/categories/category9.mjs +294 -0
  316. package/scripts/lib/harness-audit/categories/helpers.mjs +165 -0
  317. package/scripts/lib/harness-audit/categories.mjs +19 -0
  318. package/scripts/lib/historical-guard.mjs +15 -0
  319. package/scripts/lib/host-identity.mjs +262 -0
  320. package/scripts/lib/instruction-budget-guard.mjs +332 -0
  321. package/scripts/lib/io.mjs +304 -0
  322. package/scripts/lib/issue-close-strip-labels.mjs +161 -0
  323. package/scripts/lib/language-mappers/README.md +57 -0
  324. package/scripts/lib/language-mappers/index.mjs +165 -0
  325. package/scripts/lib/language-mappers/markdown.mjs +149 -0
  326. package/scripts/lib/language-mappers/python.mjs +249 -0
  327. package/scripts/lib/language-mappers/swift.mjs +201 -0
  328. package/scripts/lib/language-mappers/typescript.mjs +433 -0
  329. package/scripts/lib/learnings/expiry-sweep.mjs +164 -0
  330. package/scripts/lib/learnings/filters.mjs +43 -0
  331. package/scripts/lib/learnings/io.mjs +255 -0
  332. package/scripts/lib/learnings/schema.mjs +518 -0
  333. package/scripts/lib/learnings/surface.mjs +207 -0
  334. package/scripts/lib/learnings.mjs +42 -0
  335. package/scripts/lib/lock-reaper.mjs +648 -0
  336. package/scripts/lib/locks/index.mjs +31 -0
  337. package/scripts/lib/locks/lock-body.mjs +62 -0
  338. package/scripts/lib/locks/staging-fence-lock.mjs +267 -0
  339. package/scripts/lib/locks/state-md-lock.mjs +351 -0
  340. package/scripts/lib/loop-readiness-banner.mjs +144 -0
  341. package/scripts/lib/memory-banner.mjs +478 -0
  342. package/scripts/lib/memory-cleanup/worktree-sweep.mjs +108 -0
  343. package/scripts/lib/memory-cleanup-stamp.mjs +56 -0
  344. package/scripts/lib/memory-paths.mjs +31 -0
  345. package/scripts/lib/memory-proposals/collector.mjs +334 -0
  346. package/scripts/lib/memory-proposals/schema.mjs +289 -0
  347. package/scripts/lib/memory-proposals/sink.mjs +507 -0
  348. package/scripts/lib/memory-proposals/store.mjs +441 -0
  349. package/scripts/lib/mission-status-schema.mjs +114 -0
  350. package/scripts/lib/mode-selector/alternatives.mjs +64 -0
  351. package/scripts/lib/mode-selector/constants.mjs +29 -0
  352. package/scripts/lib/mode-selector/context-pressure.mjs +157 -0
  353. package/scripts/lib/mode-selector/rationale.mjs +55 -0
  354. package/scripts/lib/mode-selector/scoring.mjs +221 -0
  355. package/scripts/lib/mode-selector-accuracy.mjs +121 -0
  356. package/scripts/lib/mode-selector.mjs +160 -0
  357. package/scripts/lib/multi-provider-build/providers.mjs +64 -0
  358. package/scripts/lib/multi-provider-build/templating.mjs +130 -0
  359. package/scripts/lib/named-baseline-resolver.mjs +233 -0
  360. package/scripts/lib/named-vault-resolver.mjs +433 -0
  361. package/scripts/lib/owner-config/coerce.mjs +29 -0
  362. package/scripts/lib/owner-config/constants.mjs +21 -0
  363. package/scripts/lib/owner-config/defaults.mjs +50 -0
  364. package/scripts/lib/owner-config/error.mjs +19 -0
  365. package/scripts/lib/owner-config/index.mjs +13 -0
  366. package/scripts/lib/owner-config/merge.mjs +52 -0
  367. package/scripts/lib/owner-config/validate.mjs +259 -0
  368. package/scripts/lib/owner-config-banner.mjs +126 -0
  369. package/scripts/lib/owner-config-loader.mjs +159 -0
  370. package/scripts/lib/owner-config.example.yaml +72 -0
  371. package/scripts/lib/owner-config.mjs +28 -0
  372. package/scripts/lib/owner-interview.mjs +243 -0
  373. package/scripts/lib/owner-yaml.mjs +571 -0
  374. package/scripts/lib/package-manager.mjs +160 -0
  375. package/scripts/lib/path-utils.mjs +217 -0
  376. package/scripts/lib/peer-cards/merger.mjs +310 -0
  377. package/scripts/lib/peer-cards/reader.mjs +125 -0
  378. package/scripts/lib/peer-cards/schema.mjs +230 -0
  379. package/scripts/lib/peer-cards/staleness-banner.mjs +86 -0
  380. package/scripts/lib/peer-cards/writer.mjs +138 -0
  381. package/scripts/lib/peer-discovery.mjs +200 -0
  382. package/scripts/lib/persona-panel/catalog-loader.mjs +577 -0
  383. package/scripts/lib/persona-panel/consolidator.mjs +370 -0
  384. package/scripts/lib/persona-panel/persona-runner.mjs +375 -0
  385. package/scripts/lib/persona-panel/threshold.mjs +130 -0
  386. package/scripts/lib/pi-hook-bridge.mjs +328 -0
  387. package/scripts/lib/platform.mjs +266 -0
  388. package/scripts/lib/playwright-driver/runner.mjs +297 -0
  389. package/scripts/lib/plugin-root.mjs +210 -0
  390. package/scripts/lib/pre-dispatch-check.mjs +126 -0
  391. package/scripts/lib/product-repo-detect.mjs +121 -0
  392. package/scripts/lib/profiles/registry.mjs +176 -0
  393. package/scripts/lib/profiles/schema.mjs +209 -0
  394. package/scripts/lib/qg-command-drift-banner.mjs +88 -0
  395. package/scripts/lib/quality-gate/diagnostics.mjs +92 -0
  396. package/scripts/lib/quality-gate.mjs +536 -0
  397. package/scripts/lib/quality-gates-cache.mjs +228 -0
  398. package/scripts/lib/quality-gates-policy.mjs +95 -0
  399. package/scripts/lib/recommendations-v0.mjs +156 -0
  400. package/scripts/lib/reconcile/eligibility.mjs +203 -0
  401. package/scripts/lib/reconcile/emitter.mjs +244 -0
  402. package/scripts/lib/reconcile/engine.mjs +412 -0
  403. package/scripts/lib/reconcile/idempotency.mjs +239 -0
  404. package/scripts/lib/reconcile/renderer.mjs +211 -0
  405. package/scripts/lib/reconcile/writer.mjs +293 -0
  406. package/scripts/lib/reconcile-nudge-banner.mjs +284 -0
  407. package/scripts/lib/resource-probe/evaluate.mjs +190 -0
  408. package/scripts/lib/resource-probe/parsers.mjs +181 -0
  409. package/scripts/lib/resource-probe/probe-platform.mjs +300 -0
  410. package/scripts/lib/resource-probe.mjs +95 -0
  411. package/scripts/lib/rule-loader.mjs +552 -0
  412. package/scripts/lib/rules-sync.mjs +439 -0
  413. package/scripts/lib/scope-gate.mjs +496 -0
  414. package/scripts/lib/session-close-backfill.mjs +539 -0
  415. package/scripts/lib/session-discovery.mjs +256 -0
  416. package/scripts/lib/session-end/phase-skip.mjs +357 -0
  417. package/scripts/lib/session-end/worktree-cleanup.mjs +112 -0
  418. package/scripts/lib/session-id.mjs +362 -0
  419. package/scripts/lib/session-lock.mjs +703 -0
  420. package/scripts/lib/session-registry.mjs +355 -0
  421. package/scripts/lib/session-schema/aliases.mjs +71 -0
  422. package/scripts/lib/session-schema/constants.mjs +115 -0
  423. package/scripts/lib/session-schema/normalizer.mjs +66 -0
  424. package/scripts/lib/session-schema/timestamps.mjs +64 -0
  425. package/scripts/lib/session-schema/validator.mjs +453 -0
  426. package/scripts/lib/session-schema.mjs +71 -0
  427. package/scripts/lib/session-token-rollup.mjs +137 -0
  428. package/scripts/lib/sessions-staleness-banner.mjs +247 -0
  429. package/scripts/lib/skill-evolution/blast-radius-classifier.mjs +114 -0
  430. package/scripts/lib/skill-evolution/candidate-intake.mjs +270 -0
  431. package/scripts/lib/skill-evolution/config-validation-gate.mjs +279 -0
  432. package/scripts/lib/skill-evolution/engine.mjs +719 -0
  433. package/scripts/lib/skill-evolution/idempotency.mjs +279 -0
  434. package/scripts/lib/skill-evolution/mr-opener.mjs +507 -0
  435. package/scripts/lib/skill-health/join.mjs +181 -0
  436. package/scripts/lib/skill-health/score.mjs +123 -0
  437. package/scripts/lib/skill-invocations-schema.mjs +214 -0
  438. package/scripts/lib/skill-judge.mjs +348 -0
  439. package/scripts/lib/skill-judgments-schema.mjs +264 -0
  440. package/scripts/lib/slopcheck.mjs +501 -0
  441. package/scripts/lib/soul-resolve.mjs +118 -0
  442. package/scripts/lib/spiral-carryover.mjs +495 -0
  443. package/scripts/lib/state-md/body-sections.mjs +851 -0
  444. package/scripts/lib/state-md/frontmatter-mutators.mjs +453 -0
  445. package/scripts/lib/state-md/mission-status.mjs +247 -0
  446. package/scripts/lib/state-md/recommendations.mjs +57 -0
  447. package/scripts/lib/state-md/yaml-parser.mjs +234 -0
  448. package/scripts/lib/state-md-peer-guard.mjs +232 -0
  449. package/scripts/lib/state-md.mjs +53 -0
  450. package/scripts/lib/subagents-schema.mjs +309 -0
  451. package/scripts/lib/sunset/walker.mjs +1192 -0
  452. package/scripts/lib/test-runner/artifact-paths.mjs +94 -0
  453. package/scripts/lib/test-runner/fingerprint.mjs +33 -0
  454. package/scripts/lib/test-runner/issue-reconcile.mjs +770 -0
  455. package/scripts/lib/tmux-layout/layouts.mjs +224 -0
  456. package/scripts/lib/tmux-layout/telemetry-stats.mjs +100 -0
  457. package/scripts/lib/tmux-layout/telemetry.mjs +88 -0
  458. package/scripts/lib/tmux-layout/tmux-shell.mjs +82 -0
  459. package/scripts/lib/tmux-layout/vcs-detector.mjs +88 -0
  460. package/scripts/lib/validate/check-agents.mjs +457 -0
  461. package/scripts/lib/validate/check-codex-plugin.mjs +37 -0
  462. package/scripts/lib/validate/check-commands.mjs +148 -0
  463. package/scripts/lib/validate/check-component-paths.mjs +112 -0
  464. package/scripts/lib/validate/check-dead-bridge.mjs +180 -0
  465. package/scripts/lib/validate/check-hooks-symmetry.mjs +258 -0
  466. package/scripts/lib/validate/check-json-files.mjs +116 -0
  467. package/scripts/lib/validate/check-owner-leakage.mjs +1011 -0
  468. package/scripts/lib/validate/check-path-utils-canary.mjs +175 -0
  469. package/scripts/lib/validate/check-peekaboo-driver-canary.mjs +201 -0
  470. package/scripts/lib/validate/check-pi-package.mjs +110 -0
  471. package/scripts/lib/validate/check-pi-prompts.mjs +43 -0
  472. package/scripts/lib/validate/check-playwright-mcp-canary.mjs +154 -0
  473. package/scripts/lib/validate/check-plugin-json.mjs +96 -0
  474. package/scripts/lib/validate/check-plugin-monitors.mjs +206 -0
  475. package/scripts/lib/validate/check-plugin-schema.mjs +137 -0
  476. package/scripts/lib/validate/check-rules.mjs +143 -0
  477. package/scripts/lib/validate/check-session-plan-routing.mjs +154 -0
  478. package/scripts/lib/validate/check-test-fixture-shapes.mjs +280 -0
  479. package/scripts/lib/validate/check-unicode-safety.mjs +533 -0
  480. package/scripts/lib/validate/confidential-names.mjs +169 -0
  481. package/scripts/lib/validate/dead-bridge-corpus.mjs +141 -0
  482. package/scripts/lib/validate/dead-bridge-detectors.mjs +568 -0
  483. package/scripts/lib/validate/tier-inference.mjs +100 -0
  484. package/scripts/lib/validate-vendored-rules.mjs +519 -0
  485. package/scripts/lib/vault-archive.mjs +404 -0
  486. package/scripts/lib/vault-backfill/glab.mjs +164 -0
  487. package/scripts/lib/vault-backfill/manifest.mjs +75 -0
  488. package/scripts/lib/vault-backfill/template.mjs +130 -0
  489. package/scripts/lib/vault-consolidate-fs.mjs +331 -0
  490. package/scripts/lib/vault-migration-rules.mjs +155 -0
  491. package/scripts/lib/vault-mirror/auto-commit.mjs +203 -0
  492. package/scripts/lib/vault-mirror/namespace.mjs +152 -0
  493. package/scripts/lib/vault-mirror/process.mjs +567 -0
  494. package/scripts/lib/vault-mirror/pseudonym-map.mjs +164 -0
  495. package/scripts/lib/vault-mirror/render-learnings.mjs +201 -0
  496. package/scripts/lib/vault-mirror/render-sessions.mjs +367 -0
  497. package/scripts/lib/vault-mirror/render.mjs +8 -0
  498. package/scripts/lib/vault-mirror/utils.mjs +217 -0
  499. package/scripts/lib/vault-relocation-rules.mjs +555 -0
  500. package/scripts/lib/vault-repo-backfill.mjs +235 -0
  501. package/scripts/lib/vault-staleness-banner.mjs +142 -0
  502. package/scripts/lib/vault-status/board-writer.mjs +769 -0
  503. package/scripts/lib/vault-status/narrative-mirror.mjs +544 -0
  504. package/scripts/lib/vault-sync-baseline.mjs +152 -0
  505. package/scripts/lib/wave-context.mjs +29 -0
  506. package/scripts/lib/wave-executor/pool.mjs +248 -0
  507. package/scripts/lib/wave-resource-gate.mjs +204 -0
  508. package/scripts/lib/wave-sizing.mjs +75 -0
  509. package/scripts/lib/webhook-url.mjs +105 -0
  510. package/scripts/lib/workspace.mjs +198 -0
  511. package/scripts/lib/worktree/constants.mjs +35 -0
  512. package/scripts/lib/worktree/index.mjs +17 -0
  513. package/scripts/lib/worktree/lifecycle.mjs +287 -0
  514. package/scripts/lib/worktree/listing.mjs +118 -0
  515. package/scripts/lib/worktree/meta.mjs +64 -0
  516. package/scripts/lib/worktree-freshness.mjs +313 -0
  517. package/scripts/lib/worktree.mjs +15 -0
  518. package/scripts/lifecycle-sim-v6.mjs +347 -0
  519. package/scripts/lock-reaper.mjs +185 -0
  520. package/scripts/mcp-server.sh +241 -0
  521. package/scripts/measure-policy-cache-effectiveness.mjs +427 -0
  522. package/scripts/memory-propose.mjs +464 -0
  523. package/scripts/migrate-cold-start-seed.mjs +404 -0
  524. package/scripts/migrate-learnings-jsonl.mjs +189 -0
  525. package/scripts/migrate-legacy-learnings.sh +61 -0
  526. package/scripts/migrate-sessions-jsonl.mjs +448 -0
  527. package/scripts/migrate-subagents-jsonl.mjs +196 -0
  528. package/scripts/migrate-vault-paths.mjs +796 -0
  529. package/scripts/parse-config.mjs +149 -0
  530. package/scripts/pi-install.mjs +117 -0
  531. package/scripts/print-applicable-rules.mjs +247 -0
  532. package/scripts/promote-vault-strict.mjs +496 -0
  533. package/scripts/relocate-vault-corpus.mjs +1178 -0
  534. package/scripts/run-migrate-v2-cross-repo.mjs +385 -0
  535. package/scripts/run-quality-gate.mjs +216 -0
  536. package/scripts/spikes/h3-agent-teams/preflight.sh +53 -0
  537. package/scripts/spikes/h3-agent-teams/run-h3.sh +112 -0
  538. package/scripts/spikes/h3-agent-teams/setup.sh +137 -0
  539. package/scripts/spikes/h3-agent-teams/toggle.sh +38 -0
  540. package/scripts/sweep-expired-learnings.mjs +135 -0
  541. package/scripts/sync-vault-schema.mjs +376 -0
  542. package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +8 -0
  543. package/scripts/tmux-layout.mjs +245 -0
  544. package/scripts/token-audit.sh +191 -0
  545. package/scripts/typecheck.mjs +42 -0
  546. package/scripts/upload-social-preview.mjs +316 -0
  547. package/scripts/validate-config.mjs +46 -0
  548. package/scripts/validate-plugin-manifests.mjs +163 -0
  549. package/scripts/validate-plugin.mjs +264 -0
  550. package/scripts/validate-wave-scope.mjs +289 -0
  551. package/scripts/vault-backfill.mjs +404 -0
  552. package/scripts/vault-consolidate.mjs +596 -0
  553. package/scripts/vault-integration-watcher.mjs +394 -0
  554. package/scripts/vault-mirror.mjs +430 -0
  555. package/skills/_shared/bootstrap-gate.md +111 -0
  556. package/skills/_shared/config-reading.md +226 -0
  557. package/skills/_shared/instruction-file-resolution.md +79 -0
  558. package/skills/_shared/model-selection.md +64 -0
  559. package/skills/_shared/monitor-patterns.md +300 -0
  560. package/skills/_shared/parallel-aware-auq.md +121 -0
  561. package/skills/_shared/parallel-aware-preamble.md +185 -0
  562. package/skills/_shared/platform-tools.md +96 -0
  563. package/skills/_shared/state-ownership.md +221 -0
  564. package/skills/architecture/DEEPENING.md +37 -0
  565. package/skills/architecture/INTERFACE-DESIGN.md +44 -0
  566. package/skills/architecture/LANGUAGE.md +53 -0
  567. package/skills/architecture/SKILL.md +92 -0
  568. package/skills/autopilot/SKILL.md +419 -0
  569. package/skills/bootstrap/SKILL.md +592 -0
  570. package/skills/bootstrap/STATE.md.template +24 -0
  571. package/skills/bootstrap/_shared-template.md +243 -0
  572. package/skills/bootstrap/deep-template.md +659 -0
  573. package/skills/bootstrap/fast-template.md +251 -0
  574. package/skills/bootstrap/intensity-heuristic.md +80 -0
  575. package/skills/bootstrap/public-fallback.md +342 -0
  576. package/skills/bootstrap/standard-template.md +736 -0
  577. package/skills/bootstrap/templates/agents/project-code-review.md +18 -0
  578. package/skills/bootstrap/templates/agents/project-discovery.md +18 -0
  579. package/skills/bootstrap/templates/agents/project-quality-gate.md +18 -0
  580. package/skills/brainstorm/SKILL.md +268 -0
  581. package/skills/brainstorm/soul.md +49 -0
  582. package/skills/claude-md-drift-check/SKILL.md +186 -0
  583. package/skills/claude-md-drift-check/checker.mjs +1380 -0
  584. package/skills/claude-md-drift-check/checker.sh +37 -0
  585. package/skills/claude-md-drift-check/package.json +16 -0
  586. package/skills/convergence-monitoring/README.md +39 -0
  587. package/skills/convergence-monitoring/SIGNALS.md +246 -0
  588. package/skills/convergence-monitoring/SKILL.md +285 -0
  589. package/skills/daily/SKILL.md +222 -0
  590. package/skills/daily/generate.sh +92 -0
  591. package/skills/daily/templates/daily.md.tpl +36 -0
  592. package/skills/debug/SKILL.md +188 -0
  593. package/skills/debug/soul.md +35 -0
  594. package/skills/discovery/SKILL.md +567 -0
  595. package/skills/discovery/issue-templates.md +237 -0
  596. package/skills/discovery/probes/docs-staleness.mjs +195 -0
  597. package/skills/discovery/probes/frontend-slop.mjs +186 -0
  598. package/skills/discovery/probes/ssot-code-diff.mjs +310 -0
  599. package/skills/discovery/probes/supply-chain-slopcheck.mjs +440 -0
  600. package/skills/discovery/probes/vault-narrative-staleness.mjs +355 -0
  601. package/skills/discovery/probes/vault-staleness.mjs +272 -0
  602. package/skills/discovery/probes-arch.md +252 -0
  603. package/skills/discovery/probes-audit.md +95 -0
  604. package/skills/discovery/probes-code.md +329 -0
  605. package/skills/discovery/probes-docs.md +76 -0
  606. package/skills/discovery/probes-feature.md +150 -0
  607. package/skills/discovery/probes-infra.md +138 -0
  608. package/skills/discovery/probes-intro.md +25 -0
  609. package/skills/discovery/probes-session.md +495 -0
  610. package/skills/discovery/probes-supply-chain.md +94 -0
  611. package/skills/discovery/probes-ui.md +147 -0
  612. package/skills/discovery/probes-vault.md +64 -0
  613. package/skills/discovery/slop-patterns.md +115 -0
  614. package/skills/dispatcher/SKILL.md +173 -0
  615. package/skills/docs-orchestrator/SKILL.md +362 -0
  616. package/skills/docs-orchestrator/audience-mapping.md +140 -0
  617. package/skills/domain-model/ADR-FORMAT.md +47 -0
  618. package/skills/domain-model/CONTEXT-FORMAT.md +77 -0
  619. package/skills/domain-model/SKILL.md +85 -0
  620. package/skills/ecosystem-health/SKILL.md +119 -0
  621. package/skills/ecosystem-health/wizard.md +193 -0
  622. package/skills/eval/SKILL.md +293 -0
  623. package/skills/eval/rubric-v1.md +218 -0
  624. package/skills/evolve/SKILL.md +546 -0
  625. package/skills/frontmatter-guard/SKILL.md +126 -0
  626. package/skills/gitlab-ops/SKILL.md +368 -0
  627. package/skills/gitlab-portfolio/SKILL.md +196 -0
  628. package/skills/grill/SKILL.md +185 -0
  629. package/skills/grill/soul.md +55 -0
  630. package/skills/hook-development/SKILL.md +413 -0
  631. package/skills/mcp-builder/SKILL.md +260 -0
  632. package/skills/memory-cleanup/SKILL.md +310 -0
  633. package/skills/mode-selector/SKILL.md +226 -0
  634. package/skills/peekaboo-driver/SKILL.md +237 -0
  635. package/skills/peekaboo-driver/soul.md +32 -0
  636. package/skills/persona-panel/SKILL.md +365 -0
  637. package/skills/persona-panel/persona-format.md +205 -0
  638. package/skills/persona-panel/presets/designer-lens.md +87 -0
  639. package/skills/persona-panel/presets/engineer-lens.md +88 -0
  640. package/skills/persona-panel/presets/pm-lens.md +86 -0
  641. package/skills/plan/SKILL.md +496 -0
  642. package/skills/plan/mode-feature.md +141 -0
  643. package/skills/plan/mode-new.md +297 -0
  644. package/skills/plan/mode-retro.md +271 -0
  645. package/skills/plan/prd-feature-template.md +132 -0
  646. package/skills/plan/prd-full-template.md +151 -0
  647. package/skills/plan/prd-reviewer-prompt.md +103 -0
  648. package/skills/plan/retro-template.md +75 -0
  649. package/skills/plan/soul.md +62 -0
  650. package/skills/playwright-driver/SKILL.md +226 -0
  651. package/skills/playwright-driver/soul.md +30 -0
  652. package/skills/quality-gates/SKILL.md +212 -0
  653. package/skills/reconcile/SKILL.md +324 -0
  654. package/skills/repo-audit/SKILL.md +272 -0
  655. package/skills/session-end/SKILL.md +1044 -0
  656. package/skills/session-end/discovery-scan.md +37 -0
  657. package/skills/session-end/drift-operations.md +97 -0
  658. package/skills/session-end/learning-patterns.md +78 -0
  659. package/skills/session-end/metrics-collection.md +175 -0
  660. package/skills/session-end/phase-3-2-docs-verification.md +148 -0
  661. package/skills/session-end/phase-3-6-tail.md +344 -0
  662. package/skills/session-end/phase-3-7a-recommendations.md +86 -0
  663. package/skills/session-end/plan-verification.md +288 -0
  664. package/skills/session-end/session-metrics-write.md +223 -0
  665. package/skills/session-end/vault-operations.md +50 -0
  666. package/skills/session-end/verification-checklist.md +20 -0
  667. package/skills/session-plan/SKILL.md +554 -0
  668. package/skills/session-plan/wave-template.md +37 -0
  669. package/skills/session-start/SKILL.md +1043 -0
  670. package/skills/session-start/phase-2-5-docs-planning.md +119 -0
  671. package/skills/session-start/phase-4-5-resource-health.md +49 -0
  672. package/skills/session-start/phase-7-1-premise-check.md +47 -0
  673. package/skills/session-start/phase-7-5-mode-selector.md +237 -0
  674. package/skills/session-start/phase-8-5-express-path.md +61 -0
  675. package/skills/session-start/presentation-format.md +81 -0
  676. package/skills/session-start/soul.md +57 -0
  677. package/skills/skill-creator/SKILL.md +168 -0
  678. package/skills/spinout/SKILL.md +76 -0
  679. package/skills/sunset-review/SKILL.md +96 -0
  680. package/skills/test-runner/SKILL.md +362 -0
  681. package/skills/test-runner/rubric-v1.md +388 -0
  682. package/skills/test-runner/soul.md +46 -0
  683. package/skills/tmux-layout/SKILL.md +104 -0
  684. package/skills/ubiquitous-language/SKILL.md +97 -0
  685. package/skills/using-orchestrator/SKILL.md +144 -0
  686. package/skills/vault-mirror/SKILL.md +234 -0
  687. package/skills/vault-sync/SKILL.md +319 -0
  688. package/skills/vault-sync/package-lock.json +40 -0
  689. package/skills/vault-sync/package.json +11 -0
  690. package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +8 -0
  691. package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
  692. package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +8 -0
  693. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
  694. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +8 -0
  695. package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +8 -0
  696. package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +8 -0
  697. package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +10 -0
  698. package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +8 -0
  699. package/skills/vault-sync/tests/fixtures/clean-vault/README.md +3 -0
  700. package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +11 -0
  701. package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
  702. package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +9 -0
  703. package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +8 -0
  704. package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
  705. package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
  706. package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +7 -0
  707. package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +9 -0
  708. package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
  709. package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +11 -0
  710. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +3 -0
  711. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +3 -0
  712. package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
  713. package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +11 -0
  714. package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
  715. package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +11 -0
  716. package/skills/vault-sync/tests/schema-drift.test.mjs +133 -0
  717. package/skills/vault-sync/validator.mjs +658 -0
  718. package/skills/vault-sync/validator.sh +55 -0
  719. package/skills/wave-executor/SKILL.md +496 -0
  720. package/skills/wave-executor/circuit-breaker.md +169 -0
  721. package/skills/wave-executor/wave-loop.md +1043 -0
  722. package/skills/write-executable-plan/SKILL.md +237 -0
  723. package/skills/write-executable-plan/plan-template.md +154 -0
  724. package/templates/_minimal/CLAUDE.md.tmpl +41 -0
  725. package/templates/_minimal/README.md.tmpl +15 -0
  726. package/templates/_minimal/gitignore.tmpl +47 -0
  727. package/templates/_shared/harte-regeln.md +16 -0
  728. package/templates/_shared/loop.md +90 -0
  729. package/templates/_shared/rules/parallel-sessions.md +77 -0
  730. package/templates/nextjs-minimal/README.md +30 -0
  731. package/templates/nextjs-minimal/app/layout.tsx +18 -0
  732. package/templates/nextjs-minimal/app/page.tsx +7 -0
  733. package/templates/nextjs-minimal/eslint.config.mjs +16 -0
  734. package/templates/nextjs-minimal/next.config.mjs +4 -0
  735. package/templates/nextjs-minimal/package.json +27 -0
  736. package/templates/nextjs-minimal/tsconfig.json +23 -0
  737. package/templates/node-minimal/README.md +33 -0
  738. package/templates/node-minimal/eslint.config.mjs +10 -0
  739. package/templates/node-minimal/package.json +21 -0
  740. package/templates/node-minimal/src/index.ts +1 -0
  741. package/templates/node-minimal/tests/sanity.test.ts +5 -0
  742. package/templates/node-minimal/tsconfig.json +17 -0
  743. package/templates/personas/README.md +150 -0
  744. package/templates/personas/accounting-compliance.v1.md +120 -0
  745. package/templates/personas/accounting-tax-advisor.v1.md +116 -0
  746. package/templates/personas/buyer-p1-cto.v1.md +125 -0
  747. package/templates/personas/buyer-p2-kanzlei.v1.md +134 -0
  748. package/templates/personas/buyer-p3-build.v1.md +130 -0
  749. package/templates/personas/buyer-p4-tech-veto.v1.md +130 -0
  750. package/templates/personas/buyer-p5-solo.v1.md +132 -0
  751. package/templates/personas/buyer-p6-ld.v1.md +130 -0
  752. package/templates/personas/klima-ai-expert.v1.md +114 -0
  753. package/templates/personas/klima-physicist.v1.md +117 -0
  754. package/templates/python-uv/README.md +28 -0
  755. package/templates/python-uv/pyproject.toml +32 -0
  756. package/templates/python-uv/src/__PROJECT_NAME__/__init__.py +0 -0
  757. package/templates/python-uv/src/__PROJECT_NAME__/main.py +6 -0
  758. package/templates/python-uv/tests/test_sanity.py +2 -0
  759. package/templates/static-html/README.md +19 -0
  760. package/templates/static-html/index.html +15 -0
  761. package/templates/static-html/script.js +1 -0
  762. package/templates/static-html/styles.css +26 -0
@@ -0,0 +1,256 @@
1
+ /**
2
+ * session-discovery.mjs — discover active sessions across all worktrees.
3
+ *
4
+ * Purpose: enumerate all active Claude sessions in the repo's worktree set
5
+ * (P1.1 of the Parallel-Aware Sessions Epic #568, Issue #569).
6
+ *
7
+ * Liveness rule (Epic #583, W2-I3 — REPLACES PID-liveness):
8
+ * - A lock is "live" when (now - last_heartbeat) < ttl_hours.
9
+ * - PID-liveness is no longer the discovery-time filter; the writer-process
10
+ * PID is the *hook* PID, not the session PID, so PID-liveness incorrectly
11
+ * filtered out locks whose semantic owner (Claude harness) was still
12
+ * alive (D2 defect from Epic #583 audit).
13
+ * - `isPidAliveOnHost` is preserved in session-lock.mjs as a forensic helper
14
+ * but is not called from the discovery decision tree.
15
+ * - #799 evaluated (2026-07-17): dead-PID stale-marking for source=discovered
16
+ * registry entries is an explicit NO-GO — the recorded PID is the ephemeral
17
+ * hook-subprocess PID (see above), so a same-host dead-PID filter would
18
+ * misclassify nearly every entry as stale seconds after write; even a
19
+ * corroborating PID *label* adds zero detection power over heartbeat
20
+ * freshness (it could only ever annotate entries the heartbeat gate has
21
+ * already excluded). Do not re-attempt without new evidence.
22
+ *
23
+ * Cross-host policy:
24
+ * - Same-host: heartbeat freshness rules.
25
+ * - Cross-host: heartbeat freshness rules (PID-liveness was already skipped
26
+ * across hosts; nothing changes here).
27
+ *
28
+ * Registry fallback (Epic #583, W2-I3 — Merged Source-of-Truth):
29
+ * - When a worktree's lock is null OR not live, the discovery path consults
30
+ * the host registry as a fallback. Entries matching the current repo's
31
+ * `repo_path_hash` and within `freshnessMin` are merged into the result.
32
+ * - Lock takes precedence over registry (more detail per session); registry
33
+ * supplements missing per-worktree entries (e.g., when the hook ran but
34
+ * the prose Phase 1.2 acquire was skipped).
35
+ *
36
+ * Timeout + A1 fallback:
37
+ * - listWorktrees() is raced against DEFAULT_DISCOVERY_TIMEOUT_MS (2 s).
38
+ * - On timeout or throw → falls back to reading only the local session.lock.
39
+ * - Timer uses .unref() so it never keeps the Node event loop alive.
40
+ * - Stderr WARN: `[session-discovery] WARN: <reason> — falling back to single-worktree mode`
41
+ *
42
+ * DI hooks (for tests): opts.listWorktreesImpl, opts.timeoutMs, opts.registryReader.
43
+ */
44
+
45
+ import os from 'node:os';
46
+ import { listWorktrees } from './worktree/listing.mjs';
47
+ import { readLock, isLockLive } from './session-lock.mjs';
48
+ import { readRegistry, repoPathHash, isRegistryEntryFresh } from './session-registry.mjs';
49
+
50
+ // ---------------------------------------------------------------------------
51
+ // Constants
52
+ // ---------------------------------------------------------------------------
53
+
54
+ /** Default timeout in milliseconds for the listWorktrees race. */
55
+ export const DEFAULT_DISCOVERY_TIMEOUT_MS = 2000;
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Private helpers
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /**
62
+ * Convert a lock object + worktree path/branch into the session-shape that
63
+ * discoverActiveSessions returns. Centralised so the in-tree + fallback paths
64
+ * emit identical shapes.
65
+ *
66
+ * @param {object} lock Parsed lock body (schema v2).
67
+ * @param {string} worktreePath Absolute worktree path.
68
+ * @param {string} [branch] Branch from worktree object (falsy → '').
69
+ * @returns {{worktreePath:string,sessionId:string,mode:string,startedAt:string,pid:number,host:string,branch:string}}
70
+ */
71
+ function sessionFromLock(lock, worktreePath, branch = '') {
72
+ return {
73
+ worktreePath,
74
+ sessionId: lock.session_id,
75
+ mode: lock.mode,
76
+ startedAt: lock.started_at,
77
+ pid: lock.pid,
78
+ host: lock.host,
79
+ branch: typeof branch === 'string' ? branch : '',
80
+ };
81
+ }
82
+
83
+ /**
84
+ * Convert a registry entry into the same session-shape. `worktreePath` is set
85
+ * to the repoRoot under which the discovery is running, since the registry
86
+ * does not record per-worktree paths — only repo-path-hashes. Branch is
87
+ * passed through from the registry entry when available.
88
+ *
89
+ * @param {object} entry Registry entry.
90
+ * @param {string} repoRoot Discovery repoRoot (used as worktreePath fallback).
91
+ */
92
+ function sessionFromRegistryEntry(entry, repoRoot) {
93
+ return {
94
+ worktreePath: repoRoot,
95
+ sessionId: entry.session_id,
96
+ mode: typeof entry.mode === 'string' ? entry.mode : 'session',
97
+ startedAt: entry.started_at,
98
+ pid: typeof entry.pid === 'number' ? entry.pid : 0,
99
+ // Registry entries do not currently record `host` (hostname); use the
100
+ // local hostname as the default since registry entries are host-scoped
101
+ // by design (see ~/.config/session-orchestrator/sessions/).
102
+ host: os.hostname(),
103
+ branch: typeof entry.branch === 'string' ? entry.branch : '',
104
+ };
105
+ }
106
+
107
+ /**
108
+ * A1 fallback — read only the local repoRoot's session.lock (0-or-1 result).
109
+ * `branch` is left empty; callers treat it as "unknown — A1 fallback active".
110
+ *
111
+ * Liveness rule: heartbeat freshness via isLockLive (Epic #583, W2-I3).
112
+ *
113
+ * @param {string} repoRoot
114
+ * @returns {Array<{worktreePath:string,sessionId:string,mode:string,startedAt:string,pid:number,host:string,branch:string}>}
115
+ */
116
+ function readLocalSession(repoRoot) {
117
+ const lock = readLock({ repoRoot });
118
+ if (lock === null) return [];
119
+ if (!isLockLive(lock)) return [];
120
+ return [sessionFromLock(lock, repoRoot, '')];
121
+ }
122
+
123
+ /**
124
+ * Deduplicate a session list by sessionId, preferring earlier entries. The
125
+ * discovery path constructs the result with lock-sourced entries first
126
+ * (which carry more detail — exact worktreePath, branch from git) and
127
+ * appends registry-sourced entries; this dedupe keeps the lock-sourced one.
128
+ *
129
+ * @param {Array<{sessionId:string}>} sessions
130
+ * @returns {Array<{sessionId:string}>}
131
+ */
132
+ function dedupeBySessionId(sessions) {
133
+ const seen = new Set();
134
+ const out = [];
135
+ for (const s of sessions) {
136
+ if (seen.has(s.sessionId)) continue;
137
+ seen.add(s.sessionId);
138
+ out.push(s);
139
+ }
140
+ return out;
141
+ }
142
+
143
+ // ---------------------------------------------------------------------------
144
+ // discoverActiveSessions
145
+ // ---------------------------------------------------------------------------
146
+
147
+ /**
148
+ * Discover all active sessions across the repository's worktree set.
149
+ *
150
+ * Liveness rule (Epic #583, W2-I3): heartbeat-based — `isLockLive(lock)`
151
+ * returns true when `(now - last_heartbeat) < ttl_hours`. Replaces the
152
+ * previous PID-liveness rule which incorrectly filtered out locks whose
153
+ * writer-process (hook PID) had exited.
154
+ *
155
+ * Registry fallback: after iterating worktree locks, registry entries with
156
+ * matching `repo_path_hash` that pass `isRegistryEntryFresh()` are merged
157
+ * into the result. Lock entries take precedence (they carry per-worktree
158
+ * detail); registry entries supplement when locks are absent or stale.
159
+ *
160
+ * On listWorktrees() failure or timeout, falls back to A1 single-worktree
161
+ * mode and emits a WARN to stderr.
162
+ *
163
+ * @param {string} repoRoot Absolute path to the main repository root.
164
+ * @param {object} [opts]
165
+ * @param {number} [opts.timeoutMs=2000] Race timeout (ms). Default DEFAULT_DISCOVERY_TIMEOUT_MS.
166
+ * @param {Function} [opts.listWorktreesImpl] DI hook replacing listWorktrees() for tests.
167
+ * @param {Function} [opts.registryReader] DI hook replacing readRegistry() for tests.
168
+ * @param {number} [opts.freshnessMin=15] Registry-entry freshness threshold in minutes.
169
+ * @param {number} [opts.now] ms-since-epoch (test seam for heartbeat freshness).
170
+ * @returns {Promise<Array<{worktreePath:string,sessionId:string,mode:string,startedAt:string,pid:number,host:string,branch:string}>>}
171
+ */
172
+ export async function discoverActiveSessions(repoRoot, opts = {}) {
173
+ const listWorktreesFn = opts.listWorktreesImpl ?? listWorktrees;
174
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_DISCOVERY_TIMEOUT_MS;
175
+ const registryReaderFn = opts.registryReader ?? readRegistry;
176
+ const freshnessMin = typeof opts.freshnessMin === 'number' ? opts.freshnessMin : 15;
177
+ const nowMs = typeof opts.now === 'number' ? opts.now : Date.now();
178
+
179
+ let worktrees;
180
+ try {
181
+ worktrees = await Promise.race([
182
+ listWorktreesFn(),
183
+ new Promise((_, reject) => {
184
+ const timer = setTimeout(() => reject(new Error('timeout')), timeoutMs);
185
+ timer.unref();
186
+ }),
187
+ ]);
188
+ } catch (err) {
189
+ // Either listWorktrees threw, or our timeout fired. Either way: A1 fallback.
190
+ const reason = err.message === 'timeout'
191
+ ? `git worktree list timed out at ${timeoutMs}ms`
192
+ : `git worktree list failed: ${err.message}`;
193
+ process.stderr.write(`[session-discovery] WARN: ${reason} — falling back to single-worktree mode\n`);
194
+ return readLocalSession(repoRoot);
195
+ }
196
+
197
+ const lockSessions = [];
198
+
199
+ for (const worktree of worktrees) {
200
+ // Read the lock for this worktree (returns null if absent or malformed).
201
+ const lock = readLock({ repoRoot: worktree.path });
202
+
203
+ // No lock → no session in this worktree (registry fallback handled below).
204
+ if (lock === null) {
205
+ continue;
206
+ }
207
+
208
+ // Liveness rule (Epic #583, W2-I3): heartbeat freshness, not PID-liveness.
209
+ if (!isLockLive(lock, nowMs)) {
210
+ // Stale by heartbeat — exclude. (Registry fallback may still recover the
211
+ // session id if the registry entry is fresh.)
212
+ continue;
213
+ }
214
+
215
+ lockSessions.push(sessionFromLock(lock, worktree.path, worktree.branch));
216
+ }
217
+
218
+ // Registry fallback (Merged Source-of-Truth, Epic #583, W2-I3).
219
+ // Filter to entries that (a) match this repo's repo_path_hash and (b) pass
220
+ // the freshness gate. Failures are swallowed — registry is advisory.
221
+ let registrySessions;
222
+ try {
223
+ const allEntries = await registryReaderFn();
224
+ const myRepoHash = repoPathHash(repoRoot);
225
+ registrySessions = allEntries
226
+ .filter((e) => e && e.repo_path_hash === myRepoHash)
227
+ .filter((e) => isRegistryEntryFresh(e, { freshnessMin, now: nowMs }))
228
+ .map((e) => sessionFromRegistryEntry(e, repoRoot));
229
+ } catch {
230
+ // Registry read failure → keep going with lock-only results.
231
+ registrySessions = [];
232
+ }
233
+
234
+ // Merge: lock-sourced first (more detail), then registry. Dedupe by
235
+ // sessionId so a session that has both a lock and a registry entry only
236
+ // appears once with the richer lock detail.
237
+ return dedupeBySessionId([...lockSessions, ...registrySessions]);
238
+ }
239
+
240
+ // ---------------------------------------------------------------------------
241
+ // findWorktrees
242
+ // ---------------------------------------------------------------------------
243
+
244
+ /**
245
+ * Thin namespace-cohesion wrapper around listWorktrees().
246
+ *
247
+ * The `repoRoot` parameter is reserved for future per-worktree filtering
248
+ * (Issue #569 P1.2) and is currently passed through without effect.
249
+ *
250
+ * @param {string} _repoRoot Absolute path to the main repository root (reserved).
251
+ * @returns {Promise<Array<{path: string, branch: string, head: string}>>}
252
+ * Same shape as listWorktrees(); empty array on git failure.
253
+ */
254
+ export async function findWorktrees(_repoRoot) {
255
+ return listWorktrees();
256
+ }
@@ -0,0 +1,357 @@
1
+ /**
2
+ * session-end/phase-skip.mjs — Tail-Diät skip-plan aggregator (Issue #724).
3
+ *
4
+ * The session-end Phase 3.6.x tail (3.6.3 Memory-Proposals, 3.6.4 Expired-Sweep,
5
+ * 3.6.5 Auto-Dream, 3.6.6 Skill-Judge, 3.6.7 Auto-Dialectic, 3.6.8 Reconcile) is
6
+ * the close-out abort-attractor: six phases, each ~50 lines of coordinator prose,
7
+ * that in the overwhelming majority of sessions do nothing (no proposals queued,
8
+ * nothing expired, under cadence, judge off, reconcile off). This aggregator
9
+ * computes — side-effect-free — WHICH of the six should actually run, so the
10
+ * coordinator loads only the detail procedure for the `run: true` phases and
11
+ * emits a one-line `skippedReport` for the rest.
12
+ *
13
+ * Every one of the six phases already ships a mechanical fast-path in its own lib
14
+ * (a config kill-switch, an `existsSync` short-circuit, or a cadence/trigger
15
+ * decision). This module WRAPS those existing signals — it never re-implements
16
+ * their logic. Config gates run FIRST as the cheap short-circuit (no disk touch),
17
+ * then the input-detection helpers run only when the config gate passed.
18
+ *
19
+ * Side-effect-free contract:
20
+ * - reads only (existsSync / read helpers); writes NOTHING.
21
+ * - reconcile runs with `dryRun: true` so the candidate sidecar is never written.
22
+ * - the sweep runs with `dryRun: true` (its default) so the store is untouched.
23
+ *
24
+ * Never-throws contract (mirrors the banner-probe posture): a failure while
25
+ * probing a single phase degrades to `run: true` (fail-open) with a
26
+ * `probe-error: …` reason — when in doubt, RUN the phase rather than silently
27
+ * lose it. `planTailPhases` itself never throws to its caller.
28
+ *
29
+ * Plain Node ESM, no external deps — Node 20+ stdlib + the six read-only signal
30
+ * helpers only.
31
+ *
32
+ * @typedef {Object} PhaseDecision
33
+ * @property {string} phase - the phase id, e.g. '3.6.3'.
34
+ * @property {boolean} run - true → coordinator runs the detail procedure.
35
+ * @property {string} reason - human-readable reason for the decision.
36
+ * @property {string} inputSource - which signal drove the decision
37
+ * ('config-gate' | 'proposals.jsonl' | 'sweep-dry-run' | 'auto-dream-signal' |
38
+ * 'skill-invocations.jsonl' | 'auto-dialectic-signal' | 'reconcile-dry-run' |
39
+ * 'learnings.jsonl' | 'probe-error').
40
+ *
41
+ * @typedef {Object} TailPlan
42
+ * @property {PhaseDecision[]} plan
43
+ * @property {string} skippedReport
44
+ */
45
+
46
+ import { existsSync } from 'node:fs';
47
+ import path from 'node:path';
48
+
49
+ import { collectProposals } from '../memory-proposals/collector.mjs';
50
+ import { sweepExpiredLearnings } from '../learnings/expiry-sweep.mjs';
51
+ import { shouldDispatchAutoDream } from '../auto-dream.mjs';
52
+ import { shouldDispatchAutoDialectic } from '../auto-dialectic.mjs';
53
+ import { readSkillInvocations } from '../skill-invocations-schema.mjs';
54
+ import { runReconcile } from '../reconcile/engine.mjs';
55
+ import { resolveMemoryDir } from '../memory-paths.mjs';
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Decision constructors
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /**
62
+ * @param {string} phase
63
+ * @param {boolean} run
64
+ * @param {string} reason
65
+ * @param {string} inputSource
66
+ * @returns {PhaseDecision}
67
+ */
68
+ function decision(phase, run, reason, inputSource) {
69
+ return { phase, run, reason, inputSource };
70
+ }
71
+
72
+ /** Skip decision. */
73
+ function mkSkip(phase, reason, inputSource) {
74
+ return decision(phase, false, reason, inputSource);
75
+ }
76
+
77
+ /** Run decision. */
78
+ function mkRun(phase, reason, inputSource) {
79
+ return decision(phase, true, reason, inputSource);
80
+ }
81
+
82
+ /**
83
+ * Fail-open decision for a probe that threw. Runs the phase (never silently
84
+ * loses it) and stamps a `probe-error: …` reason.
85
+ */
86
+ function mkProbeError(phase, err) {
87
+ const msg = err && err.message ? err.message : String(err);
88
+ return decision(phase, true, `probe-error: ${msg}`, 'probe-error');
89
+ }
90
+
91
+ // ---------------------------------------------------------------------------
92
+ // Config / platform helpers
93
+ // ---------------------------------------------------------------------------
94
+
95
+ /** persistence is off only when explicitly `false`; absent → treated as on. */
96
+ function isPersistenceOff(cfg) {
97
+ return cfg && cfg.persistence === false;
98
+ }
99
+
100
+ /**
101
+ * MEMORY.md (Auto-Dream signal source) lives under `~/.claude/projects/` — a
102
+ * Claude Code-only path. Absent platform → treated as Claude Code (the common
103
+ * coordinator context); any explicit non-Claude platform gates 3.6.5 off.
104
+ */
105
+ function isClaudePlatform(platform) {
106
+ if (platform === undefined || platform === null || platform === '') return true;
107
+ const p = String(platform).toLowerCase();
108
+ return p === 'claude' || p === 'claude-code' || p === 'claudecode';
109
+ }
110
+
111
+ // ---------------------------------------------------------------------------
112
+ // Per-phase deciders — each wraps an EXISTING signal helper, config-gate first.
113
+ // ---------------------------------------------------------------------------
114
+
115
+ /**
116
+ * 3.6.3 Memory-Proposals Collection (#501). Config gate (persistence,
117
+ * memory.proposals.enabled) → then `collectProposals` (existsSync short-circuit
118
+ * on proposals.jsonl → empty queue).
119
+ */
120
+ async function decideMemoryProposals({ repoRoot, cfg }) {
121
+ const phase = '3.6.3';
122
+ try {
123
+ if (isPersistenceOff(cfg)) return mkSkip(phase, 'persistence=false', 'config-gate');
124
+ if (cfg?.memory?.proposals?.enabled === false) {
125
+ return mkSkip(phase, 'memory.proposals.enabled=false', 'config-gate');
126
+ }
127
+ const { queue, stats } = await collectProposals({
128
+ repoRoot,
129
+ minConfidence: cfg?.['auto-dream']?.['min-confidence'],
130
+ });
131
+ if (!Array.isArray(queue) || queue.length === 0) {
132
+ return mkSkip(phase, `proposals empty (queued=${stats?.queued ?? 0})`, 'proposals.jsonl');
133
+ }
134
+ return mkRun(phase, `${queue.length} proposal(s) queued`, 'proposals.jsonl');
135
+ } catch (err) {
136
+ return mkProbeError(phase, err);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * 3.6.4 Expired-Learnings Sweep (Epic #723 B4). No config gate — best-effort,
142
+ * non-blocking. `sweepExpiredLearnings` runs in `dryRun: true` (writes nothing):
143
+ * archived === 0 → nothing to move → skip.
144
+ */
145
+ async function decideExpiredSweep({ repoRoot }) {
146
+ const phase = '3.6.4';
147
+ try {
148
+ const filePath = path.join(repoRoot, '.orchestrator', 'metrics', 'learnings.jsonl');
149
+ if (!existsSync(filePath)) return mkSkip(phase, 'learnings.jsonl absent', 'learnings.jsonl');
150
+ const archivePath = path.join(
151
+ repoRoot,
152
+ '.orchestrator',
153
+ 'metrics',
154
+ 'learnings-archive.jsonl',
155
+ );
156
+ const res = await sweepExpiredLearnings({ filePath, archivePath, dryRun: true });
157
+ if (!res || res.archived === 0) {
158
+ return mkSkip(phase, `nothing archive-eligible (scanned=${res?.scanned ?? 0})`, 'sweep-dry-run');
159
+ }
160
+ const plural = res.archived === 1 ? 'y' : 'ies';
161
+ return mkRun(phase, `${res.archived} entr${plural} archive-eligible`, 'sweep-dry-run');
162
+ } catch (err) {
163
+ return mkProbeError(phase, err);
164
+ }
165
+ }
166
+
167
+ /**
168
+ * 3.6.5 Auto-Dream nudge (#502). Config gate (kill-switch threshold=0, platform)
169
+ * → then `shouldDispatchAutoDream` (trigger:false branches → skip).
170
+ */
171
+ async function decideAutoDream({ repoRoot, cfg, platform, memoryDir }) {
172
+ const phase = '3.6.5';
173
+ try {
174
+ const threshold = cfg?.['memory-cleanup-threshold'] ?? 5;
175
+ if (threshold === 0) {
176
+ return mkSkip(phase, 'kill-switch (memory-cleanup-threshold=0)', 'config-gate');
177
+ }
178
+ if (!isClaudePlatform(platform)) {
179
+ return mkSkip(phase, 'non-Claude-Code platform (memory dir unavailable)', 'config-gate');
180
+ }
181
+ const dir = memoryDir ?? resolveMemoryDir();
182
+ const dec = await shouldDispatchAutoDream({
183
+ repoRoot,
184
+ memoryDir: dir,
185
+ threshold,
186
+ softLimit: cfg?.['memory-cleanup-soft-limit'] ?? 180,
187
+ });
188
+ if (!dec.trigger) return mkSkip(phase, dec.reason, 'auto-dream-signal');
189
+ return mkRun(phase, dec.reason, 'auto-dream-signal');
190
+ } catch (err) {
191
+ return mkProbeError(phase, err);
192
+ }
193
+ }
194
+
195
+ /**
196
+ * 3.6.6 Skill-Applied Judge (#645 L3). Config gate (judge default OFF,
197
+ * persistence) → then the judged-set emptiness check via
198
+ * `readSkillInvocations` (mirrors runSkillJudge's `empty-input` gate: no
199
+ * selected skill this session → nothing to judge → skip). This computes the
200
+ * judged set the coordinator would compute anyway; it does NOT re-implement the
201
+ * judge (runSkillJudge needs a live dispatch, which is not side-effect-free).
202
+ *
203
+ * `sessionId === null/undefined` (noSessionFilter) deliberately falls to the
204
+ * BROADER match — every entry in skill-invocations.jsonl counts toward
205
+ * `judged`, regardless of which session recorded it. This can over-count (a
206
+ * `run: true` decision when the true current-session set would have been
207
+ * empty), which is the fail-open direction: worst case the coordinator loads
208
+ * the 3.6.6 detail procedure for nothing, since the REAL `runSkillJudge` self-
209
+ * gates on its own empty-input check when it actually runs. It never
210
+ * under-counts into a false skip.
211
+ */
212
+ async function decideSkillJudge({ repoRoot, cfg, sessionId }) {
213
+ const phase = '3.6.6';
214
+ try {
215
+ if (cfg?.['skill-evolution']?.judge !== true) {
216
+ return mkSkip(phase, 'disabled (skill-evolution.judge=false)', 'config-gate');
217
+ }
218
+ if (isPersistenceOff(cfg)) return mkSkip(phase, 'persistence=false', 'config-gate');
219
+ const invPath = path.join(repoRoot, '.orchestrator', 'metrics', 'skill-invocations.jsonl');
220
+ const entries = await readSkillInvocations(invPath);
221
+ const noSessionFilter = sessionId === null || sessionId === undefined;
222
+ const judged = new Set(
223
+ entries
224
+ .filter((e) => noSessionFilter || e.session_id === sessionId)
225
+ .map((e) => e.skill)
226
+ .filter((s) => typeof s === 'string' && s.trim().length > 0),
227
+ );
228
+ if (judged.size === 0) {
229
+ return mkSkip(phase, 'empty-input (no selected skills this session)', 'skill-invocations.jsonl');
230
+ }
231
+ return mkRun(phase, `${judged.size} selected skill(s) to judge`, 'skill-invocations.jsonl');
232
+ } catch (err) {
233
+ return mkProbeError(phase, err);
234
+ }
235
+ }
236
+
237
+ /**
238
+ * 3.6.7 Auto-Dialectic nudge (#506). Config gate (persistence, kill-switch
239
+ * cadence=0) → then `shouldDispatchAutoDialectic` (the reference implementation
240
+ * of the no-new-input-since-last-run pattern via `.orchestrator/dialectic-last-run`).
241
+ */
242
+ async function decideAutoDialectic({ repoRoot, cfg }) {
243
+ const phase = '3.6.7';
244
+ try {
245
+ if (isPersistenceOff(cfg)) return mkSkip(phase, 'persistence=false', 'config-gate');
246
+ const cadence = cfg?.dialectic?.cadence ?? 5;
247
+ if (cadence === 0) return mkSkip(phase, 'kill-switch (dialectic.cadence=0)', 'config-gate');
248
+ const dec = await shouldDispatchAutoDialectic({ repoRoot, cadence });
249
+ if (!dec.trigger) return mkSkip(phase, dec.reason, 'auto-dialectic-signal');
250
+ return mkRun(phase, dec.reason, 'auto-dialectic-signal');
251
+ } catch (err) {
252
+ return mkProbeError(phase, err);
253
+ }
254
+ }
255
+
256
+ /**
257
+ * 3.6.8 Reconciliation Rule Proposals (#696). Config gate (persistence,
258
+ * reconcile.enabled default OFF, learnings.jsonl present) → then `runReconcile`
259
+ * with `dryRun: true` (SKIPs the candidate-sidecar merge — no write) and the
260
+ * operator confidence-floor delivery gate. 0 proposals above floor → skip.
261
+ * runReconcile never throws; an engine `error` is treated fail-open (run).
262
+ */
263
+ async function decideReconcile({ repoRoot, cfg }) {
264
+ const phase = '3.6.8';
265
+ try {
266
+ if (isPersistenceOff(cfg)) return mkSkip(phase, 'persistence=false', 'config-gate');
267
+ if (cfg?.reconcile?.enabled !== true) {
268
+ return mkSkip(phase, 'disabled (reconcile.enabled=false)', 'config-gate');
269
+ }
270
+ const learningsPath = path.join(repoRoot, '.orchestrator', 'metrics', 'learnings.jsonl');
271
+ if (!existsSync(learningsPath)) {
272
+ return mkSkip(phase, 'learnings.jsonl absent', 'learnings.jsonl');
273
+ }
274
+ const { proposals, summary, error } = await runReconcile({
275
+ repoRoot,
276
+ ruleExpiryDays: cfg?.reconcile?.['rule-expiry-days'] ?? undefined,
277
+ minRuleDays: cfg?.reconcile?.['min-rule-days'] ?? undefined,
278
+ minInsightChars: cfg?.reconcile?.['min-insight-chars'] ?? undefined,
279
+ now: new Date(),
280
+ dryRun: true, // never write the candidate sidecar from the aggregator
281
+ });
282
+ if (error) return mkProbeError(phase, new Error(error)); // fail-open on engine error
283
+ const floor = cfg?.reconcile?.['confidence-floor'] ?? 0.5;
284
+ const surfaced = (Array.isArray(proposals) ? proposals : []).filter(
285
+ (p) => typeof p.confidence === 'number' && p.confidence >= floor,
286
+ );
287
+ if (surfaced.length === 0) {
288
+ return mkSkip(
289
+ phase,
290
+ `0 proposals above confidence floor (eligible=${summary?.eligible ?? 0}, floor=${floor})`,
291
+ 'reconcile-dry-run',
292
+ );
293
+ }
294
+ return mkRun(phase, `${surfaced.length} proposal(s) above confidence floor`, 'reconcile-dry-run');
295
+ } catch (err) {
296
+ return mkProbeError(phase, err);
297
+ }
298
+ }
299
+
300
+ // ---------------------------------------------------------------------------
301
+ // Report builder
302
+ // ---------------------------------------------------------------------------
303
+
304
+ /**
305
+ * Build the compact one-line skip report from a plan.
306
+ *
307
+ * @param {PhaseDecision[]} plan
308
+ * @returns {string}
309
+ */
310
+ export function buildSkippedReport(plan) {
311
+ const parts = (Array.isArray(plan) ? plan : []).map((d) => {
312
+ const verb = d.run ? 'RUN' : 'skipped';
313
+ return `${d.phase} ${verb} (${d.reason})`;
314
+ });
315
+ return `Tail-Diät: ${parts.join(' · ')}`;
316
+ }
317
+
318
+ // ---------------------------------------------------------------------------
319
+ // Main aggregator
320
+ // ---------------------------------------------------------------------------
321
+
322
+ /**
323
+ * Compute the run/skip plan for the six session-end Phase 3.6.x tail phases.
324
+ *
325
+ * NEVER throws — each phase probe fail-opens to `run: true`, and the top-level
326
+ * guard converts any unexpected error into an all-run plan so the coordinator
327
+ * runs the full tail rather than silently skipping it.
328
+ *
329
+ * @param {object} args
330
+ * @param {string} args.repoRoot Absolute repo root.
331
+ * @param {object} args.config Parsed Session Config object (from parse-config.mjs).
332
+ * @param {string|null} [args.sessionId] Current session id (for the 3.6.6 judged-set filter).
333
+ * @param {string} [args.platform] Platform id ('claude' | 'codex' | 'cursor' | …).
334
+ * @param {string} [args.memoryDir] Optional Auto-Dream memory dir override (default resolveMemoryDir()).
335
+ * @returns {Promise<TailPlan>}
336
+ */
337
+ export async function planTailPhases({ repoRoot, config, sessionId, platform, memoryDir } = {}) {
338
+ const cfg = config ?? {};
339
+ try {
340
+ const plan = await Promise.all([
341
+ decideMemoryProposals({ repoRoot, cfg }),
342
+ decideExpiredSweep({ repoRoot }),
343
+ decideAutoDream({ repoRoot, cfg, platform, memoryDir }),
344
+ decideSkillJudge({ repoRoot, cfg, sessionId }),
345
+ decideAutoDialectic({ repoRoot, cfg }),
346
+ decideReconcile({ repoRoot, cfg }),
347
+ ]);
348
+ return { plan, skippedReport: buildSkippedReport(plan) };
349
+ } catch (err) {
350
+ // Top-level fail-open guard: run the full tail rather than lose it silently.
351
+ const msg = err && err.message ? err.message : String(err);
352
+ const plan = ['3.6.3', '3.6.4', '3.6.5', '3.6.6', '3.6.7', '3.6.8'].map((p) =>
353
+ decision(p, true, `probe-error: ${msg}`, 'probe-error'),
354
+ );
355
+ return { plan, skippedReport: buildSkippedReport(plan) };
356
+ }
357
+ }