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,258 @@
1
+ /**
2
+ * persona-gate-wave.mjs — Parser for the `persona-gate-wave:` Session Config block (#458).
3
+ *
4
+ * Mirrors `wave-reviewers.mjs` pattern: pure parser, no I/O, no side effects.
5
+ * Returns `null` when the block is absent; returns a normalised config object
6
+ * when present. Throws on malformed input (e.g. unparseable threshold).
7
+ *
8
+ * Fields:
9
+ * enabled — boolean (default: false)
10
+ * after — 'quality' | 'impl-polish' (default: 'quality')
11
+ * threshold — string spec parsed via parseThreshold (default: 'all')
12
+ * personas — string[] (each matches SAFE_PERSONA_NAME_RE) (default: [])
13
+ * dispatch-model — model alias or full ID (default: 'claude-opus-4-7')
14
+ * mode — 'off' | 'warn' | 'strict' (default: 'off')
15
+ *
16
+ * Used by skills/wave-executor/wave-loop.md § 3b: Persona-Gate Hook to decide
17
+ * whether to fan out a persona-panel review after a wave completes.
18
+ */
19
+
20
+ import { parseThreshold } from '../persona-panel/threshold.mjs';
21
+ import { ALLOWED_MODEL_ALIASES, MODEL_ID_RE } from '../agent-frontmatter.mjs';
22
+ import { matchBlockHeader } from './block-header.mjs';
23
+
24
+ const ALLOWED_AFTER = new Set(['quality', 'impl-polish']);
25
+ const ALLOWED_MODE = new Set(['off', 'warn', 'strict']);
26
+ const SAFE_PERSONA_NAME_RE = /^[a-z0-9-]{1,64}$/;
27
+
28
+ const DEFAULTS = Object.freeze({
29
+ enabled: false,
30
+ after: 'quality',
31
+ threshold: 'all',
32
+ threshold_parsed: null, // cached ParsedThreshold result; populated by _normalizePersonaGateWave
33
+ personas: [],
34
+ 'dispatch-model': 'claude-opus-4-7',
35
+ mode: 'off',
36
+ });
37
+
38
+ /**
39
+ * Parse the `persona-gate-wave:` YAML block from markdown content.
40
+ *
41
+ * Returns `null` when the block is absent. Returns a normalised config object
42
+ * (with defaults applied) when present. Throws on validation failure so the
43
+ * caller can surface the precise error to the operator.
44
+ *
45
+ * @param {string} content — full CLAUDE.md / AGENTS.md file content
46
+ * @returns {null | {enabled: boolean, after: string, threshold: string, threshold_parsed: {kind: string, m?: number, n?: number}, personas: string[], 'dispatch-model': string, mode: string}}
47
+ */
48
+ export function _parsePersonaGateWave(content) {
49
+ const blockLines = _extractBlock(content, 'persona-gate-wave');
50
+ if (blockLines.length === 0) return null;
51
+
52
+ const parsed = _parseBlockLines(blockLines);
53
+ return _normalizePersonaGateWave(parsed);
54
+ }
55
+
56
+ /**
57
+ * Validate and normalise a parsed config object. Pure function — applies
58
+ * defaults and throws on any field that fails validation.
59
+ *
60
+ * @param {object} parsed — raw parsed object (possibly missing fields)
61
+ * @returns {{enabled: boolean, after: string, threshold: string, threshold_parsed: {kind: string, m?: number, n?: number}, personas: string[], 'dispatch-model': string, mode: string}}
62
+ */
63
+ export function _normalizePersonaGateWave(parsed) {
64
+ const out = { ...DEFAULTS };
65
+
66
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
67
+ throw new Error(
68
+ `persona-gate-wave: expected an object (got ${Array.isArray(parsed) ? 'array' : typeof parsed})`,
69
+ );
70
+ }
71
+
72
+ // enabled
73
+ if (parsed.enabled !== undefined) {
74
+ if (typeof parsed.enabled !== 'boolean') {
75
+ throw new Error(
76
+ `persona-gate-wave.enabled must be a boolean (got ${JSON.stringify(parsed.enabled)})`,
77
+ );
78
+ }
79
+ out.enabled = parsed.enabled;
80
+ }
81
+
82
+ // after
83
+ if (parsed.after !== undefined) {
84
+ if (typeof parsed.after !== 'string' || !ALLOWED_AFTER.has(parsed.after)) {
85
+ throw new Error(
86
+ `persona-gate-wave.after must be one of ${[...ALLOWED_AFTER].map((a) => JSON.stringify(a)).join('|')} (got ${JSON.stringify(parsed.after)})`,
87
+ );
88
+ }
89
+ out.after = parsed.after;
90
+ }
91
+
92
+ // threshold — parsed via parseThreshold (throws InvalidThresholdError on failure)
93
+ if (parsed.threshold !== undefined) {
94
+ if (typeof parsed.threshold !== 'string') {
95
+ throw new Error(
96
+ `persona-gate-wave.threshold must be a string (got ${typeof parsed.threshold})`,
97
+ );
98
+ }
99
+ // parseThreshold throws InvalidThresholdError on bad spec; let it propagate
100
+ // Store the result as threshold_parsed so callers avoid re-parsing at dispatch time.
101
+ out.threshold_parsed = parseThreshold(parsed.threshold);
102
+ out.threshold = parsed.threshold;
103
+ } else {
104
+ // Populate threshold_parsed from the default threshold string so it is always non-null.
105
+ out.threshold_parsed = parseThreshold(DEFAULTS.threshold);
106
+ }
107
+
108
+ // personas — array of strings each matching SAFE_PERSONA_NAME_RE
109
+ if (parsed.personas !== undefined) {
110
+ if (!Array.isArray(parsed.personas)) {
111
+ throw new Error(
112
+ `persona-gate-wave.personas must be an array (got ${typeof parsed.personas})`,
113
+ );
114
+ }
115
+ for (const p of parsed.personas) {
116
+ if (typeof p !== 'string') {
117
+ throw new Error(
118
+ `persona-gate-wave.personas[] entries must be strings (got ${typeof p})`,
119
+ );
120
+ }
121
+ if (!SAFE_PERSONA_NAME_RE.test(p)) {
122
+ throw new Error(
123
+ `persona-gate-wave.personas[] entry ${JSON.stringify(p)} must match ${SAFE_PERSONA_NAME_RE} (lowercase, digits, hyphens, ≤64 chars)`,
124
+ );
125
+ }
126
+ }
127
+ out.personas = [...parsed.personas];
128
+ }
129
+
130
+ // dispatch-model — alias OR full model ID (reuses agent-frontmatter.mjs semantics)
131
+ if (parsed['dispatch-model'] !== undefined) {
132
+ const m = parsed['dispatch-model'];
133
+ if (typeof m !== 'string' || m === '') {
134
+ throw new Error(
135
+ `persona-gate-wave.dispatch-model must be a non-empty string (got ${JSON.stringify(m)})`,
136
+ );
137
+ }
138
+ if (!ALLOWED_MODEL_ALIASES.has(m) && !MODEL_ID_RE.test(m)) {
139
+ throw new Error(
140
+ `persona-gate-wave.dispatch-model must be one of ${[...ALLOWED_MODEL_ALIASES].map((a) => JSON.stringify(a)).join('|')} or a full model ID like "claude-opus-4-7" (got ${JSON.stringify(m)})`,
141
+ );
142
+ }
143
+ out['dispatch-model'] = m;
144
+ }
145
+
146
+ // mode
147
+ if (parsed.mode !== undefined) {
148
+ if (typeof parsed.mode !== 'string' || !ALLOWED_MODE.has(parsed.mode)) {
149
+ throw new Error(
150
+ `persona-gate-wave.mode must be one of ${[...ALLOWED_MODE].map((a) => JSON.stringify(a)).join('|')} (got ${JSON.stringify(parsed.mode)})`,
151
+ );
152
+ }
153
+ out.mode = parsed.mode;
154
+ }
155
+
156
+ return out;
157
+ }
158
+
159
+ // ---------------------------------------------------------------------------
160
+ // Internal helpers — block extraction + line parsing
161
+ // ---------------------------------------------------------------------------
162
+
163
+ /**
164
+ * Extract the indented block lines for a given top-level key from markdown
165
+ * content. Returns an empty array when the key is not present.
166
+ *
167
+ * @param {string} content
168
+ * @param {string} key — e.g. 'persona-gate-wave'
169
+ * @returns {string[]}
170
+ */
171
+ function _extractBlock(content, key) {
172
+ const lines = content.split(/\r?\n/);
173
+ const blockLines = [];
174
+ let inBlock = false;
175
+
176
+ for (const rawLine of lines) {
177
+ const line = rawLine.replace(/\r$/, '');
178
+ if (!inBlock) {
179
+ if (matchBlockHeader(line, key)) {
180
+ inBlock = true;
181
+ }
182
+ continue;
183
+ }
184
+ // Stop at a non-empty line with no leading whitespace (next top-level key)
185
+ if (line.length > 0 && !/^\s/.test(line)) break;
186
+ blockLines.push(line);
187
+ }
188
+
189
+ return blockLines;
190
+ }
191
+
192
+ /**
193
+ * Parse the indented block lines into a raw object (defaults NOT applied here —
194
+ * normalisation happens in _normalizePersonaGateWave).
195
+ *
196
+ * Accepts:
197
+ * - scalars: `enabled: true`, `mode: warn`, `after: quality`
198
+ * - inline arrays: `personas: []`, `personas: [a, b, c]`
199
+ * - quoted strings: `threshold: "5-of-6"` or `threshold: '5-of-6'`
200
+ *
201
+ * @param {string[]} blockLines
202
+ * @returns {object}
203
+ */
204
+ function _parseBlockLines(blockLines) {
205
+ /** @type {Record<string, unknown>} */
206
+ const out = {};
207
+
208
+ for (const rawLine of blockLines) {
209
+ // Strip inline comments + trailing whitespace
210
+ const clean = rawLine.replace(/\s*#.*$/, '').replace(/\s+$/, '');
211
+ if (!clean.trim()) continue;
212
+
213
+ const kvMatch = clean.match(/^\s+([a-zA-Z][a-zA-Z0-9_-]*):\s*(.*)/);
214
+ if (!kvMatch) continue;
215
+
216
+ const k = kvMatch[1];
217
+ let v = kvMatch[2].trim();
218
+
219
+ // Strip surrounding quotes
220
+ if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) v = v.slice(1, -1);
221
+ else if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) v = v.slice(1, -1);
222
+
223
+ switch (k) {
224
+ case 'enabled': {
225
+ const low = v.toLowerCase();
226
+ if (low === 'true') out.enabled = true;
227
+ else if (low === 'false') out.enabled = false;
228
+ else out.enabled = v; // let normaliser raise the precise error
229
+ break;
230
+ }
231
+ case 'after':
232
+ case 'mode':
233
+ case 'threshold':
234
+ case 'dispatch-model':
235
+ out[k] = v;
236
+ break;
237
+ case 'personas': {
238
+ // Inline array notation: [] or [a, b, c]
239
+ const stripped = v.replace(/^\s*\[/, '').replace(/\]\s*$/, '').trim();
240
+ if (stripped === '') {
241
+ out.personas = [];
242
+ } else {
243
+ out.personas = stripped
244
+ .split(',')
245
+ .map((s) => s.trim())
246
+ .filter((s) => s.length > 0);
247
+ }
248
+ break;
249
+ }
250
+ default:
251
+ // Unknown keys are silently ignored — additive-friendly. The
252
+ // normaliser does not check for unknown keys (mirrors wave-reviewers).
253
+ break;
254
+ }
255
+ }
256
+
257
+ return out;
258
+ }
@@ -0,0 +1,205 @@
1
+ import { matchBlockHeader } from './block-header.mjs';
2
+
3
+ /**
4
+ * reconcile.mjs — Parser for the top-level `reconcile:` YAML block.
5
+ *
6
+ * Drives:
7
+ * - FA3 (#696) advisory rule-proposal delivery at session-end Phase 3.6.8.
8
+ * - FA4 (#697) this config foundation: `reconcile.enabled` gates the delivery.
9
+ *
10
+ * Returns:
11
+ * {
12
+ * enabled: boolean,
13
+ * mode: 'warn' | 'off',
14
+ * targets: string[],
15
+ * 'rule-expiry-days': number | null,
16
+ * 'confidence-floor': number,
17
+ * 'min-rule-days': number,
18
+ * 'min-insight-chars': number,
19
+ * }
20
+ *
21
+ * Tolerant parser: malformed values silently fall back to defaults.
22
+ *
23
+ * Consumers: `scripts/lib/config.mjs`, `skills/session-end/SKILL.md` Phase 3.6.8.
24
+ */
25
+
26
+ /**
27
+ * Parse the top-level `reconcile:` YAML block from markdown content.
28
+ *
29
+ * Defaults:
30
+ * reconcile.enabled: false — opt-in (FA3 reads this to gate Phase 3.6.8)
31
+ * reconcile.mode: 'warn' — advisory only; rules NEVER auto-applied,
32
+ * every write is operator-AUQ-gated (enum: off|warn)
33
+ * reconcile.targets: ['repo-local']
34
+ * — where approved rules are written;
35
+ * repo-local = `.claude/rules/` in v1
36
+ * reconcile.rule-expiry-days: null — CRITICAL: must default to null so the
37
+ * reconcile engine (`emitter.mjs`
38
+ * `computeExpiresAt`) falls back to per-type
39
+ * TTL (`deriveExpiresAt`, default 60d).
40
+ * A non-null committed default would silently
41
+ * force flat expiry and change FA2 behaviour.
42
+ * Set to a positive integer to override.
43
+ * reconcile.confidence-floor: 0.5 — float 0.0..1.0; min learning confidence
44
+ * before a learning is eligible for rule proposal
45
+ * reconcile.min-rule-days: 7 — positive integer; floor window (days) applied
46
+ * to a proposed rule's `expires-at` so a near-dead
47
+ * or already-elapsed natural expiry never produces
48
+ * a born-dead rule (issue #741.1). Malformed,
49
+ * absent, or non-positive values fall back to 7.
50
+ * reconcile.min-insight-chars: 24 — integer >= 0; opt-in minimum insight length
51
+ * gating the eligibility placeholder-insight check
52
+ * (issue #741.2). Malformed, absent, or negative
53
+ * values fall back to 24.
54
+ *
55
+ * YAML shape:
56
+ * reconcile:
57
+ * enabled: false
58
+ * mode: warn
59
+ * targets: [repo-local]
60
+ * rule-expiry-days: null # default null — falls back to per-type TTL
61
+ * confidence-floor: 0.5
62
+ * min-rule-days: 7
63
+ * min-insight-chars: 24
64
+ *
65
+ * @param {string} content — full file contents
66
+ * @returns {{
67
+ * enabled: boolean,
68
+ * mode: string,
69
+ * targets: string[],
70
+ * 'rule-expiry-days': number | null,
71
+ * 'confidence-floor': number,
72
+ * 'min-rule-days': number,
73
+ * 'min-insight-chars': number,
74
+ * }}
75
+ */
76
+ export function _parseReconcile(content) {
77
+ const defaults = {
78
+ enabled: false,
79
+ mode: 'warn',
80
+ targets: ['repo-local'],
81
+ 'rule-expiry-days': null,
82
+ 'confidence-floor': 0.5,
83
+ 'min-rule-days': 7,
84
+ 'min-insight-chars': 24,
85
+ };
86
+
87
+ const lines = content.split(/\r?\n/);
88
+ let inBlock = false;
89
+ const blockLines = [];
90
+
91
+ for (const rawLine of lines) {
92
+ const line = rawLine.replace(/\r$/, '');
93
+ if (!inBlock) {
94
+ if (matchBlockHeader(line, 'reconcile')) inBlock = true;
95
+ continue;
96
+ }
97
+ // Stop at next column-0 non-empty line (sibling top-level key or H2 heading)
98
+ if (line.length > 0 && !/^\s/.test(line)) break;
99
+ blockLines.push(line);
100
+ }
101
+
102
+ if (blockLines.length === 0) return defaults;
103
+
104
+ let enabled = false;
105
+ let mode = 'warn';
106
+ let targets = ['repo-local'];
107
+ let ruleExpiryDays = null;
108
+ let confidenceFloor = 0.5;
109
+ let minRuleDays = 7;
110
+ let minInsightChars = 24;
111
+
112
+ for (const rawLine of blockLines) {
113
+ // Strip inline comments and trailing whitespace
114
+ const clean = rawLine.replace(/\s*#.*$/, '').replace(/\s+$/, '');
115
+ if (!clean.trim()) continue;
116
+
117
+ // Parse YAML list value: targets: [repo-local] or targets: [a, b]
118
+ const listMatch = clean.match(/^\s+(targets):\s*\[([^\]]*)\]/);
119
+ if (listMatch) {
120
+ const items = listMatch[2]
121
+ .split(',')
122
+ .map((s) => s.trim())
123
+ .filter(Boolean);
124
+ if (items.length > 0) targets = items;
125
+ continue;
126
+ }
127
+
128
+ const kvMatch = clean.match(/^\s+([a-zA-Z_-]+):\s*(.*)/);
129
+ if (!kvMatch) continue;
130
+
131
+ const k = kvMatch[1];
132
+ let v = kvMatch[2].trim();
133
+
134
+ // Strip surrounding quotes
135
+ if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) v = v.slice(1, -1);
136
+ else if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) v = v.slice(1, -1);
137
+
138
+ switch (k) {
139
+ case 'enabled':
140
+ // Default is false → only flip to true on explicit "true"
141
+ enabled = v.toLowerCase() === 'true';
142
+ break;
143
+
144
+ case 'mode': {
145
+ const VALID_MODES = ['off', 'warn'];
146
+ if (VALID_MODES.includes(v)) mode = v;
147
+ // else: silently fall back to default 'warn'
148
+ break;
149
+ }
150
+
151
+ case 'rule-expiry-days': {
152
+ if (v === 'null' || v === '') {
153
+ ruleExpiryDays = null;
154
+ } else if (/^\d+$/.test(v)) {
155
+ const n = parseInt(v, 10);
156
+ if (n > 0) ruleExpiryDays = n;
157
+ // 0 or negative: silently ignore, keep null
158
+ }
159
+ break;
160
+ }
161
+
162
+ case 'confidence-floor': {
163
+ const f = parseFloat(v);
164
+ if (!isNaN(f) && f >= 0.0 && f <= 1.0) confidenceFloor = f;
165
+ break;
166
+ }
167
+
168
+ case 'min-rule-days': {
169
+ if (/^\d+$/.test(v)) {
170
+ const n = parseInt(v, 10);
171
+ if (n > 0) minRuleDays = n;
172
+ // 0 or negative: silently ignore, keep default 7
173
+ }
174
+ break;
175
+ }
176
+
177
+ case 'min-insight-chars': {
178
+ if (/^\d+$/.test(v)) {
179
+ const n = parseInt(v, 10);
180
+ if (n >= 0) minInsightChars = n;
181
+ // negative (unrepresentable by \d+ anyway) or malformed: keep default 24
182
+ }
183
+ break;
184
+ }
185
+
186
+ // targets inline-list with no brackets (e.g. targets: repo-local) — single value
187
+ case 'targets': {
188
+ if (v && !v.startsWith('[')) {
189
+ targets = [v];
190
+ }
191
+ break;
192
+ }
193
+ }
194
+ }
195
+
196
+ return {
197
+ enabled,
198
+ mode,
199
+ targets,
200
+ 'rule-expiry-days': ruleExpiryDays,
201
+ 'confidence-floor': confidenceFloor,
202
+ 'min-rule-days': minRuleDays,
203
+ 'min-insight-chars': minInsightChars,
204
+ };
205
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * section-extractor.mjs — Extract and parse the ## Session Config KV block.
3
+ *
4
+ * Ported from config-yaml-parser.sh (v2). Used by parseSessionConfig in config.mjs.
5
+ */
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // Section extraction (ported from config-yaml-parser.sh)
9
+ // ---------------------------------------------------------------------------
10
+
11
+ /**
12
+ * Extract the raw ## Session Config block lines from markdown content.
13
+ * - CRLF-tolerant
14
+ * - Skips code fence lines (``` alone on a line)
15
+ * - Strips trailing whitespace from each line
16
+ * @param {string} content
17
+ * @returns {string[]} lines of the Session Config block
18
+ */
19
+ export function _extractConfigSection(content) {
20
+ const lines = content.split(/\r?\n/);
21
+ const result = [];
22
+ let inSection = false;
23
+
24
+ for (const rawLine of lines) {
25
+ const line = rawLine.replace(/\r$/, '');
26
+
27
+ if (line === '## Session Config') {
28
+ inSection = true;
29
+ continue;
30
+ }
31
+
32
+ if (inSection) {
33
+ // Next ## header closes the section
34
+ if (/^## /.test(line)) break;
35
+ // Skip standalone code fences
36
+ if (line.trim() === '```') continue;
37
+ // Strip trailing whitespace and collect
38
+ result.push(line.replace(/\s+$/, ''));
39
+ }
40
+ }
41
+
42
+ return result;
43
+ }
44
+
45
+ /**
46
+ * Parse the key-value pairs from extracted Session Config lines.
47
+ * Supports Format 1: `- **key:** value`
48
+ * Supports Format 2: plain `key: value`
49
+ * Last occurrence of a key wins.
50
+ * @param {string[]} lines
51
+ * @returns {Map<string, string>}
52
+ */
53
+ export function _parseKV(lines) {
54
+ // We accumulate all matches, last-match wins per key
55
+ const allPairs = [];
56
+
57
+ for (const line of lines) {
58
+ if (!line.trim()) continue;
59
+
60
+ let key;
61
+ let value;
62
+
63
+ // Format 1: - **key:** value
64
+ const fmt1 = line.match(/^\s*-\s+\*\*([^*:]+):\*\*\s*(.*)/);
65
+ if (fmt1) {
66
+ key = fmt1[1].trim();
67
+ value = fmt1[2].trim();
68
+ } else {
69
+ // Format 2: key: value — supports both plain "key: value" and
70
+ // YAML list-item form "- key: value" (issue #497). Key starts with
71
+ // letter; rest is alphanum/hyphen/underscore.
72
+ const fmt2 = line.match(/^\s*(?:-\s+)?([a-zA-Z][a-zA-Z0-9_-]+):\s+(.*)/);
73
+ if (fmt2) {
74
+ key = fmt2[1].trim();
75
+ value = fmt2[2].trim();
76
+ } else {
77
+ continue;
78
+ }
79
+ }
80
+
81
+ if (!key) continue;
82
+
83
+ // Strip inline YAML comment (matches block-parser behaviour in _parseVaultSync etc.)
84
+ value = value.replace(/\s+#.*$/, '').trim();
85
+
86
+ // Strip surrounding double quotes from value
87
+ if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) {
88
+ value = value.slice(1, -1);
89
+ }
90
+
91
+ allPairs.push([key, value]);
92
+ }
93
+
94
+ // Last match wins: build the map by iterating in order
95
+ const kv = new Map();
96
+ for (const [k, v] of allPairs) {
97
+ kv.set(k, v);
98
+ }
99
+ return kv;
100
+ }
@@ -0,0 +1,112 @@
1
+ import { matchBlockHeader } from './block-header.mjs';
2
+
3
+ /**
4
+ * skill-evolution.mjs — Parser for the top-level `skill-evolution:` YAML block
5
+ * (Epic #643 Skill Self-Evolution Foundation / issue #646 C1-config).
6
+ *
7
+ * Returns `{ autonomy, "evidence-floor", judge, "judge-budget-tokens" }`.
8
+ * Tolerant parser: malformed values silently fall back to defaults.
9
+ *
10
+ * NOTE: `skill-evolution:` is a DISTINCT sibling block from the pre-existing
11
+ * `evolve:` block. Do not confuse them; this parser only touches the
12
+ * `skill-evolution:` header.
13
+ *
14
+ * Consumers:
15
+ * - `scripts/lib/config.mjs` (wired in Wave 3, reads parsed object)
16
+ * - Skills that implement the self-evolution autonomy gate
17
+ */
18
+
19
+ const ALLOWED_AUTONOMY = ['off', 'advisory', 'autonomous-gated'];
20
+
21
+ /**
22
+ * Parse the top-level `skill-evolution:` YAML block from markdown content.
23
+ * Independent of the `## Session Config` section boundary.
24
+ *
25
+ * Defaults:
26
+ * autonomy: 'off' (enum: off | advisory | autonomous-gated)
27
+ * evidence-floor: 0.5 (float in [0.0, 1.0])
28
+ * judge: false (boolean: on/true → true, else false)
29
+ * judge-budget-tokens: 8000 (integer > 0 — L3 judge per-call input budget, #645)
30
+ *
31
+ * @param {string} content — full file contents
32
+ * @returns {{ autonomy: string, "evidence-floor": number, judge: boolean, "judge-budget-tokens": number }}
33
+ */
34
+ export function _parseSkillEvolution(content) {
35
+ const defaults = {
36
+ autonomy: 'off',
37
+ 'evidence-floor': 0.5,
38
+ judge: false,
39
+ 'judge-budget-tokens': 8000,
40
+ };
41
+
42
+ const lines = content.split(/\r?\n/);
43
+ let inBlock = false;
44
+ const blockLines = [];
45
+
46
+ for (const rawLine of lines) {
47
+ const line = rawLine.replace(/\r$/, '');
48
+ if (!inBlock) {
49
+ if (matchBlockHeader(line, 'skill-evolution')) inBlock = true;
50
+ continue;
51
+ }
52
+ if (line.length > 0 && !/^\s/.test(line)) break;
53
+ blockLines.push(line);
54
+ }
55
+
56
+ if (blockLines.length === 0) return defaults;
57
+
58
+ let autonomy = 'off';
59
+ let evidenceFloor = 0.5;
60
+ let judge = false;
61
+ let judgeBudgetTokens = 8000;
62
+
63
+ for (const rawLine of blockLines) {
64
+ const clean = rawLine.replace(/\s*#.*$/, '').replace(/\s+$/, '');
65
+ if (!clean.trim()) continue;
66
+
67
+ const kvMatch = clean.match(/^\s+([a-zA-Z_-]+):\s*(.*)/);
68
+ if (!kvMatch) continue;
69
+
70
+ const k = kvMatch[1];
71
+ let v = kvMatch[2].trim();
72
+ if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) v = v.slice(1, -1);
73
+ else if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) v = v.slice(1, -1);
74
+
75
+ switch (k) {
76
+ case 'autonomy': {
77
+ const lower = v.toLowerCase();
78
+ if (ALLOWED_AUTONOMY.includes(lower)) autonomy = lower;
79
+ // else: silently fall back to default 'off'
80
+ break;
81
+ }
82
+ case 'evidence-floor': {
83
+ if (/^\d+(\.\d+)?$/.test(v)) {
84
+ const f = parseFloat(v);
85
+ if (Number.isFinite(f) && f >= 0.0 && f <= 1.0) evidenceFloor = f;
86
+ // else: silently fall back to default 0.5
87
+ }
88
+ break;
89
+ }
90
+ case 'judge': {
91
+ const lower = v.toLowerCase();
92
+ judge = lower === 'on' || lower === 'true';
93
+ break;
94
+ }
95
+ case 'judge-budget-tokens': {
96
+ if (/^\d+$/.test(v)) {
97
+ const n = parseInt(v, 10);
98
+ if (Number.isInteger(n) && n > 0) judgeBudgetTokens = n;
99
+ // else: silently fall back to default 8000
100
+ }
101
+ break;
102
+ }
103
+ }
104
+ }
105
+
106
+ return {
107
+ autonomy,
108
+ 'evidence-floor': evidenceFloor,
109
+ judge,
110
+ 'judge-budget-tokens': judgeBudgetTokens,
111
+ };
112
+ }