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,157 @@
1
+ /**
2
+ * Context-pressure signal computation (#332).
3
+ *
4
+ * Extracted from scripts/lib/mode-selector.mjs (issue #358).
5
+ * Pure function: no I/O, no side effects.
6
+ *
7
+ * Per W1 D3 risk warning, scorer split deferred; only `computeContextPressure`
8
+ * extracted this session.
9
+ */
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Local helpers (inlined — clamp/round2/safeArray are <5 lines each and are
13
+ // also used by the parent mode-selector.mjs; inlining avoids a circular import
14
+ // or a shared-helper re-export).
15
+ // ---------------------------------------------------------------------------
16
+
17
+ /**
18
+ * Clamp a number to [min, max].
19
+ * @param {number} v
20
+ * @param {number} min
21
+ * @param {number} max
22
+ * @returns {number}
23
+ */
24
+ function clamp(v, min, max) {
25
+ return Math.min(max, Math.max(min, v));
26
+ }
27
+
28
+ /**
29
+ * Round to 2 decimal places (avoids floating-point drift in comparisons).
30
+ * @param {number} v
31
+ * @returns {number}
32
+ */
33
+ function round2(v) {
34
+ return Math.round(v * 100) / 100;
35
+ }
36
+
37
+ /**
38
+ * Safely coerce to an array (returns [] for non-arrays, null, undefined).
39
+ * @param {unknown} v
40
+ * @returns {any[]}
41
+ */
42
+ function safeArray(v) {
43
+ return Array.isArray(v) ? v : [];
44
+ }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Regex
48
+ // ---------------------------------------------------------------------------
49
+
50
+ /**
51
+ * Regex for cross-cutting keyword detection in task description text.
52
+ * Matches phrases that indicate large, scope-spanning work.
53
+ */
54
+ const CROSS_CUTTING_PATTERN =
55
+ /across all|every (skill|agent|repo)|repo-?wide|cross-cutting|rename across|massive refactor/i;
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Public API
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /**
62
+ * @typedef {Object} ContextPressureComponents
63
+ * @property {number} scope - Scope component contribution (0.0–0.5).
64
+ * @property {number} keywords - Cross-cutting keyword component contribution (0 or 0.25).
65
+ * @property {number} carryover - Carryover component contribution (0.0–0.25).
66
+ */
67
+
68
+ /**
69
+ * @typedef {Object} ContextPressureResult
70
+ * @property {number} score - Aggregate pressure score 0.0–1.0.
71
+ * @property {ContextPressureComponents} components - Per-component breakdown.
72
+ * @property {'low'|'medium'|'high'} level - Bucketed level from score.
73
+ */
74
+
75
+ /**
76
+ * Compute context-pressure score (0.0–1.0) for the proposed work.
77
+ * High pressure → recommend deferring scope or preferring deep mode over feature.
78
+ *
79
+ * Inputs (read from signals):
80
+ * - signals.topPriorities: number[]|undefined — count used as proxy for scope
81
+ * - signals.recentSessions: array — tail-5 used to derive carryover_ratio from
82
+ * session.effectiveness.carryover / session.effectiveness.planned_issues
83
+ * - signals.taskDescriptionText: string|undefined — joined PRD/issue body for keyword scan
84
+ *
85
+ * Score components (additive, clamped to [0, 1]):
86
+ * - scope: min(0.5, max(0, (priorityCount - 3) / 10))
87
+ * - keywords: +0.25 if CROSS_CUTTING_PATTERN matches taskDescriptionText
88
+ * - carryover: min(0.25, max(0, carryoverRatio - 0.3))
89
+ *
90
+ * Returns level buckets: score < 0.3 → 'low'; 0.3–0.7 → 'medium'; ≥ 0.7 → 'high'.
91
+ *
92
+ * Pure function: no I/O, no side effects. Missing/invalid fields → 0 contribution.
93
+ *
94
+ * @param {object|null|undefined} signals
95
+ * @returns {ContextPressureResult}
96
+ */
97
+ export function computeContextPressure(signals) {
98
+ // --- Scope component ---
99
+ const priorities = safeArray(signals?.topPriorities);
100
+ const priorityCount = priorities.length;
101
+ const scopeComponent = clamp((priorityCount - 3) / 10, 0, 0.5);
102
+
103
+ // --- Cross-cutting keywords component ---
104
+ const text = typeof signals?.taskDescriptionText === 'string' ? signals.taskDescriptionText : '';
105
+ const keywordsComponent = text.length > 0 && CROSS_CUTTING_PATTERN.test(text) ? 0.25 : 0;
106
+
107
+ // --- Carryover component ---
108
+ // Derive carryover ratio from tail-5 recent sessions using
109
+ // effectiveness.carryover / effectiveness.planned_issues (sessions.jsonl schema).
110
+ // Falls back gracefully when fields are absent (contributes 0).
111
+ const recentSessions = safeArray(signals?.recentSessions);
112
+ const last5 = recentSessions.slice(-5);
113
+ let derivedCarryoverRatio = 0;
114
+ if (last5.length > 0) {
115
+ let validCount = 0;
116
+ let ratioSum = 0;
117
+ for (const session of last5) {
118
+ if (session === null || typeof session !== 'object') continue;
119
+ const eff = session.effectiveness;
120
+ if (eff === null || typeof eff !== 'object') continue;
121
+ const carryover =
122
+ typeof eff.carryover === 'number' && !Number.isNaN(eff.carryover) ? eff.carryover : null;
123
+ const planned =
124
+ typeof eff.planned_issues === 'number' &&
125
+ !Number.isNaN(eff.planned_issues) &&
126
+ eff.planned_issues > 0
127
+ ? eff.planned_issues
128
+ : null;
129
+ if (carryover !== null && planned !== null) {
130
+ ratioSum += carryover / planned;
131
+ validCount++;
132
+ }
133
+ }
134
+ if (validCount > 0) {
135
+ derivedCarryoverRatio = ratioSum / validCount;
136
+ }
137
+ }
138
+ const carryoverComponent = clamp(derivedCarryoverRatio - 0.3, 0, 0.25);
139
+
140
+ const score = round2(clamp(scopeComponent + keywordsComponent + carryoverComponent, 0, 1));
141
+
142
+ /** @type {'low'|'medium'|'high'} */
143
+ let level;
144
+ if (score < 0.3) level = 'low';
145
+ else if (score < 0.7) level = 'medium';
146
+ else level = 'high';
147
+
148
+ return {
149
+ score,
150
+ components: {
151
+ scope: round2(scopeComponent),
152
+ keywords: round2(keywordsComponent),
153
+ carryover: round2(carryoverComponent),
154
+ },
155
+ level,
156
+ };
157
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Rationale-string builder for the mode-selector passthrough branch (W1A2 split, issue #358).
3
+ *
4
+ * Exports: buildPassthroughRationale.
5
+ * Imports: constants (leaf). Shared helpers inlined per Option B.
6
+ *
7
+ * Pure function: no I/O, no side effects.
8
+ * 120-char clamp is enforced on every returned string.
9
+ */
10
+
11
+ import { TIER_MODE_MAP } from './constants.mjs';
12
+ import { safeArray, safeBootstrapLock } from './scoring.mjs';
13
+ import { hasActiveSignals } from './alternatives.mjs';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Public API
17
+ // ---------------------------------------------------------------------------
18
+
19
+ /**
20
+ * Build a rationale string for branch 3 (passthrough-weighted) based on the
21
+ * dominant factor. Result is deterministic for the same (mode, signals) pair.
22
+ * Always ≤120 chars.
23
+ *
24
+ * @param {string} mode
25
+ * @param {number} confidence
26
+ * @param {object} signals
27
+ * @returns {string}
28
+ */
29
+ export function buildPassthroughRationale(mode, confidence, signals) {
30
+ const recentSessions = safeArray(signals.recentSessions);
31
+ const last3 = recentSessions.slice(-3);
32
+ const bootstrapLock = safeBootstrapLock(signals);
33
+ const tier = bootstrapLock && typeof bootstrapLock.tier === 'string' ? bootstrapLock.tier : null;
34
+
35
+ const hasTrend = last3.length >= 3 &&
36
+ last3.every((s) => typeof s === 'object' && s !== null && s.session_type === mode);
37
+ const hasTierAlign = tier !== null && TIER_MODE_MAP[tier] === mode;
38
+ const hasSignals = hasActiveSignals(signals);
39
+
40
+ let rationale;
41
+ if (!hasSignals) {
42
+ rationale = 'passthrough of Phase A recommended-mode — stale signals';
43
+ } else if (hasTrend && hasTierAlign) {
44
+ rationale = 'passthrough reinforced by recent-sessions trend + bootstrap tier';
45
+ } else if (hasTrend) {
46
+ rationale = 'passthrough reinforced by recent-sessions trend';
47
+ } else if (hasTierAlign) {
48
+ rationale = `passthrough reinforced by bootstrap tier (${tier})`;
49
+ } else {
50
+ rationale = 'passthrough of Phase A recommended-mode';
51
+ }
52
+
53
+ // Clamp to 120 chars (safety net)
54
+ return rationale.slice(0, 120);
55
+ }
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Mode-scoring logic for the mode-selector heuristic (W1A2 split, issue #358).
3
+ *
4
+ * Exports: computeDelta, scoreMode.
5
+ * Imports: constants (leaf). Shared helpers inlined per Option B (avoids cycle
6
+ * risk; matches context-pressure.mjs precedent).
7
+ *
8
+ * Pure functions: no I/O, no side effects.
9
+ */
10
+
11
+ import { ALL_MODES, TIER_MODE_MAP } from './constants.mjs';
12
+ import { computeContextPressure } from './context-pressure.mjs';
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Non-execution (read-only precursor) modes — PRD §2 Out-of-Scope (line 56),
16
+ // §4 line 244, P2.4 (issue #678).
17
+ //
18
+ // `discovery` (routes to /discovery) and `plan-retro` (routes to /plan) are
19
+ // READ-ONLY precursors. The dispatcher MENU routes to them and the
20
+ // recommendation engine may SUGGEST them, but they must NEVER become a
21
+ // scoring-promoted execution-wave `mode` (the primary that session-start /
22
+ // wave-executor would RUN as a build-and-commit wave).
23
+ //
24
+ // Exported so the mode-selector guardrail (global-max swap) and the dispatcher
25
+ // suggestion surface (recommendations-v0.mjs) share a single source of truth.
26
+ // ---------------------------------------------------------------------------
27
+
28
+ /** @type {ReadonlySet<string>} */
29
+ export const NON_EXECUTION_MODES = Object.freeze(new Set(['discovery', 'plan-retro']));
30
+
31
+ /**
32
+ * True when `mode` is a read-only precursor (discovery / plan-retro) that must
33
+ * never be scoring-promoted into the primary executed `mode`.
34
+ * @param {unknown} mode
35
+ * @returns {boolean}
36
+ */
37
+ export function isNonExecutionMode(mode) {
38
+ return typeof mode === 'string' && NON_EXECUTION_MODES.has(mode);
39
+ }
40
+
41
+ // ---------------------------------------------------------------------------
42
+ // Inlined helpers (clamp, round2, safeArray, safeBootstrapLock)
43
+ // ---------------------------------------------------------------------------
44
+
45
+ /**
46
+ * Clamp a number to [min, max].
47
+ * @param {number} v
48
+ * @param {number} min
49
+ * @param {number} max
50
+ * @returns {number}
51
+ */
52
+ function clamp(v, min, max) {
53
+ return Math.min(max, Math.max(min, v));
54
+ }
55
+
56
+ /**
57
+ * Round to 2 decimal places (avoids floating-point drift in comparisons).
58
+ * @param {number} v
59
+ * @returns {number}
60
+ */
61
+ export function round2(v) {
62
+ return Math.round(v * 100) / 100;
63
+ }
64
+
65
+ /**
66
+ * Safely coerce to an array (returns [] for non-arrays, null, undefined).
67
+ * @param {unknown} v
68
+ * @returns {any[]}
69
+ */
70
+ export function safeArray(v) {
71
+ return Array.isArray(v) ? v : [];
72
+ }
73
+
74
+ /**
75
+ * Return signals.bootstrapLock when it is a non-null object, otherwise null.
76
+ * @param {object} signals
77
+ * @returns {object|null}
78
+ */
79
+ export function safeBootstrapLock(signals) {
80
+ return (signals.bootstrapLock !== null && typeof signals.bootstrapLock === 'object')
81
+ ? signals.bootstrapLock
82
+ : null;
83
+ }
84
+
85
+ // ---------------------------------------------------------------------------
86
+ // Public API
87
+ // ---------------------------------------------------------------------------
88
+
89
+ /**
90
+ * Compute the bonus+penalty score delta for a candidate mode given the
91
+ * provided signals. Returns a number in the range (-0.30, +0.35).
92
+ *
93
+ * @param {string} candidateMode
94
+ * @param {object} signals
95
+ * @returns {number} delta (positive bonuses − negative penalties)
96
+ */
97
+ export function computeDelta(candidateMode, signals) {
98
+ const recentSessions = safeArray(signals.recentSessions);
99
+ const learnings = safeArray(signals.learnings);
100
+ const bootstrapLock = safeBootstrapLock(signals);
101
+
102
+ // --- Recent-sessions trend bonus (max +0.15) ---
103
+ let trendBonus = 0;
104
+ const last3 = recentSessions.slice(-3);
105
+ if (last3.length >= 3) {
106
+ const allMatch = last3.every(
107
+ (s) => typeof s === 'object' && s !== null && s.session_type === candidateMode,
108
+ );
109
+ if (allMatch) {
110
+ const avgCompletion =
111
+ last3.reduce((sum, s) => sum + (typeof s.completion_rate === 'number' ? s.completion_rate : 0), 0) /
112
+ 3;
113
+ trendBonus = avgCompletion >= 0.9 ? 0.15 : 0.075;
114
+ }
115
+ }
116
+
117
+ // --- Bootstrap-tier alignment bonus (max +0.10) ---
118
+ let tierBonus = 0;
119
+ if (bootstrapLock !== null) {
120
+ const tier = typeof bootstrapLock.tier === 'string' ? bootstrapLock.tier : null;
121
+ if (tier !== null && TIER_MODE_MAP[tier] === candidateMode) {
122
+ tierBonus = 0.10;
123
+ }
124
+ }
125
+
126
+ // --- Learnings-hint bonus (max +0.10) ---
127
+ let learningsBonus = 0;
128
+ const HINT_TYPES = new Set(['effective-sizing', 'scope-guidance']);
129
+ const modeKeyword = candidateMode.toLowerCase();
130
+ for (const learning of learnings) {
131
+ if (
132
+ typeof learning === 'object' &&
133
+ learning !== null &&
134
+ typeof learning.type === 'string' &&
135
+ HINT_TYPES.has(learning.type) &&
136
+ typeof learning.subject === 'string' &&
137
+ learning.subject.toLowerCase().includes(modeKeyword)
138
+ ) {
139
+ learningsBonus = Math.min(learningsBonus + 0.05, 0.10);
140
+ }
141
+ }
142
+
143
+ // --- Conflict penalties (max −0.30) ---
144
+ let penalty = 0;
145
+
146
+ // Penalty: recent sessions trend strongly suggests a DIFFERENT mode
147
+ if (last3.length >= 3) {
148
+ const otherModes = ALL_MODES.filter((m) => m !== candidateMode);
149
+ for (const otherMode of otherModes) {
150
+ const allOther = last3.every(
151
+ (s) => typeof s === 'object' && s !== null && s.session_type === otherMode,
152
+ );
153
+ if (allOther) {
154
+ const avgCompletion =
155
+ last3.reduce((sum, s) => sum + (typeof s.completion_rate === 'number' ? s.completion_rate : 0), 0) /
156
+ 3;
157
+ if (avgCompletion >= 0.9) {
158
+ penalty += 0.10;
159
+ break; // only one other dominant mode possible
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ // Penalty: bootstrap tier maps to a different mode than candidateMode
166
+ if (bootstrapLock !== null) {
167
+ const tier = typeof bootstrapLock.tier === 'string' ? bootstrapLock.tier : null;
168
+ if (tier !== null) {
169
+ const alignedMode = TIER_MODE_MAP[tier];
170
+ if (alignedMode !== undefined && alignedMode !== candidateMode) {
171
+ penalty += 0.10;
172
+ }
173
+ }
174
+ }
175
+
176
+ // Penalty: high carryover but not in 'deep' mode
177
+ const carryoverRatio =
178
+ typeof signals.carryoverRatio === 'number' && !Number.isNaN(signals.carryoverRatio)
179
+ ? signals.carryoverRatio
180
+ : null;
181
+ if (carryoverRatio !== null && carryoverRatio >= 0.2 && candidateMode !== 'deep') {
182
+ penalty += 0.10;
183
+ }
184
+
185
+ // --- Context-pressure modulation (#332) ---
186
+ // Pure additive delta on top of existing signal modulation.
187
+ // Only applies when at least one context-pressure input is explicitly present.
188
+ // When all inputs are absent, pressure is undefined → treat as neutral (no adjustment).
189
+ // This preserves backward-compatibility for callers that do not yet supply the new fields.
190
+ const hasPressureInputs =
191
+ (signals.topPriorities !== null && signals.topPriorities !== undefined) ||
192
+ (typeof signals.taskDescriptionText === 'string' && signals.taskDescriptionText.length > 0) ||
193
+ safeArray(signals.recentSessions).some(
194
+ (s) => s !== null && typeof s === 'object' && typeof s.effectiveness === 'object' && s.effectiveness !== null,
195
+ );
196
+
197
+ let pressureDelta = 0;
198
+ if (hasPressureInputs) {
199
+ const pressure = computeContextPressure(signals);
200
+ if (pressure.level === 'high') {
201
+ if (candidateMode === 'feature') pressureDelta = -0.15;
202
+ else if (candidateMode === 'housekeeping') pressureDelta = -0.10;
203
+ } else if (pressure.level === 'low') {
204
+ if (candidateMode === 'feature') pressureDelta = +0.05;
205
+ }
206
+ // level === 'medium': no adjustment
207
+ }
208
+
209
+ return trendBonus + tierBonus + learningsBonus - penalty + pressureDelta;
210
+ }
211
+
212
+ /**
213
+ * Score a candidate mode: base 0.5 + delta, clamped to [0.0, 0.9].
214
+ *
215
+ * @param {string} candidateMode
216
+ * @param {object} signals
217
+ * @returns {number}
218
+ */
219
+ export function scoreMode(candidateMode, signals) {
220
+ return round2(clamp(0.5 + computeDelta(candidateMode, signals), 0.0, 0.9));
221
+ }
@@ -0,0 +1,121 @@
1
+ /**
2
+ * mode-selector-accuracy.mjs — Mode-Selector feedback-loop helper (Phase B-4, issue #294).
3
+ *
4
+ * After session-start renders a Mode-Selector recommendation and the user
5
+ * confirms or overrides it, call `recordAccuracy({recommended, chosen, sessionId})`
6
+ * to append a `mode-selector-accuracy` learning to the project's learnings.jsonl.
7
+ *
8
+ * Lifecycle (handled by skills/evolve + skills/session-end on subsequent reads,
9
+ * NOT by this helper):
10
+ * - Same (type, subject) seen again → +0.15 confidence (confirmed)
11
+ * - Contradicted by new evidence → -0.20 confidence
12
+ *
13
+ * Subject pattern encodes the outcome class:
14
+ * `<recommended>-selected-vs-<chosen>`
15
+ *
16
+ * Examples:
17
+ * recommended=feature, chosen=feature → "feature-selected-vs-feature" (agreement)
18
+ * recommended=feature, chosen=deep → "feature-selected-vs-deep" (override)
19
+ *
20
+ * Same-pair recurrence in future sessions hits the dedupe path in evolve and
21
+ * confirms; novel pairs land at confidence 0.5 and accumulate from there.
22
+ *
23
+ * AC contract (from issue #294):
24
+ * - Learning written only when user actively chooses (caller decides).
25
+ * - Confidence starts at 0.5 (initial value; lifecycle handles increment/decrement).
26
+ * - No-op when `recommended` is null/undefined (selector did not render a banner).
27
+ *
28
+ * The helper is a thin wrapper around `appendLearning` from `learnings.mjs`. It
29
+ * never throws on validation issues — those bubble back to the caller as a
30
+ * resolved-error return value (`{ok: false, reason}`) so session-start can
31
+ * log to sweep.log without halting the session.
32
+ */
33
+
34
+ import { appendLearning } from './learnings.mjs';
35
+ import { isValidMode } from './recommendations-v0.mjs';
36
+
37
+ export const LEARNING_TYPE = 'mode-selector-accuracy';
38
+ export const INITIAL_CONFIDENCE = 0.5;
39
+ export const DEFAULT_EXPIRY_DAYS = 30;
40
+
41
+ /**
42
+ * Build the canonical subject string for a (recommended, chosen) pair.
43
+ * @param {string} recommended
44
+ * @param {string} chosen
45
+ * @returns {string}
46
+ */
47
+ export function buildSubject(recommended, chosen) {
48
+ return `${recommended}-selected-vs-${chosen}`;
49
+ }
50
+
51
+ /**
52
+ * Record a Mode-Selector accuracy learning.
53
+ *
54
+ * @param {{
55
+ * recommended: string|null,
56
+ * chosen: string,
57
+ * sessionId: string,
58
+ * filePath?: string,
59
+ * nowMs?: number,
60
+ * expiryDays?: number,
61
+ * confidence?: number,
62
+ * }} opts
63
+ * @returns {Promise<{ok: true, entry: object} | {ok: false, reason: string}>}
64
+ */
65
+ export async function recordAccuracy(opts) {
66
+ const recommended = opts?.recommended;
67
+ const chosen = opts?.chosen;
68
+ const sessionId = opts?.sessionId;
69
+ const filePath = opts?.filePath || '.orchestrator/metrics/learnings.jsonl';
70
+
71
+ // No-op when the selector did not render a recommendation (banner suppressed,
72
+ // confidence 0.0, etc). Caller passes recommended=null in that case.
73
+ if (recommended === null || recommended === undefined || recommended === '') {
74
+ return { ok: false, reason: 'no-recommendation' };
75
+ }
76
+ if (typeof recommended !== 'string' || typeof chosen !== 'string') {
77
+ return { ok: false, reason: 'invalid-mode-type' };
78
+ }
79
+ if (!isValidMode(recommended) || !isValidMode(chosen)) {
80
+ return { ok: false, reason: 'unknown-mode' };
81
+ }
82
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
83
+ return { ok: false, reason: 'missing-session-id' };
84
+ }
85
+
86
+ const nowMs = typeof opts.nowMs === 'number' ? opts.nowMs : Date.now();
87
+ const expiryDays = Number.isInteger(opts.expiryDays) && opts.expiryDays > 0
88
+ ? opts.expiryDays
89
+ : DEFAULT_EXPIRY_DAYS;
90
+ const confidence = typeof opts.confidence === 'number'
91
+ ? opts.confidence
92
+ : INITIAL_CONFIDENCE;
93
+
94
+ const subject = buildSubject(recommended, chosen);
95
+ const agreement = recommended === chosen;
96
+ const insight = agreement
97
+ ? `User confirmed Mode-Selector recommendation (${recommended}).`
98
+ : `User overrode Mode-Selector recommendation (${recommended}) with ${chosen}.`;
99
+
100
+ const created_at = new Date(nowMs).toISOString();
101
+ const expires_at = new Date(nowMs + expiryDays * 86_400_000).toISOString();
102
+
103
+ const entry = {
104
+ id: `${LEARNING_TYPE}-${subject}-${sessionId}`,
105
+ type: LEARNING_TYPE,
106
+ subject,
107
+ insight,
108
+ evidence: [`${sessionId}: recommended=${recommended} chosen=${chosen}`],
109
+ confidence,
110
+ source_session: sessionId,
111
+ created_at,
112
+ expires_at,
113
+ };
114
+
115
+ try {
116
+ const validated = await appendLearning(filePath, entry);
117
+ return { ok: true, entry: validated };
118
+ } catch (err) {
119
+ return { ok: false, reason: `append-failed: ${err?.message ?? String(err)}` };
120
+ }
121
+ }