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,295 @@
1
+ /**
2
+ * scripts/lib/frontend-detect/rules.mjs
3
+ *
4
+ * Deterministic frontend-slop rule registry (regex tier — no LLM, no API key,
5
+ * no browser). Each rule is a pure function over file text that returns zero or
6
+ * more matches with the offending line + snippet.
7
+ *
8
+ * Design provenance: the rule *catalogue* (which AI-generated design tells to
9
+ * detect) is inspired by pbakaus/impeccable (Apache-2.0) and our own
10
+ * `.claude/rules/frontend.md`. The detection *code* here is a clean-room
11
+ * regex-tier reimplementation — we deliberately skip impeccable's heavier
12
+ * static-HTML CSS-cascade + Puppeteer tiers (cost ≫ value for a pre-commit /
13
+ * discovery probe; see the analysis in the linked backlog issue).
14
+ *
15
+ * The load-bearing idea we adopt: every prose design rule should have a
16
+ * MECHANICAL counterpart. `ruleRef` ties each detector rule back to the prose
17
+ * guidance it enforces — the "Disziplin statt Mechanik" pattern applied to a
18
+ * domain (frontend quality) we previously enforced with prose alone.
19
+ *
20
+ * Rule contract:
21
+ * {
22
+ * id: string, // stable kebab-case id
23
+ * ruleRef: string, // prose-guidance anchor it enforces
24
+ * severity: 'high'|'medium'|'low',
25
+ * category: 'ai-slop'|'quality',
26
+ * title: string,
27
+ * recommendation: string,
28
+ * fpRisk: 'low'|'medium'|'high', // false-positive risk (honesty signal)
29
+ * scan(content: string): Array<{ line: number, snippet: string, value?: string }>
30
+ * }
31
+ *
32
+ * A "match" is reported with a 1-based line number and a trimmed snippet of the
33
+ * offending source line.
34
+ */
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // Shared helpers
38
+ // ---------------------------------------------------------------------------
39
+
40
+ /**
41
+ * Convert a 0-based string index to a 1-based line number.
42
+ * @param {string} content
43
+ * @param {number} index
44
+ * @returns {number}
45
+ */
46
+ function lineOf(content, index) {
47
+ let line = 1;
48
+ for (let i = 0; i < index && i < content.length; i++) {
49
+ if (content[i] === '\n') line++;
50
+ }
51
+ return line;
52
+ }
53
+
54
+ /**
55
+ * Return the trimmed full source line containing `index`, capped to 160 chars.
56
+ * @param {string} content
57
+ * @param {number} index
58
+ * @returns {string}
59
+ */
60
+ function snippetAt(content, index) {
61
+ const start = content.lastIndexOf('\n', index - 1) + 1;
62
+ let end = content.indexOf('\n', index);
63
+ if (end === -1) end = content.length;
64
+ const raw = content.slice(start, end).trim();
65
+ return raw.length > 160 ? `${raw.slice(0, 157)}…` : raw;
66
+ }
67
+
68
+ /**
69
+ * Run a global regex over content and emit one match per hit.
70
+ * Deduplicates by line so a single offending line reports once.
71
+ * @param {string} content
72
+ * @param {RegExp} re — MUST have the global flag
73
+ * @returns {Array<{ line: number, snippet: string, value: string }>}
74
+ */
75
+ function scanRegex(content, re) {
76
+ const out = [];
77
+ const seenLines = new Set();
78
+ let m;
79
+ // Defensive: reset lastIndex in case a non-fresh regex is passed.
80
+ re.lastIndex = 0;
81
+ while ((m = re.exec(content)) !== null) {
82
+ const line = lineOf(content, m.index);
83
+ if (seenLines.has(line)) continue;
84
+ seenLines.add(line);
85
+ out.push({ line, snippet: snippetAt(content, m.index), value: m[0].trim() });
86
+ // Guard against zero-width matches looping forever.
87
+ if (m.index === re.lastIndex) re.lastIndex++;
88
+ }
89
+ return out;
90
+ }
91
+
92
+ // Purple / indigo / violet color tokens — the canonical AI-gradient palette.
93
+ const PURPLE_TOKENS = [
94
+ 'purple',
95
+ 'violet',
96
+ 'indigo',
97
+ 'fuchsia',
98
+ 'rebeccapurple',
99
+ '#7c3aed',
100
+ '#8b5cf6',
101
+ '#a855f7',
102
+ '#6366f1',
103
+ '#818cf8',
104
+ '#d946ef',
105
+ '#c084fc',
106
+ '#9333ea',
107
+ ];
108
+ const BLUE_TOKENS = ['blue', '#3b82f6', '#2563eb', '#60a5fa', '#0ea5e9', '#06b6d4', 'cyan'];
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // Rules
112
+ // ---------------------------------------------------------------------------
113
+
114
+ /** @type {Array<import('./detect.mjs').Rule>} */
115
+ export const RULES = [
116
+ {
117
+ id: 'gradient-text',
118
+ ruleRef: 'frontend.md#absolute-bans (gradient text)',
119
+ severity: 'high',
120
+ category: 'ai-slop',
121
+ title: 'Gradient text (background-clip:text + gradient)',
122
+ recommendation:
123
+ 'Decorative, never meaningful. Use a single solid color; carry emphasis with weight or size.',
124
+ fpRisk: 'low',
125
+ scan(content) {
126
+ const matches = [];
127
+ // CSS form: background-clip:text (or -webkit-) anywhere AND a gradient() anywhere.
128
+ const hasClipText = /(?:-webkit-)?background-clip\s*:\s*text\b/i.test(content);
129
+ const hasGradient = /\b(?:linear|radial|conic)-gradient\s*\(/i.test(content);
130
+ if (hasClipText && hasGradient) {
131
+ matches.push(...scanRegex(content, /(?:-webkit-)?background-clip\s*:\s*text\b/gi));
132
+ }
133
+ // Tailwind form: the `bg-clip-text` utility is the unambiguous tell.
134
+ matches.push(...scanRegex(content, /\bbg-clip-text\b/g));
135
+ return dedupeByLine(matches);
136
+ },
137
+ },
138
+
139
+ {
140
+ id: 'side-stripe-border',
141
+ ruleRef: 'frontend.md#absolute-bans (side-stripe borders)',
142
+ severity: 'high',
143
+ category: 'ai-slop',
144
+ title: 'Side-stripe accent border (border-left/right ≥ 2px)',
145
+ recommendation:
146
+ 'Never intentional as a colored accent. Use full borders, a background tint, a leading icon/number, or nothing.',
147
+ fpRisk: 'low',
148
+ scan(content) {
149
+ const matches = [];
150
+ // CSS: border-left: 4px solid <color> (width >= 2, not transparent/none)
151
+ const css = /border-(?:left|right)\s*:\s*(\d+)px\s+(?:solid|dashed|dotted|double)\b(?![^;]*\b(?:transparent|none)\b)/gi;
152
+ let m;
153
+ css.lastIndex = 0;
154
+ while ((m = css.exec(content)) !== null) {
155
+ if (Number(m[1]) >= 2) {
156
+ matches.push({ line: lineOf(content, m.index), snippet: snippetAt(content, m.index), value: m[0].trim() });
157
+ }
158
+ }
159
+ // Tailwind: border-l-2 / border-l-4 / border-l-8 / border-r-4 ...
160
+ matches.push(...scanRegex(content, /\bborder-(?:l|r)-(?:2|4|8)\b/g));
161
+ return dedupeByLine(matches);
162
+ },
163
+ },
164
+
165
+ {
166
+ id: 'overused-font',
167
+ ruleRef: 'frontend.md / development.md (avoid overused fonts)',
168
+ severity: 'medium',
169
+ category: 'ai-slop',
170
+ title: 'Overused primary font (Inter / Roboto / Arial / Helvetica)',
171
+ recommendation:
172
+ 'Every model reaches for these. Pick a font with a point of view; keep these only as fallbacks deeper in the stack.',
173
+ fpRisk: 'medium',
174
+ scan(content) {
175
+ // First family in a font-family stack is one of the overused four.
176
+ return scanRegex(content, /font-family\s*:\s*["']?(?:Inter|Roboto|Arial|Helvetica)\b/gi);
177
+ },
178
+ },
179
+
180
+ {
181
+ id: 'bounce-easing',
182
+ ruleRef: 'frontend.md#motion (no bounce/elastic easing)',
183
+ severity: 'medium',
184
+ category: 'ai-slop',
185
+ title: 'Bounce / elastic / overshoot easing',
186
+ recommendation: 'Feels dated. Ease out with exponential curves (ease-out-quart / quint / expo). No overshoot.',
187
+ fpRisk: 'low',
188
+ scan(content) {
189
+ const matches = [];
190
+ // Keyword easings.
191
+ matches.push(...scanRegex(content, /\b(?:bounce|elastic|wobble|spring)\b/gi));
192
+ // cubic-bezier with a y-control point > 1 or < 0 (overshoot).
193
+ const cb = /cubic-bezier\(\s*([\d.]+)\s*,\s*(-?[\d.]+)\s*,\s*([\d.]+)\s*,\s*(-?[\d.]+)\s*\)/gi;
194
+ let m;
195
+ cb.lastIndex = 0;
196
+ while ((m = cb.exec(content)) !== null) {
197
+ const y1 = Number(m[2]);
198
+ const y2 = Number(m[4]);
199
+ if (y1 > 1 || y2 > 1 || y1 < 0 || y2 < 0) {
200
+ matches.push({ line: lineOf(content, m.index), snippet: snippetAt(content, m.index), value: m[0].trim() });
201
+ }
202
+ }
203
+ return dedupeByLine(matches);
204
+ },
205
+ },
206
+
207
+ {
208
+ id: 'ai-purple-gradient',
209
+ ruleRef: 'frontend.md / PRODUCT anti-references (purple-to-blue gradients)',
210
+ severity: 'medium',
211
+ category: 'ai-slop',
212
+ title: 'Purple / indigo AI gradient',
213
+ recommendation:
214
+ 'The single most recognizable AI tell. If purple is genuinely the brand, keep it flat; otherwise pick a committed strategy.',
215
+ fpRisk: 'high',
216
+ scan(content) {
217
+ const matches = [];
218
+ const grad = /\b(?:linear|radial|conic)-gradient\s*\(([^)]*)\)/gi;
219
+ let m;
220
+ grad.lastIndex = 0;
221
+ while ((m = grad.exec(content)) !== null) {
222
+ const args = m[1].toLowerCase();
223
+ const purpleHits = PURPLE_TOKENS.filter((t) => args.includes(t)).length;
224
+ const blueHits = BLUE_TOKENS.filter((t) => args.includes(t)).length;
225
+ // Tell = two purples, OR a purple→blue ramp.
226
+ if (purpleHits >= 2 || (purpleHits >= 1 && blueHits >= 1)) {
227
+ matches.push({ line: lineOf(content, m.index), snippet: snippetAt(content, m.index), value: m[0].trim().slice(0, 80) });
228
+ }
229
+ }
230
+ return dedupeByLine(matches);
231
+ },
232
+ },
233
+
234
+ {
235
+ id: 'pure-black-ink',
236
+ ruleRef: 'frontend.md (never pure black/gray — always tint)',
237
+ severity: 'low',
238
+ category: 'quality',
239
+ title: 'Pure black text color (#000 / black / rgb(0,0,0))',
240
+ recommendation: 'Pure black reads harsh on screen. Tint toward the brand hue (e.g. very dark, slightly hued ink).',
241
+ fpRisk: 'medium',
242
+ scan(content) {
243
+ return scanRegex(
244
+ content,
245
+ /color\s*:\s*(?:#000(?:000)?\b|black\b|rgb\(\s*0\s*,\s*0\s*,\s*0\s*\))/gi,
246
+ );
247
+ },
248
+ },
249
+
250
+ {
251
+ id: 'arbitrary-z-index',
252
+ ruleRef: 'frontend.md#layout (semantic z-index scale, never 999/9999)',
253
+ severity: 'low',
254
+ category: 'quality',
255
+ title: 'Arbitrary z-index (999 / 9999 …)',
256
+ recommendation: 'Build a semantic z-index scale (dropdown → sticky → modal → toast → tooltip). Never magic numbers.',
257
+ fpRisk: 'low',
258
+ scan(content) {
259
+ return scanRegex(content, /z-index\s*:\s*(?:9{3,})\b/gi);
260
+ },
261
+ },
262
+
263
+ {
264
+ id: 'layout-property-transition',
265
+ ruleRef: 'frontend.md#motion (don\'t animate layout properties)',
266
+ severity: 'low',
267
+ category: 'quality',
268
+ title: 'Animating layout properties (width/height/margin/…)',
269
+ recommendation:
270
+ 'Animating layout props thrashes the main thread. Animate transform/opacity; reserve layout animation for genuine need.',
271
+ fpRisk: 'medium',
272
+ scan(content) {
273
+ // `transition:` shorthand whose property list includes a layout prop.
274
+ return scanRegex(
275
+ content,
276
+ /transition\s*:\s*[^;{}]*\b(?:width|height|top|left|right|bottom|margin|padding)\b/gi,
277
+ );
278
+ },
279
+ },
280
+ ];
281
+
282
+ /**
283
+ * Collapse multiple matches on the same line into one (stable order).
284
+ * @param {Array<{line:number, snippet:string, value?:string}>} matches
285
+ */
286
+ function dedupeByLine(matches) {
287
+ const byLine = new Map();
288
+ for (const mt of matches) {
289
+ if (!byLine.has(mt.line)) byLine.set(mt.line, mt);
290
+ }
291
+ return [...byLine.values()].sort((a, b) => a.line - b.line);
292
+ }
293
+
294
+ /** Stable list of rule ids (for config validation + tests). */
295
+ export const RULE_IDS = RULES.map((r) => r.id);
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Frontmatter-Guard library (issue #328).
3
+ *
4
+ * Reads the canonical vault-frontmatter Zod schema source and exposes helpers
5
+ * for generating a contextual schema snippet that can be injected into agent
6
+ * prompts before vault-write tasks.
7
+ *
8
+ * Pure ESM, no top-level side effects. All I/O is wrapped in functions.
9
+ * Uses `node:fs` and `node:crypto` only — no external dependencies.
10
+ */
11
+
12
+ import { digestSha256Short } from './crypto-digest-utils.mjs';
13
+ import { readFileSync, statSync } from 'node:fs';
14
+ import { homedir } from 'node:os';
15
+ import { join } from 'node:path';
16
+
17
+ /** Absolute path to the canonical vault-frontmatter schema source. */
18
+ const SCHEMA_SOURCE_PATH = join(
19
+ homedir(),
20
+ 'Projects/projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts',
21
+ );
22
+
23
+ /**
24
+ * In-memory mtime cache so repeated calls within a single process invocation
25
+ * skip the FS read when the file has not changed. Re-reads on mtime change.
26
+ *
27
+ * @type {{ mtime: number | null; result: ReturnType<typeof _parseSchema> | null }}
28
+ */
29
+ const _cache = { mtime: null, result: null };
30
+
31
+ /**
32
+ * Parse the type-enum values out of a Zod `z.enum([...])` call in source text.
33
+ *
34
+ * @param {string} text
35
+ * @param {string} exportName - e.g. 'vaultNoteTypeSchema'
36
+ * @returns {string[]}
37
+ */
38
+ function _extractEnum(text, exportName) {
39
+ // Match: export const <name> = z.enum([ ...values... ]);
40
+ const re = new RegExp(
41
+ `export\\s+const\\s+${exportName}\\s*=\\s*z\\.enum\\(\\s*\\[([^\\]]+)\\]`,
42
+ 's',
43
+ );
44
+ const match = text.match(re);
45
+ if (!match) return [];
46
+ return match[1]
47
+ .split(',')
48
+ .map((s) => s.trim().replace(/^['"]|['"]$/g, ''))
49
+ .filter(Boolean);
50
+ }
51
+
52
+ /**
53
+ * Internal parser — extracts structured info from the TS source.
54
+ *
55
+ * @param {string} text
56
+ * @returns {{ typeEnum: string[], statusEnum: string[], requiredFields: string[], idRegex: string, tagsRegex: string, schemaText: string }}
57
+ */
58
+ function _parseSchema(text) {
59
+ const typeEnum = _extractEnum(text, 'vaultNoteTypeSchema');
60
+ const statusEnum = _extractEnum(text, 'vaultNoteStatusSchema');
61
+
62
+ // Required fields are id, type, created, updated — stable; extracted
63
+ // from the schema object declaration (non-optional fields).
64
+ const requiredFields = ['id', 'type', 'created', 'updated'];
65
+
66
+ // Regex values — parse from source or use hard-coded fallback that matches
67
+ // the known schema. Prefer source-parse for drift-safety.
68
+ const slugMatch = text.match(/const slugRegex\s*=\s*([^;]+);/);
69
+ const tagMatch = text.match(/const tagPathRegex\s*=\s*([^;]+);/);
70
+
71
+ // Convert JS regex literal /pattern/ to pattern string
72
+ const toPattern = (raw) => {
73
+ if (!raw) return null;
74
+ const m = raw.trim().match(/^\/(.+)\/[gimsuy]*$/);
75
+ return m ? m[1] : null;
76
+ };
77
+
78
+ const idRegex =
79
+ toPattern(slugMatch?.[1]) ?? '^[a-z0-9]+(?:-[a-z0-9]+)*$';
80
+ const tagsRegex =
81
+ toPattern(tagMatch?.[1]) ??
82
+ '^[a-z0-9]+(?:-[a-z0-9]+)*(?:/[a-z0-9]+(?:-[a-z0-9]+)*)*$';
83
+
84
+ return { typeEnum, statusEnum, requiredFields, idRegex, tagsRegex, schemaText: text };
85
+ }
86
+
87
+ /**
88
+ * Read and parse the canonical vault-frontmatter schema source.
89
+ *
90
+ * Caches the result in-memory; re-reads only when the file mtime changes.
91
+ * Returns `null` (no throw) if the file is missing or unreadable.
92
+ *
93
+ * @returns {{ typeEnum: string[], statusEnum: string[], requiredFields: string[], idRegex: string, tagsRegex: string, schemaText: string } | null}
94
+ */
95
+ export function readVaultSchema() {
96
+ let mtime;
97
+ try {
98
+ mtime = statSync(SCHEMA_SOURCE_PATH).mtimeMs;
99
+ } catch {
100
+ // File missing or inaccessible
101
+ return null;
102
+ }
103
+
104
+ if (_cache.mtime === mtime && _cache.result !== null) {
105
+ return _cache.result;
106
+ }
107
+
108
+ let text;
109
+ try {
110
+ text = readFileSync(SCHEMA_SOURCE_PATH, 'utf8');
111
+ } catch {
112
+ return null;
113
+ }
114
+
115
+ const result = _parseSchema(text);
116
+ _cache.mtime = mtime;
117
+ _cache.result = result;
118
+ return result;
119
+ }
120
+
121
+ /**
122
+ * Compute an 8-character SHA-256 hex prefix of the given schema source text.
123
+ * Stable across calls for the same input — useful as a cache-busting token.
124
+ *
125
+ * @param {string} schemaText
126
+ * @returns {string}
127
+ */
128
+ export function computeSchemaHash(schemaText) {
129
+ return digestSha256Short(schemaText);
130
+ }
131
+
132
+ /**
133
+ * Generate a deterministic Markdown snippet documenting the vault frontmatter
134
+ * schema, suitable for injection into agent prompts before vault-write tasks.
135
+ *
136
+ * @param {{ typeEnum: string[], statusEnum: string[], requiredFields: string[], idRegex: string, tagsRegex: string }} schema
137
+ * @returns {string}
138
+ */
139
+ export function generateFrontmatterSnippet(schema) {
140
+ const { typeEnum, statusEnum, requiredFields, idRegex, tagsRegex: _tagsRegex } = schema;
141
+
142
+ const typeList = typeEnum.map((v) => `\`${v}\``).join(' | ');
143
+ const statusList = statusEnum.map((v) => `\`${v}\``).join(' | ');
144
+ const requiredList = requiredFields.map((f) => `\`${f}\``).join(', ');
145
+
146
+ return `## Vault Frontmatter Schema (REQUIRED for files under ~/Projects/vault/)
147
+
148
+ **Required fields (every note):** ${requiredList}
149
+
150
+ ### Enums
151
+ - **\`type\`:** ${typeList}
152
+ - **\`status\`** (optional): ${statusList}
153
+
154
+ ### Field formats
155
+ - \`id\`: kebab-case, 2-128 chars, regex \`${idRegex}\`
156
+ - \`tags\`: array of kebab-case strings, \`/\` separator allowed (e.g., \`learning/cli-design\`)
157
+ - \`created\` / \`updated\` / \`expires\`: ISO 8601 (\`YYYY-MM-DD\` or \`YYYY-MM-DDTHH:MM:SSZ\`)
158
+
159
+ ### Examples
160
+
161
+ #### type: reference
162
+ \`\`\`yaml
163
+ id: parallel-session-rules
164
+ type: reference
165
+ created: 2026-05-08
166
+ updated: 2026-05-08
167
+ status: active
168
+ tags: [reference/rules]
169
+ \`\`\`
170
+ #### type: session
171
+ \`\`\`yaml
172
+ id: session-2026-05-08-deep
173
+ type: session
174
+ created: 2026-05-08
175
+ updated: 2026-05-08
176
+ status: archived
177
+ tags: [session/deep]
178
+ \`\`\`
179
+ #### type: learning
180
+ \`\`\`yaml
181
+ id: w1-discovery-shrinks-scope
182
+ type: learning
183
+ created: 2026-05-08
184
+ updated: 2026-05-08
185
+ status: active
186
+ \`\`\`
187
+ #### type: daily
188
+ \`\`\`yaml
189
+ id: 2026-05-08
190
+ type: daily
191
+ created: 2026-05-08
192
+ updated: 2026-05-08
193
+ \`\`\`
194
+ #### type: project
195
+ \`\`\`yaml
196
+ id: session-orchestrator
197
+ type: project
198
+ created: 2026-04-01
199
+ updated: 2026-05-08
200
+ status: active
201
+ \`\`\`
202
+ `;
203
+ }
204
+
205
+ /**
206
+ * Heuristic detector: returns true when the current task is likely to write
207
+ * vault files, in which case the frontmatter-guard snippet should be injected.
208
+ *
209
+ * Detection rules (OR logic — any match returns true):
210
+ * 1. Any file in `fileScope` whose path contains `/Projects/vault/`.
211
+ * 2. Any file in `fileScope` under known vault subdirectories:
212
+ * `40-learnings/`, `50-sessions/`, `03-daily/`, `01-projects/`.
213
+ * 3. `taskDescription` mentions "vault" or "vault-mirror" AND contains a
214
+ * write-intent keyword ("write", "creat", "generat", "emit", "mirror",
215
+ * "update", "add", "insert").
216
+ *
217
+ * Pure function — no I/O.
218
+ *
219
+ * @param {string} taskDescription
220
+ * @param {string[]} fileScope
221
+ * @returns {boolean}
222
+ */
223
+ export function detectVaultTaskScope(taskDescription, fileScope) {
224
+ const VAULT_PATH_RE = /\/Projects\/vault\//;
225
+ const VAULT_SUBDIR_RE = /(?:40-learnings|50-sessions|03-daily|01-projects)\//;
226
+
227
+ for (const f of fileScope) {
228
+ if (VAULT_PATH_RE.test(f) || VAULT_SUBDIR_RE.test(f)) {
229
+ return true;
230
+ }
231
+ }
232
+
233
+ const desc = taskDescription.toLowerCase();
234
+ const mentionsVault = desc.includes('vault') || desc.includes('vault-mirror');
235
+ const WRITE_INTENT_RE = /\b(?:write[a-z]*|creat[a-z]*|generat[a-z]*|emit[a-z]*|mirror[a-z]*|updat[a-z]*|add[a-z]*|insert[a-z]*)\b/;
236
+ if (mentionsVault && WRITE_INTENT_RE.test(desc)) {
237
+ return true;
238
+ }
239
+
240
+ return false;
241
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * echo-stub-detect.mjs — Detect quality-gate commands that are no-op stubs.
3
+ * Prevents `echo "no automated tests yet"` from producing a false-positive pass.
4
+ */
5
+
6
+ /**
7
+ * Detect whether a quality-gate command is a no-op echo-stub or a `:` no-op.
8
+ *
9
+ * Detection rules (applied in order):
10
+ * 1. Empty / undefined / `'skip'` → not a stub (skip branch handles these).
11
+ * 2. Whole command equals `:` → stub of kind `'noop'`.
12
+ * 3. Whole command is `echo` followed by a single quoted or simple argument
13
+ * with no shell-meta tail (pipe, redirect, command-substitution, etc.)
14
+ * → stub of kind `'echo'`.
15
+ * 4. Otherwise → not a stub.
16
+ *
17
+ * @param {string|undefined} cmd
18
+ * @returns {{ isStub: boolean, kind?: 'echo'|'noop' }}
19
+ */
20
+ export function detectStubCommand(cmd) {
21
+ if (!cmd || cmd === 'skip') {
22
+ return { isStub: false };
23
+ }
24
+
25
+ const trimmed = cmd.trim();
26
+
27
+ if (trimmed === ':') {
28
+ return { isStub: true, kind: 'noop' };
29
+ }
30
+
31
+ // Matches: echo "quoted" | echo 'quoted' | echo simpleArg
32
+ // Rejects any shell-meta characters after the argument (|, ;, &, <, >, $, `, (, ))
33
+ const ECHO_STUB_RE = /^echo\s+(?:"[^"]*"|'[^']*'|[^\s|;&<>$`()]+)\s*$/;
34
+ if (ECHO_STUB_RE.test(trimmed)) {
35
+ return { isStub: true, kind: 'echo' };
36
+ }
37
+
38
+ return { isStub: false };
39
+ }
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ // gate-baseline.mjs — baseline quality gate handler
3
+ // Runs typecheck (tail-5) + test (tail-5); informational only, always exits 0.
4
+ //
5
+ // Required env: TYPECHECK_CMD, TEST_CMD
6
+ // Each may equal "skip" or empty string → treated as skip.
7
+
8
+ import { runCheck } from './gate-helpers.mjs';
9
+
10
+ const typecheckCmd = process.env.TYPECHECK_CMD;
11
+ const testCmd = process.env.TEST_CMD;
12
+
13
+ if (!typecheckCmd) {
14
+ process.stderr.write('TYPECHECK_CMD must be set\n');
15
+ process.exit(1);
16
+ }
17
+ if (!testCmd) {
18
+ process.stderr.write('TEST_CMD must be set\n');
19
+ process.exit(1);
20
+ }
21
+
22
+ let tcResult = { status: 'skip', output: '' };
23
+ let testResult = { status: 'skip', output: '' };
24
+
25
+ if (typecheckCmd !== 'skip') {
26
+ tcResult = await runCheck(typecheckCmd);
27
+ }
28
+
29
+ if (testCmd !== 'skip') {
30
+ testResult = await runCheck(testCmd);
31
+ }
32
+
33
+ const result = {
34
+ variant: 'baseline',
35
+ typecheck: tcResult.status,
36
+ test: testResult.status,
37
+ typecheck_output: tcResult.output,
38
+ test_output: testResult.output,
39
+ };
40
+
41
+ process.stdout.write(JSON.stringify(result) + '\n');
42
+ process.exit(0);
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ // gate-full.mjs — full-gate quality gate handler
3
+ // Runs typecheck + tests + lint sequentially; exits 2 if any check fails, 0 otherwise.
4
+ //
5
+ // Required env: TYPECHECK_CMD, TEST_CMD, LINT_CMD (each may equal "skip")
6
+ // Optional env: SESSION_START_REF
7
+
8
+ import {
9
+ runCheck,
10
+ extractCount,
11
+ extractTestCounts,
12
+ collectDebugArtifacts,
13
+ } from './gate-helpers.mjs';
14
+
15
+ const typecheckCmd = process.env.TYPECHECK_CMD;
16
+ const testCmd = process.env.TEST_CMD;
17
+ const lintCmd = process.env.LINT_CMD;
18
+ const sessionStartRef = process.env.SESSION_START_REF ?? '';
19
+
20
+ if (!typecheckCmd) {
21
+ process.stderr.write('TYPECHECK_CMD must be set\n');
22
+ process.exit(1);
23
+ }
24
+ if (!testCmd) {
25
+ process.stderr.write('TEST_CMD must be set\n');
26
+ process.exit(1);
27
+ }
28
+ if (!lintCmd) {
29
+ process.stderr.write('LINT_CMD must be set\n');
30
+ process.exit(1);
31
+ }
32
+
33
+ const startTime = Date.now();
34
+
35
+ // --- Typecheck ---
36
+ const tcResult = runCheck(typecheckCmd);
37
+ const tcErrorCount =
38
+ tcResult.status === 'fail'
39
+ ? extractCount(tcResult.output, /error TS\d+/)
40
+ : 0;
41
+
42
+ // --- Test ---
43
+ const testResult = runCheck(testCmd);
44
+ const { passed: testPassed, total: testTotal } =
45
+ testResult.status !== 'skip'
46
+ ? extractTestCounts(testResult.output)
47
+ : { passed: 0, total: 0 };
48
+
49
+ // --- Lint ---
50
+ const lintResult = runCheck(lintCmd);
51
+ const lintWarnings =
52
+ lintResult.status !== 'skip'
53
+ ? extractCount(lintResult.output, /warning/i)
54
+ : 0;
55
+
56
+ // --- Debug artifacts ---
57
+ const debugArtifacts = collectDebugArtifacts(sessionStartRef);
58
+
59
+ // --- Duration ---
60
+ const durationSeconds = Math.round((Date.now() - startTime) / 1000);
61
+
62
+ // --- Stub map ---
63
+ const stubbed = {};
64
+ if (tcResult.stubbed) stubbed.typecheck = tcResult.stubbed;
65
+ if (testResult.stubbed) stubbed.test = testResult.stubbed;
66
+ if (lintResult.stubbed) stubbed.lint = lintResult.stubbed;
67
+
68
+ // --- Output ---
69
+ const output = {
70
+ variant: 'full-gate',
71
+ duration_seconds: durationSeconds,
72
+ typecheck: { status: tcResult.status, error_count: tcErrorCount },
73
+ test: { status: testResult.status, total: testTotal, passed: testPassed },
74
+ lint: { status: lintResult.status, warnings: lintWarnings },
75
+ debug_artifacts: debugArtifacts,
76
+ stubbed,
77
+ };
78
+
79
+ process.stdout.write(JSON.stringify(output) + '\n');
80
+
81
+ // Exit 2 if any check failed; skipped counts as pass.
82
+ const failed = [tcResult, testResult, lintResult].some(
83
+ (r) => r.status === 'fail',
84
+ );
85
+ process.exit(failed ? 2 : 0);