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,333 @@
1
+ /**
2
+ * common.mjs — Shared I/O utilities for session-orchestrator scripts.
3
+ *
4
+ * Pure ESM, Node stdlib only. Replaces the generic helpers from common.sh.
5
+ *
6
+ * Part of v3.0.0 migration (Epic #124, issue #136).
7
+ * Shell-helper ports added for issue #218.
8
+ */
9
+
10
+ import os from 'node:os';
11
+ import path from 'node:path';
12
+ import crypto from 'node:crypto';
13
+ import { promises as fs, existsSync, statSync } from 'node:fs';
14
+ import { fileURLToPath } from 'node:url';
15
+ import { execSync } from 'node:child_process';
16
+
17
+ // ---------------------------------------------------------------------------
18
+ // Path helpers
19
+ // ---------------------------------------------------------------------------
20
+
21
+ /**
22
+ * Returns a unique temp path (does NOT create the file/directory).
23
+ * @param {string} prefix - non-empty string prepended to the filename
24
+ * @returns {string}
25
+ */
26
+ export function makeTmpPath(prefix) {
27
+ if (typeof prefix !== 'string' || prefix.length === 0) {
28
+ throw new TypeError('makeTmpPath: prefix must be a non-empty string');
29
+ }
30
+ const rand = crypto.randomBytes(4).toString('hex');
31
+ return path.join(os.tmpdir(), `${prefix}-${Date.now()}-${rand}`);
32
+ }
33
+
34
+ /**
35
+ * Expand a leading `~` (home-directory shorthand) to the current user's home
36
+ * directory. Non-`~`-prefixed strings, non-strings, and the empty string pass
37
+ * through unchanged.
38
+ *
39
+ * Canonical shared implementation for vault-dir-consuming call-sites added
40
+ * under Epic #774 (docs Public-Split) — see `scripts/lib/vault-archive.mjs`
41
+ * and `scripts/export-hw-learnings.mjs`. Several pre-existing inline copies
42
+ * of this exact shape (e.g. `scripts/lib/vault-status/board-writer.mjs`,
43
+ * `narrative-mirror.mjs`, `scripts/lib/dispatcher/enumerate.mjs`) are
44
+ * intentionally NOT migrated to this shared helper here — that consolidation
45
+ * is a separate follow-up, not this fix's scope.
46
+ *
47
+ * @param {string} p
48
+ * @returns {string}
49
+ */
50
+ export function expandTilde(p) {
51
+ if (typeof p !== 'string' || p.length === 0) return p;
52
+ if (p === '~') return os.homedir();
53
+ if (p.startsWith('~/')) return path.join(os.homedir(), p.slice(2));
54
+ return p;
55
+ }
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Timestamp helpers
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /** Returns the current time as an ISO 8601 UTC string. */
62
+ export function utcTimestamp() {
63
+ return new Date().toISOString();
64
+ }
65
+
66
+ /** Returns the current Unix time in milliseconds. */
67
+ export function epochMs() {
68
+ return Date.now();
69
+ }
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // JSON file helpers
73
+ // ---------------------------------------------------------------------------
74
+
75
+ /**
76
+ * Reads and parses a JSON file; throws on missing file or parse error.
77
+ * @param {string} filePath
78
+ * @returns {Promise<unknown>}
79
+ */
80
+ export async function readJson(filePath) {
81
+ const raw = await fs.readFile(filePath, 'utf8');
82
+ return JSON.parse(raw);
83
+ }
84
+
85
+ /**
86
+ * Serialises obj as pretty-printed JSON and writes it to filePath,
87
+ * creating any missing parent directories automatically.
88
+ * @param {string} filePath
89
+ * @param {unknown} obj
90
+ * @returns {Promise<void>}
91
+ */
92
+ export async function writeJson(filePath, obj) {
93
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
94
+ await fs.writeFile(filePath, JSON.stringify(obj, null, 2) + '\n', 'utf8');
95
+ }
96
+
97
+ /**
98
+ * Appends obj as a single JSONL line to filePath, creating missing parent
99
+ * directories automatically. Single appendFile call — atomic for lines under
100
+ * PIPE_BUF (4 KiB).
101
+ * @param {string} filePath
102
+ * @param {unknown} obj
103
+ * @returns {Promise<void>}
104
+ */
105
+ export async function appendJsonl(filePath, obj) {
106
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
107
+ await fs.appendFile(filePath, JSON.stringify(obj) + '\n', 'utf8');
108
+ }
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // Shell-helper ports (issue #218) — equivalents of common.sh functions
112
+ // ---------------------------------------------------------------------------
113
+
114
+ /**
115
+ * Print an error message to stderr and exit with code 1.
116
+ * Equivalent to die() in common.sh.
117
+ * @param {string} message
118
+ * @returns {never}
119
+ */
120
+ export function die(message) {
121
+ process.stderr.write(`ERROR: ${message}\n`);
122
+ process.exit(1);
123
+ }
124
+
125
+ /**
126
+ * Print a warning message to stderr (does not exit).
127
+ * Equivalent to warn() in common.sh.
128
+ * @param {string} message
129
+ */
130
+ export function warn(message) {
131
+ process.stderr.write(`WARNING: ${message}\n`);
132
+ }
133
+
134
+ /**
135
+ * Verify that jq is available on PATH.
136
+ * Throws an Error if jq is not found (instead of exiting, so callers can decide).
137
+ * For scripts that want exit-on-failure behaviour, wrap with die():
138
+ * try { requireJq(); } catch (e) { die(e.message); }
139
+ * Equivalent to require_jq() in common.sh.
140
+ * @returns {void}
141
+ * @throws {Error} when jq is not on PATH
142
+ */
143
+ export function requireJq() {
144
+ try {
145
+ execSync('command -v jq', { stdio: 'ignore', shell: true });
146
+ } catch {
147
+ throw new Error('jq is required but not installed. Install via: brew install jq');
148
+ }
149
+ }
150
+
151
+ // ---------------------------------------------------------------------------
152
+ // Internal helpers for project/plugin root detection
153
+ // ---------------------------------------------------------------------------
154
+
155
+ /** Return true when `dir` exists as a directory. */
156
+ function _isDirSync(dir) {
157
+ try { return statSync(dir).isDirectory(); } catch { return false; }
158
+ }
159
+
160
+ /** Return true when `file` exists (file or directory). */
161
+ function _isFileSync(file) {
162
+ return existsSync(file);
163
+ }
164
+
165
+ /**
166
+ * Walk up the directory tree from `startDir` until a directory satisfying
167
+ * `predicate(dir)` is found. Returns the matching directory or null.
168
+ * @param {string} startDir
169
+ * @param {(dir: string) => boolean} predicate
170
+ * @returns {string|null}
171
+ */
172
+ function _walkUpUntil(startDir, predicate) {
173
+ let dir = path.resolve(startDir);
174
+ while (true) {
175
+ if (predicate(dir)) return dir;
176
+ const parent = path.dirname(dir);
177
+ if (parent === dir) break; // reached filesystem root
178
+ dir = parent;
179
+ }
180
+ return null;
181
+ }
182
+
183
+ // ---------------------------------------------------------------------------
184
+ // findProjectRoot
185
+ // ---------------------------------------------------------------------------
186
+
187
+ /**
188
+ * Walk up from `startDir` (defaults to process.cwd()) looking for CLAUDE.md,
189
+ * .claude/, AGENTS.md, .codex/, or .pi/ markers. Returns the found project root, or
190
+ * `startDir` if nothing is found.
191
+ *
192
+ * Respects CLAUDE_PROJECT_DIR, CODEX_PROJECT_DIR, and PI_PROJECT_DIR environment variables as
193
+ * fast-paths (same semantics as common.sh find_project_root).
194
+ *
195
+ * Equivalent to find_project_root() in common.sh.
196
+ *
197
+ * @param {string} [startDir] - directory to start the walk from (default: process.cwd())
198
+ * @returns {string} Absolute path of the project root
199
+ */
200
+ export function findProjectRoot(startDir) {
201
+ const base = startDir ? path.resolve(startDir) : process.cwd();
202
+
203
+ // Fast path: CLAUDE_PROJECT_DIR
204
+ const claudeDir = process.env.CLAUDE_PROJECT_DIR;
205
+ if (claudeDir) {
206
+ if (_isFileSync(path.join(claudeDir, 'CLAUDE.md')) || _isDirSync(path.join(claudeDir, '.claude'))) {
207
+ return claudeDir;
208
+ }
209
+ }
210
+
211
+ // Fast path: CODEX_PROJECT_DIR
212
+ const codexDir = process.env.CODEX_PROJECT_DIR;
213
+ if (codexDir) {
214
+ if (_isFileSync(path.join(codexDir, 'AGENTS.md')) || _isDirSync(path.join(codexDir, '.codex'))) {
215
+ return codexDir;
216
+ }
217
+ }
218
+
219
+ // Fast path: PI_PROJECT_DIR
220
+ const piDir = process.env.PI_PROJECT_DIR;
221
+ if (piDir) {
222
+ if (_isFileSync(path.join(piDir, 'AGENTS.md')) || _isDirSync(path.join(piDir, '.pi'))) {
223
+ return piDir;
224
+ }
225
+ }
226
+
227
+ const found = _walkUpUntil(base, (dir) =>
228
+ _isFileSync(path.join(dir, 'CLAUDE.md')) ||
229
+ _isDirSync(path.join(dir, '.claude')) ||
230
+ _isFileSync(path.join(dir, 'AGENTS.md')) ||
231
+ _isDirSync(path.join(dir, '.codex')) ||
232
+ _isDirSync(path.join(dir, '.pi')),
233
+ );
234
+
235
+ return found ?? base;
236
+ }
237
+
238
+ // ---------------------------------------------------------------------------
239
+ // resolvePluginRoot
240
+ // ---------------------------------------------------------------------------
241
+
242
+ /**
243
+ * Resolve the session-orchestrator plugin root directory.
244
+ *
245
+ * Resolution order (stops at first success):
246
+ * 1. CLAUDE_PLUGIN_ROOT env var
247
+ * 2. CODEX_PLUGIN_ROOT env var
248
+ * 3. PI_PLUGIN_ROOT env var
249
+ * 4. Walk up from import.meta.url of this file looking for plugin.json / skills/ / .codex-plugin/
250
+ * 5. Walk up from process.cwd() looking for the same markers
251
+ *
252
+ * Equivalent to resolve_plugin_root() in common.sh, but throws instead of calling die()
253
+ * so that callers in a non-process context (tests) can catch the error.
254
+ *
255
+ * @param {string} [callerUrl] - import.meta.url of the calling module (optional override for level-3 walk)
256
+ * @returns {string} Absolute path to the plugin root
257
+ * @throws {Error} when all resolution levels fail
258
+ */
259
+ export function resolvePluginRoot(callerUrl) {
260
+ const isPluginDir = (dir) =>
261
+ _isFileSync(path.join(dir, 'plugin.json')) ||
262
+ _isDirSync(path.join(dir, 'skills')) ||
263
+ _isDirSync(path.join(dir, '.codex-plugin'));
264
+
265
+ // Level 1: CLAUDE_PLUGIN_ROOT
266
+ const claudeRoot = process.env.CLAUDE_PLUGIN_ROOT;
267
+ if (claudeRoot && _isDirSync(claudeRoot)) return claudeRoot;
268
+
269
+ // Level 2: CODEX_PLUGIN_ROOT
270
+ const codexRoot = process.env.CODEX_PLUGIN_ROOT;
271
+ if (codexRoot && _isDirSync(codexRoot)) return codexRoot;
272
+
273
+ // Level 3: PI_PLUGIN_ROOT
274
+ const piRoot = process.env.PI_PLUGIN_ROOT;
275
+ if (piRoot && _isDirSync(piRoot)) return piRoot;
276
+
277
+ // Level 4: walk up from caller / this file
278
+ const startFromFile = callerUrl
279
+ ? path.dirname(fileURLToPath(callerUrl))
280
+ : path.dirname(fileURLToPath(import.meta.url));
281
+ const byFile = _walkUpUntil(startFromFile, isPluginDir);
282
+ if (byFile) return byFile;
283
+
284
+ // Level 5: walk up from cwd
285
+ const byCwd = _walkUpUntil(process.cwd(), isPluginDir);
286
+ if (byCwd) return byCwd;
287
+
288
+ throw new Error(
289
+ 'Could not locate plugin root. Set CLAUDE_PLUGIN_ROOT, CODEX_PLUGIN_ROOT, or PI_PLUGIN_ROOT to the plugin directory, ' +
290
+ 'or ensure plugin.json / skills/ exists in an ancestor of the cwd.',
291
+ );
292
+ }
293
+
294
+ // ---------------------------------------------------------------------------
295
+ // resolveInstructionFile (issue #33)
296
+ // ---------------------------------------------------------------------------
297
+
298
+ /**
299
+ * Resolve the canonical project-instruction file at the given repo root.
300
+ *
301
+ * `CLAUDE.md` (Claude Code / Cursor IDE) and `AGENTS.md` (Codex CLI) are
302
+ * transparent aliases. Precedence:
303
+ *
304
+ * 1. `<repoRoot>/CLAUDE.md` exists and is non-empty → kind: 'claude'
305
+ * 2. `<repoRoot>/AGENTS.md` exists and is non-empty → kind: 'agents'
306
+ * 3. otherwise → null (caller decides what to do)
307
+ *
308
+ * Never merge both. Never read both. Pick one.
309
+ *
310
+ * SSOT for the alias rule: `skills/_shared/instruction-file-resolution.md`.
311
+ *
312
+ * @param {string} [repoRoot] - absolute repo root (default: findProjectRoot())
313
+ * @returns {{ path: string, kind: 'claude' | 'agents' } | null}
314
+ */
315
+ export function resolveInstructionFile(repoRoot) {
316
+ const root = repoRoot ?? findProjectRoot();
317
+ if (!root) return null;
318
+ const candidates = [
319
+ { file: 'CLAUDE.md', kind: 'claude' },
320
+ { file: 'AGENTS.md', kind: 'agents' },
321
+ ];
322
+ for (const c of candidates) {
323
+ const p = path.join(root, c.file);
324
+ if (existsSync(p)) {
325
+ try {
326
+ if (statSync(p).size > 0) return { path: p, kind: c.kind };
327
+ } catch {
328
+ // stat failure (race, permissions) — skip this candidate, try next
329
+ }
330
+ }
331
+ }
332
+ return null;
333
+ }
@@ -0,0 +1,77 @@
1
+ import { matchBlockHeader } from './block-header.mjs';
2
+
3
+ /**
4
+ * auto-dream.mjs — Parser for the top-level `auto-dream:` YAML block (issue #566).
5
+ *
6
+ * Returns `{ "min-confidence": float in [0.0, 1.0] }`.
7
+ * Tolerant parser: malformed values silently fall back to defaults.
8
+ *
9
+ * Consumer: `scripts/lib/memory-proposals/collector.mjs` reads the value via
10
+ * Session Config and applies the filter inside `collectProposals()` at
11
+ * session-end Phase 3.6.3 (collect-emit time). This is a SECOND confidence
12
+ * gate above the existing write-time `memory.proposals.confidence-floor`
13
+ * floor enforced by `scripts/memory-propose.mjs`.
14
+ *
15
+ * Structurally mirrors `scripts/lib/config/cold-start.mjs` (single-level
16
+ * nested block, top-level boundary detection). Float-range validation copied
17
+ * verbatim from `scripts/lib/config/vault-mirror-quality.mjs:69-73`.
18
+ */
19
+
20
+ /**
21
+ * Parse the top-level `auto-dream:` YAML block from markdown content.
22
+ * Independent of the `## Session Config` section boundary.
23
+ *
24
+ * Defaults:
25
+ * min-confidence: 0.5 (float in [0.0, 1.0])
26
+ *
27
+ * @param {string} content — full file contents
28
+ * @returns {{ "min-confidence": number }}
29
+ */
30
+ export function _parseAutoDream(content) {
31
+ const defaults = {
32
+ 'min-confidence': 0.5,
33
+ };
34
+
35
+ const lines = content.split(/\r?\n/);
36
+ let inBlock = false;
37
+ const blockLines = [];
38
+
39
+ for (const rawLine of lines) {
40
+ const line = rawLine.replace(/\r$/, '');
41
+ if (!inBlock) {
42
+ if (matchBlockHeader(line, 'auto-dream')) inBlock = true;
43
+ continue;
44
+ }
45
+ if (line.length > 0 && !/^\s/.test(line)) break;
46
+ blockLines.push(line);
47
+ }
48
+
49
+ if (blockLines.length === 0) return defaults;
50
+
51
+ let minConfidence = 0.5;
52
+
53
+ for (const rawLine of blockLines) {
54
+ const clean = rawLine.replace(/\s*#.*$/, '').replace(/\s+$/, '');
55
+ if (!clean.trim()) continue;
56
+
57
+ const kvMatch = clean.match(/^\s+([a-zA-Z_-]+):\s*(.*)/);
58
+ if (!kvMatch) continue;
59
+
60
+ const k = kvMatch[1];
61
+ let v = kvMatch[2].trim();
62
+ if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) v = v.slice(1, -1);
63
+ else if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) v = v.slice(1, -1);
64
+
65
+ if (k === 'min-confidence') {
66
+ // Float-range validation copied verbatim from vault-mirror-quality.mjs:69-73.
67
+ if (/^\d+(\.\d+)?$/.test(v)) {
68
+ const f = parseFloat(v);
69
+ if (Number.isFinite(f) && f >= 0.0 && f <= 1.0) minConfidence = f;
70
+ }
71
+ }
72
+ }
73
+
74
+ return {
75
+ 'min-confidence': minConfidence,
76
+ };
77
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * block-header.mjs — Shared bold-tolerant top-level block-header matcher (#830).
3
+ *
4
+ * Session Config blocks in CLAUDE.md / AGENTS.md may render as a bold-bullet
5
+ * `- **key:**` markdown form rather than a plain `key:` line. Parsers that used
6
+ * the strict `/^<key>:\s*$/` regex silently MISSED the bold form → the block was
7
+ * never entered → all defaults applied with no error surfaced anywhere. #823
8
+ * fixed only vault-integration.mjs; this module generalises the tolerance so
9
+ * every block parser matches the same set of header forms.
10
+ *
11
+ * ZERO IMPORTS by design: tests/lib/config/cycle-guard.test.mjs forbids any
12
+ * scripts/lib/config/*.mjs from importing ../config.mjs. This module keeps a
13
+ * clean leaf with no dependencies at all so every sub-parser can adopt it
14
+ * without any cycle risk.
15
+ *
16
+ * RAW-PARITY constraint (#830 / claude-md-drift-check): the checker imports these
17
+ * parsers directly and feeds RAW file content. Normalisation therefore lives
18
+ * INSIDE the helper each parser calls — never in a preprocessing step in
19
+ * config.mjs — so both the config.mjs path and the direct-import checker path
20
+ * see identical tolerance by construction.
21
+ *
22
+ * LOAD-BEARING semantics — the accepted / rejected form set is a contract:
23
+ * MATCH (top-level block header for `key`), each with optional trailing ws:
24
+ * key: - key: **key:** - **key:**
25
+ * NO MATCH (intentionally):
26
+ * key: value — a header carrying a value is not a block-opener
27
+ * key: # note — inline comment on the header line (the documented
28
+ * custom-phases / eval gotcha stays broken-by-design)
29
+ * ' key:' — indented line (a sub-key of some other block)
30
+ * other-key: — a different key
31
+ *
32
+ * The two `**` markers are independent (`**key:` and `key:**` both match),
33
+ * mirroring the tolerant #823 vault-integration regex.
34
+ */
35
+
36
+ /**
37
+ * Escape regex metacharacters in a literal key so a key like `a.b` or `a+b`
38
+ * is matched literally rather than as a pattern. Defensive: current keys are
39
+ * plain `[a-z-]` slugs (`-` is a literal outside a character class), but the
40
+ * dynamic callers (persona-gate-wave / wave-reviewers) pass a variable `key`.
41
+ *
42
+ * @param {string} s
43
+ * @returns {string}
44
+ */
45
+ function escapeRegExp(s) {
46
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
47
+ }
48
+
49
+ /**
50
+ * Build the single-line block-header regex for a key.
51
+ *
52
+ * Equivalent to: `^(?:-\s+)?(?:\*\*)?<key>:(?:\*\*)?\s*$`. Not multiline — it is
53
+ * tested against one already-split line.
54
+ *
55
+ * @param {string} key
56
+ * @returns {RegExp}
57
+ */
58
+ function blockHeaderRe(key) {
59
+ return new RegExp('^(?:-\\s+)?(?:\\*\\*)?' + escapeRegExp(key) + ':(?:\\*\\*)?\\s*$');
60
+ }
61
+
62
+ /**
63
+ * True when `line` opens the top-level block for `key` — tolerant of the
64
+ * bold-bullet markdown rendering (`- **key:**`). Pure boolean, no side effects.
65
+ *
66
+ * @param {string} line — a single line (callers strip the trailing `\n`; a stray
67
+ * trailing `\r` is tolerated by the `\s*$` tail)
68
+ * @param {string} key — the literal block key (e.g. 'eval', 'broken-window-budget')
69
+ * @returns {boolean}
70
+ */
71
+ export function matchBlockHeader(line, key) {
72
+ if (typeof line !== 'string' || typeof key !== 'string' || key === '') return false;
73
+ return blockHeaderRe(key).test(line);
74
+ }
75
+
76
+ /**
77
+ * Multiline presence variant: true when ANY line of `content` opens the
78
+ * top-level block for `key`. For whole-file PRESENCE guards (e.g.
79
+ * dispatcher-autonomy-capture's `BLOCK_HEADER_RE`). Pure boolean.
80
+ *
81
+ * @param {string} content — full file contents
82
+ * @param {string} key
83
+ * @returns {boolean}
84
+ */
85
+ export function hasBlockHeader(content, key) {
86
+ if (typeof content !== 'string' || content === '' || typeof key !== 'string' || key === '') {
87
+ return false;
88
+ }
89
+ const re = blockHeaderRe(key);
90
+ for (const rawLine of content.split(/\r?\n/)) {
91
+ if (re.test(rawLine)) return true;
92
+ }
93
+ return false;
94
+ }
@@ -0,0 +1,114 @@
1
+ import { matchBlockHeader } from './block-header.mjs';
2
+
3
+ /**
4
+ * broken-window.mjs — Parser for the top-level `broken-window-budget:` YAML block
5
+ * (#730 Epic H / H5 — "Broken-Window Budget").
6
+ *
7
+ * Drives session-end Phase 2.6: a "shipped-but-broken" shipment (Full-Gate PASS
8
+ * with documented exceptions, overridden findings) mechanically files a
9
+ * hard-terminated closure issue + Override-Ratio tracking via events.jsonl.
10
+ *
11
+ * Returns `{ enabled, "due-days" }`.
12
+ * Tolerant parser: malformed values silently fall back to defaults, EXCEPT
13
+ * `due-days` — a malformed, non-positive, or non-integer value emits a stderr
14
+ * WARN before falling back (mirrors the handover-gate `max-open-questions`
15
+ * WARN discipline: a runtime-critical bound deserves a loud fallback).
16
+ *
17
+ * Consumer: `scripts/lib/config.mjs`, `skills/session-end/SKILL.md` Phase 2.6.
18
+ */
19
+
20
+ // Upper bound for due-days (~10 years). Guards against Date#setUTCDate
21
+ // overflowing into an Invalid Date downstream (#794 GAP-4).
22
+ const MAX_DUE_DAYS = 3650;
23
+
24
+ /**
25
+ * Parse the top-level `broken-window-budget:` YAML block from markdown content.
26
+ * Independent of the `## Session Config` section boundary.
27
+ *
28
+ * Defaults:
29
+ * enabled: false (opt-in — the whole Phase 2.6 is silent when disabled)
30
+ * due-days: 7 (integer >= 1 and <= 3650 [~10 years]; the closure issue's hard
31
+ * due-date = today + this). Malformed, non-integer, < 1, or > 3650
32
+ * input falls back to 7 and emits a stderr WARN. The upper bound
33
+ * guards against `Date#setUTCDate` overflowing into an Invalid Date
34
+ * (RangeError on `.toISOString()` downstream in
35
+ * `spiral-carryover.mjs` `computeDueDate` — #794 GAP-4).
36
+ *
37
+ * YAML shape:
38
+ * broken-window-budget:
39
+ * enabled: false
40
+ * due-days: 7
41
+ *
42
+ * @param {string} content — full file contents
43
+ * @returns {{ enabled: boolean, "due-days": number }}
44
+ */
45
+ export function _parseBrokenWindow(content) {
46
+ const defaults = {
47
+ enabled: false,
48
+ 'due-days': 7,
49
+ };
50
+
51
+ const lines = String(content ?? '').split(/\r?\n/);
52
+ let inBlock = false;
53
+ const blockLines = [];
54
+
55
+ for (const rawLine of lines) {
56
+ const line = rawLine.replace(/\r$/, '');
57
+ if (!inBlock) {
58
+ if (matchBlockHeader(line, 'broken-window-budget')) inBlock = true;
59
+ continue;
60
+ }
61
+ // Stop at next column-0 non-empty line (sibling top-level key or H2 heading)
62
+ if (line.length > 0 && !/^\s/.test(line)) break;
63
+ blockLines.push(line);
64
+ }
65
+
66
+ if (blockLines.length === 0) return defaults;
67
+
68
+ let enabled = false;
69
+ let dueDays = 7;
70
+
71
+ for (const rawLine of blockLines) {
72
+ // Strip inline comments and trailing whitespace
73
+ const clean = rawLine.replace(/\s*#.*$/, '').replace(/\s+$/, '');
74
+ if (!clean.trim()) continue;
75
+
76
+ const kvMatch = clean.match(/^\s+([a-zA-Z_-]+):\s*(.*)/);
77
+ if (!kvMatch) continue;
78
+
79
+ const k = kvMatch[1];
80
+ let v = kvMatch[2].trim();
81
+ if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) v = v.slice(1, -1);
82
+ else if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) v = v.slice(1, -1);
83
+
84
+ switch (k) {
85
+ case 'enabled':
86
+ // Default is false → only flip to true on explicit "true"
87
+ enabled = v.toLowerCase() === 'true';
88
+ break;
89
+
90
+ case 'due-days': {
91
+ const parsed = /^\d+$/.test(v) ? parseInt(v, 10) : NaN;
92
+ if (Number.isInteger(parsed) && parsed >= 1 && parsed <= MAX_DUE_DAYS) {
93
+ // Positive integer within bounds (>= 1 — a 0-day due-date is
94
+ // nonsensical for a hard-terminated closure issue; <= MAX_DUE_DAYS —
95
+ // guards against Date overflow downstream, #794 GAP-4).
96
+ dueDays = parsed;
97
+ } else {
98
+ // Malformed (non-numeric, empty), non-integer, < 1, or > MAX_DUE_DAYS
99
+ // — emit a stderr WARN on this fallback path (handover-gate parity).
100
+ process.stderr.write(
101
+ `⚠ broken-window-budget.due-days: '${v}' invalid — falling back to 7\n`
102
+ );
103
+ dueDays = 7;
104
+ }
105
+ break;
106
+ }
107
+ }
108
+ }
109
+
110
+ return {
111
+ enabled,
112
+ 'due-days': dueDays,
113
+ };
114
+ }