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,605 @@
1
+ // scripts/lib/autopilot/worktree-pipeline.mjs
2
+ //
3
+ // Per-story worktree-isolated loop driver for autopilot --multi-story.
4
+ // Wraps single-story runLoop from ./loop.mjs with worktree setup/teardown,
5
+ // per-worktree session-lock, and gc-on-exit. DI seams for testability.
6
+ //
7
+ // DI seam (#580-DI-001): this module uses an ASYNC `opts.$` (zx) executor seam
8
+ // because its worktree primitives — `setupWorktree`, `enterWorktree`,
9
+ // `teardownWorktree` — are async (they await `git worktree add` and lazy zx
10
+ // imports). This is DELIBERATELY divergent from the SYNCHRONOUS `opts.execFileFn`
11
+ // (execFileSync) seam used by the session-end / memory-cleanup helpers
12
+ // (`scripts/lib/session-end/worktree-cleanup.mjs`,
13
+ // `scripts/lib/memory-cleanup/worktree-sweep.mjs`), which run in synchronous
14
+ // coordinator steps. The seams are kept divergent on purpose — forcing a single
15
+ // seam would break the sync/async boundary. Do NOT unify.
16
+ //
17
+ // References:
18
+ // - "Autopilot Phase D — Per-Story Worktree Pipelines" (#341; archived in the private Meta-Vault) (PRD)
19
+ // - docs/adr/2026-05-10-364-remote-agent-substrate.md (ADR-364)
20
+ // - scripts/lib/autopilot/loop.mjs (substrate: forward-compat params)
21
+ // - scripts/lib/worktree/lifecycle.mjs (substrate: validateWorkspacePath)
22
+
23
+ // NOTE: zx is imported LAZILY inside functions that need it (see lazyZx() helper).
24
+ // Top-level `import { $ as realZx } from 'zx'` caused fork-pool fragility — when this
25
+ // module is loaded in a worker fork before tests like tests/lib/worktree/constants.test.mjs
26
+ // run, vi.mock('zx', ...) factories in those test files cannot re-route the cached
27
+ // import. Pipeline 3848 (commit 1347c7a) failed for this reason. Lazy import preserves
28
+ // module-load order isolation. Pattern matches deep-2 #367 DI-seam migration.
29
+ import path from 'node:path';
30
+ import os from 'node:os';
31
+ import fs, { realpathSync } from 'node:fs';
32
+ import { runLoop } from './loop.mjs';
33
+ import { maybeCreateDraftMR } from './mr-draft.mjs';
34
+ import { validateWorkspacePath } from '../worktree/lifecycle.mjs';
35
+ import { acquire, release } from '../session-lock.mjs';
36
+ import { main as gcMain } from '../../gc-stale-worktrees.mjs';
37
+ import { SEMANTIC_ID_RE } from '../session-id.mjs';
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Type definitions
41
+ // ---------------------------------------------------------------------------
42
+
43
+ /**
44
+ * Per-story context passed through the worktree pipeline.
45
+ *
46
+ * @typedef {object} StoryContext
47
+ * @property {number} issueIid - GitLab/GitHub issue IID.
48
+ * @property {string} issueTitle - Issue title (used for draft MR body).
49
+ * @property {string} branchName - Feature branch to create/reuse.
50
+ * @property {string} repoRoot - Absolute path to the primary repo.
51
+ * @property {string} parentRunId - Autopilot run ID of the parent orchestration session.
52
+ * @property {string} [worktreeRoot] - Override for the worktree root directory.
53
+ * @property {object} [killSwitchOpts] - Kill-switch overrides forwarded to the inner loop.
54
+ * @property {'off'|'on-loop-start'|'on-green'} [draftMrPolicy] - Draft MR creation policy; default "off".
55
+ * @property {'gitlab'|'github'} [vcs] - VCS backend; defaults to "gitlab" if absent.
56
+ */
57
+
58
+ /**
59
+ * Result returned by `runStoryPipeline` after the per-story loop completes.
60
+ *
61
+ * @typedef {object} StoryResult
62
+ * @property {number} issueIid
63
+ * @property {string} worktreePath
64
+ * @property {string} runId
65
+ * @property {string|null} killSwitch
66
+ * @property {string|null} killSwitchDetail
67
+ * @property {number} iterationsCompleted
68
+ * @property {number} spiralRecoveryCount
69
+ * @property {string|null} commitDependency
70
+ * @property {boolean} abortedByCohort
71
+ */
72
+
73
+ // ---------------------------------------------------------------------------
74
+ // Constants
75
+ // ---------------------------------------------------------------------------
76
+
77
+ /** Default root directory that contains all per-story worktrees. */
78
+ export const WORKTREE_ROOT_DEFAULT = path.join(os.homedir(), '.so-worktrees');
79
+
80
+ // ---------------------------------------------------------------------------
81
+ // Custom error classes
82
+ // ---------------------------------------------------------------------------
83
+
84
+ /**
85
+ * Thrown when the computed worktree path resolves outside the allowed root.
86
+ * Defence-in-depth against path-traversal (CWE-23 / SEC-013).
87
+ */
88
+ export class WorktreeBoundaryError extends Error {
89
+ /**
90
+ * @param {string} message
91
+ * @param {{ computed?: string, root?: string }} [meta]
92
+ */
93
+ constructor(message, meta = {}) {
94
+ super(message);
95
+ this.name = 'WorktreeBoundaryError';
96
+ this.computed = meta.computed ?? null;
97
+ this.root = meta.root ?? null;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Thrown when a per-worktree session lock cannot be acquired because another
103
+ * process already holds it.
104
+ */
105
+ export class WorktreeLockedError extends Error {
106
+ /**
107
+ * @param {string} message
108
+ * @param {{ existingLock?: object, reason?: string }} [meta]
109
+ */
110
+ constructor(message, meta = {}) {
111
+ super(message);
112
+ this.name = 'WorktreeLockedError';
113
+ this.existingLock = meta.existingLock ?? null;
114
+ this.lockReason = meta.reason ?? null;
115
+ }
116
+ }
117
+
118
+ // ---------------------------------------------------------------------------
119
+ // Internal helpers
120
+ // ---------------------------------------------------------------------------
121
+
122
+ /**
123
+ * Derive the repo basename from the repoRoot path.
124
+ * @param {string} repoRoot
125
+ * @returns {string}
126
+ */
127
+ function repoBasename(repoRoot) {
128
+ return path.basename(repoRoot);
129
+ }
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // setupWorktree
133
+ // ---------------------------------------------------------------------------
134
+
135
+ /**
136
+ * Create (or reuse) the per-story git worktree.
137
+ *
138
+ * Path layout: `<worktreeRoot>/<repoBasename>/<issueIid>`
139
+ *
140
+ * Idempotent: if the directory already exists and contains a `.git` file,
141
+ * the existing worktree is reused and `{ wtPath, reused: true }` is returned.
142
+ *
143
+ * @param {StoryContext} context
144
+ * @param {object} [opts]
145
+ * @param {Function} [opts.$] - zx-like template-tag executor (DI seam).
146
+ * @returns {Promise<{ wtPath: string, reused: boolean }>}
147
+ * @throws {WorktreeBoundaryError} when computed path escapes `worktreeRoot`.
148
+ */
149
+ export async function setupWorktree(context, opts = {}) {
150
+ const {
151
+ issueIid,
152
+ branchName,
153
+ repoRoot,
154
+ worktreeRoot = WORKTREE_ROOT_DEFAULT,
155
+ } = context;
156
+
157
+ const exec = opts.$ ?? (await import('zx')).$;
158
+
159
+ // CWE-59 hardening (#375): resolve symlinks in worktreeRoot ONCE so that
160
+ // validateWorkspacePath comparisons use a fully-resolved parent path.
161
+ // macOS gotcha: /var → /private/var, so worktreeRoot must be resolved FIRST,
162
+ // and wtPath must be derived from the resolved root — otherwise the ENOENT
163
+ // fallback path stays as /var/... while resolvedWorktreeRoot is /private/var/...
164
+ // causing legitimate paths to false-reject (mirrors #374 pattern).
165
+ let resolvedWorktreeRoot;
166
+ try {
167
+ resolvedWorktreeRoot = realpathSync(worktreeRoot);
168
+ } catch {
169
+ // worktreeRoot missing — fall back to unresolved; validateWorkspacePath
170
+ // will still catch string-level traversal attempts.
171
+ resolvedWorktreeRoot = worktreeRoot;
172
+ }
173
+
174
+ // Compute wtPath from the resolved root so path comparisons are consistent.
175
+ const wtPath = path.join(resolvedWorktreeRoot, repoBasename(repoRoot), String(issueIid));
176
+
177
+ // Resolve symlinks in wtPath to prevent symlink-escape between path
178
+ // computation and the eventual git worktree add call.
179
+ // ENOENT is expected when the worktree doesn't exist yet — use raw path.
180
+ let resolvedWtPath;
181
+ try {
182
+ resolvedWtPath = realpathSync(wtPath);
183
+ } catch (err) {
184
+ if (err.code !== 'ENOENT') throw err;
185
+ resolvedWtPath = wtPath; // path doesn't exist yet — no symlink to resolve
186
+ }
187
+
188
+ // SEC-013 / ADR-364: validate resolved path BEFORE any filesystem write.
189
+ const valid = validateWorkspacePath(resolvedWtPath, resolvedWorktreeRoot);
190
+ if (!valid) {
191
+ process.stderr.write(
192
+ `worktree-pipeline: refusing to setup symlink-escape: ${wtPath} → ${resolvedWtPath}\n`,
193
+ );
194
+ throw new WorktreeBoundaryError(
195
+ `worktree-pipeline: computed path '${resolvedWtPath}' escapes root '${resolvedWorktreeRoot}'`,
196
+ { computed: resolvedWtPath, root: resolvedWorktreeRoot },
197
+ );
198
+ }
199
+
200
+ // Idempotency: if the worktree already exists, reuse it.
201
+ if (fs.existsSync(wtPath)) {
202
+ const gitFile = path.join(wtPath, '.git');
203
+ if (fs.existsSync(gitFile)) {
204
+ console.error(
205
+ `worktree-pipeline: reusing existing worktree at '${wtPath}' for issue #${issueIid}`,
206
+ );
207
+ return { wtPath, reused: true };
208
+ }
209
+ }
210
+
211
+ // Create the worktree. Try origin/main first; fall back to HEAD if absent.
212
+ try {
213
+ await exec`git -C ${repoRoot} worktree add ${wtPath} -b ${branchName} origin/main`;
214
+ } catch {
215
+ // origin/main not available — fall back to HEAD.
216
+ await exec`git -C ${repoRoot} worktree add ${wtPath} -b ${branchName} HEAD`;
217
+ }
218
+
219
+ return { wtPath, reused: false };
220
+ }
221
+
222
+ // ---------------------------------------------------------------------------
223
+ // teardownWorktree
224
+ // ---------------------------------------------------------------------------
225
+
226
+ /**
227
+ * Tear down the per-story worktree after the loop completes.
228
+ *
229
+ * Behaviour:
230
+ * - If `result.killSwitch` is `'stall-timeout'`: leave the worktree intact
231
+ * for retry. Only release the lock.
232
+ * - Otherwise: call `opts.gcOnExit` to clean up, then release the lock.
233
+ * - Errors during teardown are swallowed (logged to stderr). Never re-throws.
234
+ *
235
+ * @param {StoryContext} context
236
+ * @param {StoryResult} result
237
+ * @param {object} [opts]
238
+ * @param {Function} [opts.gcOnExit] - GC driver (DI seam).
239
+ * @returns {Promise<void>}
240
+ */
241
+ export async function teardownWorktree(context, result, opts = {}) {
242
+ const {
243
+ repoRoot,
244
+ worktreeRoot = WORKTREE_ROOT_DEFAULT,
245
+ } = context;
246
+
247
+ const gcOnExit = opts.gcOnExit ?? gcMain;
248
+
249
+ // Preserve the worktree on stall-timeout so the caller can retry.
250
+ const preserve = result.killSwitch === 'stall-timeout';
251
+
252
+ if (!preserve) {
253
+ try {
254
+ await gcOnExit({
255
+ apply: true,
256
+ worktreeRoot,
257
+ repoRoot,
258
+ dryRun: false,
259
+ argv: [],
260
+ });
261
+ } catch (gcErr) {
262
+ console.error(
263
+ `worktree-pipeline: gc teardown error for issue #${context.issueIid}: ${gcErr?.message ?? String(gcErr)}`,
264
+ );
265
+ }
266
+ }
267
+
268
+ // Always attempt to release the per-worktree lock.
269
+ if (result._lockSessionId) {
270
+ try {
271
+ release({ sessionId: result._lockSessionId, repoRoot: result.worktreePath });
272
+ } catch (lockErr) {
273
+ console.error(
274
+ `worktree-pipeline: lock release error for issue #${context.issueIid}: ${lockErr?.message ?? String(lockErr)}`,
275
+ );
276
+ }
277
+ }
278
+ }
279
+
280
+ // ---------------------------------------------------------------------------
281
+ // runStoryPipeline
282
+ // ---------------------------------------------------------------------------
283
+
284
+ /**
285
+ * Run the full per-story worktree-isolated autopilot loop.
286
+ *
287
+ * Steps:
288
+ * 1. Validate worktree path boundary.
289
+ * 2. Setup worktree (idempotent).
290
+ * 3. Acquire per-worktree session lock.
291
+ * 4. Draft-MR creation hook (policy-gated via `context.draftMrPolicy`).
292
+ * 5. Run the inner autopilot loop.
293
+ * 6. Teardown worktree (or preserve on stall-timeout).
294
+ * 7. Return StoryResult.
295
+ *
296
+ * @param {StoryContext} context
297
+ * @param {object} [opts]
298
+ * @param {Function} [opts.$] - zx-like template-tag executor (DI seam).
299
+ * @param {Function} [opts.loopRunner] - Replaces `runLoop` for testability.
300
+ * @param {Function} [opts.lockAcquire] - Replaces `acquire` for testability.
301
+ * @param {Function} [opts.gcOnExit] - Replaces `gcMain` for testability.
302
+ * @param {Function} [opts.nowMs] - Returns current epoch-ms (DI seam).
303
+ * @param {Function} [opts.draftMrCreator] - Replaces `maybeCreateDraftMR` for testability.
304
+ * @returns {Promise<StoryResult>}
305
+ * @throws {WorktreeBoundaryError} on path-traversal attempt.
306
+ * @throws {WorktreeLockedError} when lock is already held.
307
+ */
308
+ export async function runStoryPipeline(context, opts = {}) {
309
+ const {
310
+ issueIid,
311
+ parentRunId,
312
+ killSwitchOpts = {},
313
+ } = context;
314
+
315
+ const loopRunner = opts.loopRunner ?? runLoop;
316
+ const lockAcquire = opts.lockAcquire ?? acquire;
317
+ const gcOnExit = opts.gcOnExit ?? gcMain;
318
+ const nowMs = opts.nowMs ?? (() => Date.now());
319
+ const draftMrCreator = opts.draftMrCreator ?? maybeCreateDraftMR; // DI seam: testable replacement for mr-draft module
320
+
321
+ // -------------------------------------------------------------------------
322
+ // Step 1+2: Setup worktree (includes path validation).
323
+ // -------------------------------------------------------------------------
324
+ const { wtPath } = await setupWorktree(context, { $: opts.$ });
325
+
326
+ // -------------------------------------------------------------------------
327
+ // Step 3: Acquire per-worktree session lock.
328
+ // -------------------------------------------------------------------------
329
+ const lockSessionId = `story-${issueIid}-${nowMs()}`;
330
+ const lockResult = lockAcquire({
331
+ sessionId: lockSessionId,
332
+ mode: 'multi-story-pipeline',
333
+ ttlHours: 2,
334
+ repoRoot: wtPath,
335
+ });
336
+
337
+ if (!lockResult.ok) {
338
+ throw new WorktreeLockedError(
339
+ `worktree-pipeline: cannot acquire lock for issue #${issueIid} at '${wtPath}' — reason: ${lockResult.reason}`,
340
+ { existingLock: lockResult.existingLock, reason: lockResult.reason },
341
+ );
342
+ }
343
+
344
+ // -------------------------------------------------------------------------
345
+ // Step 4: Draft-MR creation hook (policy-gated; non-blocking).
346
+ // -------------------------------------------------------------------------
347
+ if (context.draftMrPolicy && context.draftMrPolicy !== 'off') {
348
+ try {
349
+ const mrResult = await draftMrCreator({
350
+ vcs: context.vcs ?? 'gitlab',
351
+ issueIid: context.issueIid,
352
+ issueTitle: context.issueTitle,
353
+ branchName: context.branchName,
354
+ parentRunId: context.parentRunId,
355
+ worktreePath: wtPath,
356
+ draftMrPolicy: context.draftMrPolicy,
357
+ });
358
+ // Non-blocking: log result but never throw upward.
359
+ if (mrResult.created) {
360
+ console.error(`[worktree-pipeline] draft MR created: ${mrResult.mrUrl}`);
361
+ } else if (mrResult.existing) {
362
+ console.error(`[worktree-pipeline] draft MR already exists: ${mrResult.mrUrl}`);
363
+ } else if (mrResult.deferred) {
364
+ console.error('[worktree-pipeline] draft MR deferred (policy=on-green); orchestrator triggers later');
365
+ } else if (mrResult.error) {
366
+ console.error(`[worktree-pipeline] draft MR failed (non-fatal): ${mrResult.error}`);
367
+ }
368
+ } catch (err) {
369
+ // Never let MR-draft failure abort the pipeline.
370
+ console.error(`[worktree-pipeline] draft MR threw (non-fatal): ${err.message}`);
371
+ }
372
+ }
373
+
374
+ // -------------------------------------------------------------------------
375
+ // Step 5: Run the inner loop.
376
+ // -------------------------------------------------------------------------
377
+ let loopState;
378
+ let loopError = null;
379
+
380
+ try {
381
+ loopState = await loopRunner({
382
+ mode: 'deep',
383
+ maxSessions: 5,
384
+ parentRunId,
385
+ worktreePath: wtPath,
386
+ ...killSwitchOpts,
387
+ });
388
+ } catch (err) {
389
+ loopError = err;
390
+ // Build a minimal fallback state so teardown can still run.
391
+ loopState = {
392
+ autopilot_run_id: `error-${issueIid}-${nowMs()}`,
393
+ kill_switch: 'failed-wave',
394
+ kill_switch_detail: err?.message ?? String(err),
395
+ iterations_completed: 0,
396
+ stall_recovery_count: 0,
397
+ };
398
+ }
399
+
400
+ // -------------------------------------------------------------------------
401
+ // Step 6: Teardown worktree.
402
+ // -------------------------------------------------------------------------
403
+
404
+ /** @type {StoryResult} */
405
+ const result = {
406
+ issueIid,
407
+ worktreePath: wtPath,
408
+ runId: loopState.autopilot_run_id ?? `story-${issueIid}-${nowMs()}`,
409
+ killSwitch: loopState.kill_switch ?? null,
410
+ killSwitchDetail: loopState.kill_switch_detail ?? null,
411
+ iterationsCompleted: loopState.iterations_completed ?? 0,
412
+ spiralRecoveryCount: loopState.stall_recovery_count ?? 0,
413
+ commitDependency: null,
414
+ abortedByCohort: loopState.kill_switch === 'peer-abort',
415
+ // Internal: used by teardownWorktree to release the lock.
416
+ _lockSessionId: lockSessionId,
417
+ };
418
+
419
+ await teardownWorktree(context, result, { gcOnExit });
420
+
421
+ // Re-throw loop errors only after teardown has been attempted.
422
+ if (loopError !== null) {
423
+ throw loopError;
424
+ }
425
+
426
+ // Strip internal field before returning to caller.
427
+ const { _lockSessionId: _removed, ...publicResult } = result;
428
+
429
+ // Suppress unused-variable lint warning — _removed is intentionally discarded.
430
+ void _removed;
431
+
432
+ return publicResult;
433
+ }
434
+
435
+ // ---------------------------------------------------------------------------
436
+ // enterWorktree — Worktree-Auto-Promotion (#574, Epic #568 Phase 3.1)
437
+ // ---------------------------------------------------------------------------
438
+
439
+ /** Valid git branch character set — mirrors isValidBranch from session-id.mjs. */
440
+ const ENTER_WORKTREE_BRANCH_RE = /^[a-zA-Z0-9._/-]+$/;
441
+
442
+ /**
443
+ * Create a sibling git worktree for Worktree-Auto-Promotion (#574, Epic #568 P3.1).
444
+ *
445
+ * Path layout: `<basePath>/<basename(repoRoot)>-<sessionId>/`
446
+ *
447
+ * Example:
448
+ * enterWorktree({
449
+ * basePath: '/Users/foo/Projects',
450
+ * sessionId: 'main-2026-05-27-deep-2',
451
+ * branch: 'main',
452
+ * repoRoot: '/Users/foo/Projects/myrepo',
453
+ * })
454
+ * → /Users/foo/Projects/myrepo-main-2026-05-27-deep-2/
455
+ *
456
+ * This is structurally distinct from `setupWorktree`: setupWorktree creates
457
+ * `<worktreeRoot>/<repoBasename>/<issueIid>` (2-level nested); enterWorktree
458
+ * creates `<basePath>/<repoBasename>-<sessionId>` (sibling, 1-level flat) to
459
+ * satisfy the PRD §3 P3 Gherkin row-1 layout requirement.
460
+ *
461
+ * Idempotency: if the target worktree path already exists and contains `.git`,
462
+ * returns `{ wtPath, reused: true }` without re-running `git worktree add`.
463
+ *
464
+ * Security: applies the same `realpathSync` + `validateWorkspacePath` boundary
465
+ * check as `setupWorktree` (CWE-23 / SEC-013 defence-in-depth). Throws
466
+ * `WorktreeBoundaryError` if the computed path escapes `basePath`.
467
+ *
468
+ * Branch handling: if the branch already exists (verified via
469
+ * `git rev-parse --verify <branch>`), use `git worktree add <wtPath> <branch>`
470
+ * (reuse). Otherwise use `git worktree add -b <branch> <wtPath>` (create new).
471
+ * This differs from `setupWorktree`, which always passes `-b`.
472
+ *
473
+ * @param {object} params
474
+ * @param {string} params.basePath - Parent directory where the new worktree goes (absolute).
475
+ * @param {string} params.sessionId - Semantic session-ID matching SEMANTIC_ID_RE.
476
+ * @param {string} params.branch - Branch name (existing or new) matching ENTER_WORKTREE_BRANCH_RE.
477
+ * @param {string} params.repoRoot - Path to the source git repository (passed explicitly to avoid CWD drift per #219).
478
+ * @param {object} [opts]
479
+ * @param {Function} [opts.$] - zx-like template-tag executor (DI seam); falls back to lazy `await import('zx')`.
480
+ * @returns {Promise<{ wtPath: string, reused: boolean }>}
481
+ * @throws {TypeError} when any required param is missing or fails validation.
482
+ * @throws {WorktreeBoundaryError} when the computed worktree path escapes `basePath`.
483
+ */
484
+ export async function enterWorktree({ basePath, sessionId, branch, repoRoot } = {}, opts = {}) {
485
+ // -------------------------------------------------------------------------
486
+ // Step 1: Input validation (TypeError on any malformed param).
487
+ // -------------------------------------------------------------------------
488
+ if (typeof basePath !== 'string' || basePath.length === 0) {
489
+ throw new TypeError('enterWorktree: basePath must be a non-empty string');
490
+ }
491
+ if (!path.isAbsolute(basePath)) {
492
+ throw new TypeError(`enterWorktree: basePath must be an absolute path (got '${basePath}')`);
493
+ }
494
+
495
+ if (typeof sessionId !== 'string' || sessionId.length === 0) {
496
+ throw new TypeError('enterWorktree: sessionId must be a non-empty string');
497
+ }
498
+ if (!SEMANTIC_ID_RE.test(sessionId)) {
499
+ throw new TypeError(
500
+ `enterWorktree: sessionId '${sessionId}' does not match SEMANTIC_ID_RE`,
501
+ );
502
+ }
503
+
504
+ if (typeof branch !== 'string' || branch.length === 0) {
505
+ throw new TypeError('enterWorktree: branch must be a non-empty string');
506
+ }
507
+ if (!ENTER_WORKTREE_BRANCH_RE.test(branch)) {
508
+ throw new TypeError(
509
+ `enterWorktree: branch '${branch}' contains invalid characters (allowed: [a-zA-Z0-9._/-])`,
510
+ );
511
+ }
512
+
513
+ if (typeof repoRoot !== 'string' || repoRoot.length === 0) {
514
+ throw new TypeError('enterWorktree: repoRoot must be a non-empty string');
515
+ }
516
+ if (!path.isAbsolute(repoRoot)) {
517
+ throw new TypeError(`enterWorktree: repoRoot must be an absolute path (got '${repoRoot}')`);
518
+ }
519
+ if (!fs.existsSync(repoRoot)) {
520
+ throw new TypeError(`enterWorktree: repoRoot '${repoRoot}' does not exist`);
521
+ }
522
+
523
+ // -------------------------------------------------------------------------
524
+ // Step 2: Lazy zx DI (Pipeline 3848 commit 1347c7a — mandatory for vi.mock).
525
+ // -------------------------------------------------------------------------
526
+ const exec = opts.$ ?? (await import('zx')).$;
527
+
528
+ // -------------------------------------------------------------------------
529
+ // Step 3: Path resolution + boundary check (mirrors setupWorktree lines 154-187).
530
+ // -------------------------------------------------------------------------
531
+ let resolvedBasePath;
532
+ try {
533
+ resolvedBasePath = realpathSync(basePath);
534
+ } catch {
535
+ // basePath missing — fall back to unresolved; validateWorkspacePath
536
+ // will still catch string-level traversal attempts.
537
+ resolvedBasePath = basePath;
538
+ }
539
+
540
+ // Resolve repoRoot to obtain a stable basename (defends against symlinked repos).
541
+ let resolvedRepoRoot;
542
+ try {
543
+ resolvedRepoRoot = realpathSync(repoRoot);
544
+ } catch {
545
+ resolvedRepoRoot = repoRoot;
546
+ }
547
+ const repoName = path.basename(resolvedRepoRoot);
548
+
549
+ const wtPath = path.join(resolvedBasePath, `${repoName}-${sessionId}`);
550
+
551
+ // Resolve symlinks in wtPath to prevent symlink-escape between path
552
+ // computation and the eventual git worktree add call.
553
+ let resolvedWtPath;
554
+ try {
555
+ resolvedWtPath = realpathSync(wtPath);
556
+ } catch (err) {
557
+ if (err.code !== 'ENOENT') throw err;
558
+ resolvedWtPath = wtPath; // path doesn't exist yet — no symlink to resolve
559
+ }
560
+
561
+ // SEC-013 / ADR-364: validate resolved path BEFORE any filesystem write.
562
+ const valid = validateWorkspacePath(resolvedWtPath, resolvedBasePath);
563
+ if (!valid) {
564
+ process.stderr.write(
565
+ `enterWorktree: refusing to create symlink-escape: ${wtPath} → ${resolvedWtPath}\n`,
566
+ );
567
+ throw new WorktreeBoundaryError(
568
+ `enterWorktree: computed path '${resolvedWtPath}' escapes basePath '${resolvedBasePath}'`,
569
+ { computed: resolvedWtPath, root: resolvedBasePath },
570
+ );
571
+ }
572
+
573
+ // -------------------------------------------------------------------------
574
+ // Step 4: Idempotency — reuse if worktree already exists with .git.
575
+ // -------------------------------------------------------------------------
576
+ if (fs.existsSync(wtPath) && fs.existsSync(path.join(wtPath, '.git'))) {
577
+ return { wtPath, reused: true };
578
+ }
579
+
580
+ // -------------------------------------------------------------------------
581
+ // Step 5: Detect whether branch already exists, then `git worktree add`.
582
+ // -------------------------------------------------------------------------
583
+ let branchExists = false;
584
+ try {
585
+ await exec`git -C ${repoRoot} rev-parse --verify ${branch}`;
586
+ branchExists = true;
587
+ } catch {
588
+ // Branch does not exist — fall through to create-new path with `-b`.
589
+ }
590
+
591
+ if (branchExists) {
592
+ await exec`git -C ${repoRoot} worktree add ${wtPath} ${branch}`;
593
+ } else {
594
+ await exec`git -C ${repoRoot} worktree add -b ${branch} ${wtPath}`;
595
+ }
596
+
597
+ // -------------------------------------------------------------------------
598
+ // Step 6: WARN to stderr (PRD §3 P3 Gherkin row-1 + #574 DoD).
599
+ // -------------------------------------------------------------------------
600
+ console.warn(
601
+ `enterWorktree: created sibling worktree at ${wtPath} (branch=${branch}, sessionId=${sessionId})`,
602
+ );
603
+
604
+ return { wtPath, reused: false };
605
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * autopilot-telemetry.mjs — Backward-compat re-export shim.
3
+ *
4
+ * The telemetry implementation has been relocated to
5
+ * `scripts/lib/autopilot/telemetry.mjs` as part of the W1A6 decomposition.
6
+ * This file is kept as a thin re-export so existing direct importers
7
+ * (e.g. tests/lib/autopilot-telemetry.test.mjs) continue to resolve
8
+ * without modification.
9
+ */
10
+
11
+ export * from './autopilot/telemetry.mjs';
@@ -0,0 +1,39 @@
1
+ /**
2
+ * autopilot.mjs — Thin barrel re-exporting all public autopilot symbols.
3
+ *
4
+ * W1A6 decomposition: the ~418 LOC monolith has been split into four
5
+ * focused submodules under `autopilot/`. This file is now a pure aggregation
6
+ * barrel — all business logic lives in the submodules.
7
+ *
8
+ * Public API (12 exports — all backward-compat):
9
+ * From autopilot/kill-switches.mjs:
10
+ * KILL_SWITCHES
11
+ * From autopilot/flags.mjs:
12
+ * FLAG_BOUNDS, DEFAULT_PEER_ABORT_THRESHOLD, DEFAULT_JSONL_PATH,
13
+ * DEFAULT_CARRYOVER_THRESHOLD, parseFlags
14
+ * From autopilot/telemetry.mjs:
15
+ * SCHEMA_VERSION, writeAutopilotJsonl, defaultRunId, readHostClass,
16
+ * finalizeState
17
+ * From autopilot/loop.mjs:
18
+ * runLoop
19
+ */
20
+
21
+ export { KILL_SWITCHES } from './autopilot/kill-switches.mjs';
22
+
23
+ export {
24
+ FLAG_BOUNDS,
25
+ DEFAULT_PEER_ABORT_THRESHOLD,
26
+ DEFAULT_JSONL_PATH,
27
+ DEFAULT_CARRYOVER_THRESHOLD,
28
+ parseFlags,
29
+ } from './autopilot/flags.mjs';
30
+
31
+ export {
32
+ SCHEMA_VERSION,
33
+ writeAutopilotJsonl,
34
+ defaultRunId,
35
+ readHostClass,
36
+ finalizeState,
37
+ } from './autopilot/telemetry.mjs';
38
+
39
+ export { runLoop } from './autopilot/loop.mjs';