@cohortapp/agent-sdk 2.16.0 → 2.18.4

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 (529) hide show
  1. package/.claude/settings.json +18 -0
  2. package/.env.example +23 -7
  3. package/README.md +1 -0
  4. package/bin/maestro.mjs +62 -0
  5. package/docs/guides/billing-console-keys.md +60 -0
  6. package/docs/guides/front-door-session.md +54 -9
  7. package/docs/guides/mac-mini.md +20 -25
  8. package/docs/guides/poller-daemon-setup.md +4 -1
  9. package/docs/guides/setup-wizard.md +1 -1
  10. package/docs/runbooks/fleet-rollout.md +156 -0
  11. package/docs/runbooks/mac-mini-bootstrap.md +12 -14
  12. package/lib/action-executor.js +19 -3
  13. package/lib/budget-guard.mjs +279 -3
  14. package/lib/channels/base-adapter.mjs +3 -1
  15. package/lib/channels/contract.mjs +2 -1
  16. package/lib/channels/inbox-item.mjs +8 -0
  17. package/lib/claude-bin.mjs +5 -6
  18. package/lib/cli/doctor-checks.mjs +141 -10
  19. package/lib/cli/global-setup-extras.mjs +5 -1
  20. package/lib/cli/inbox.mjs +100 -15
  21. package/lib/cli/seat-auth.mjs +463 -0
  22. package/lib/cli/session.mjs +80 -12
  23. package/lib/collective/capture.mjs +8 -6
  24. package/lib/collective/global-config.mjs +63 -1
  25. package/lib/collective/presence.mjs +142 -5
  26. package/lib/comms/send-gate.mjs +559 -1
  27. package/lib/context/budget.mjs +327 -0
  28. package/lib/context/history-scope.mjs +138 -0
  29. package/lib/diagnostics/alerts.mjs +49 -0
  30. package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
  31. package/lib/engine/agents/definitions.mjs +343 -0
  32. package/lib/engine/agents/persist.mjs +275 -0
  33. package/lib/engine/agents/runtime.mjs +748 -0
  34. package/lib/engine/agents/usage.mjs +95 -0
  35. package/lib/engine/auth-status.mjs +139 -0
  36. package/lib/engine/budget.mjs +194 -0
  37. package/lib/engine/cli.mjs +1204 -0
  38. package/lib/engine/commands/index.mjs +269 -0
  39. package/lib/engine/context/budget.mjs +219 -0
  40. package/lib/engine/context/cache.mjs +125 -0
  41. package/lib/engine/context/child-env.mjs +215 -0
  42. package/lib/engine/context/compaction.mjs +342 -0
  43. package/lib/engine/context/images.mjs +90 -0
  44. package/lib/engine/context/instructions.mjs +327 -0
  45. package/lib/engine/context/lazy-instructions.mjs +169 -0
  46. package/lib/engine/context/manager.mjs +182 -0
  47. package/lib/engine/context/real-path.mjs +91 -0
  48. package/lib/engine/context/secret-values.mjs +163 -0
  49. package/lib/engine/context/settings.mjs +274 -0
  50. package/lib/engine/context/stream-input.mjs +159 -0
  51. package/lib/engine/guard.mjs +152 -0
  52. package/lib/engine/hooks.mjs +713 -0
  53. package/lib/engine/loop.mjs +560 -0
  54. package/lib/engine/mcp/client.mjs +254 -0
  55. package/lib/engine/mcp/config.mjs +301 -0
  56. package/lib/engine/mcp/http.mjs +201 -0
  57. package/lib/engine/mcp/index.mjs +146 -0
  58. package/lib/engine/mcp/jsonrpc.mjs +147 -0
  59. package/lib/engine/mcp/naming.mjs +66 -0
  60. package/lib/engine/mcp/resources.mjs +89 -0
  61. package/lib/engine/mcp/results.mjs +133 -0
  62. package/lib/engine/mcp/stdio.mjs +137 -0
  63. package/lib/engine/mcp/supervisor.mjs +116 -0
  64. package/lib/engine/messages.mjs +104 -0
  65. package/lib/engine/output/json.mjs +164 -0
  66. package/lib/engine/output/stream-json.mjs +266 -0
  67. package/lib/engine/permissions.mjs +845 -0
  68. package/lib/engine/process-identity.mjs +164 -0
  69. package/lib/engine/process-tree.mjs +551 -0
  70. package/lib/engine/prompt.mjs +60 -0
  71. package/lib/engine/session/store.mjs +299 -0
  72. package/lib/engine/session-runtime/args.mjs +97 -0
  73. package/lib/engine/session-runtime/host.mjs +143 -0
  74. package/lib/engine/session-runtime/inbox.mjs +122 -0
  75. package/lib/engine/session-runtime/notifications.mjs +129 -0
  76. package/lib/engine/session-runtime/registry.mjs +328 -0
  77. package/lib/engine/session-runtime/runner.mjs +344 -0
  78. package/lib/engine/session-runtime/socket.mjs +212 -0
  79. package/lib/engine/session-runtime/wakeup.mjs +115 -0
  80. package/lib/engine/skills/index.mjs +321 -0
  81. package/lib/engine/tools/bash-background.mjs +533 -0
  82. package/lib/engine/tools/bash.mjs +216 -0
  83. package/lib/engine/tools/edit.mjs +97 -0
  84. package/lib/engine/tools/glob.mjs +81 -0
  85. package/lib/engine/tools/grep.mjs +224 -0
  86. package/lib/engine/tools/index.mjs +84 -0
  87. package/lib/engine/tools/list-agents.mjs +32 -0
  88. package/lib/engine/tools/ls.mjs +127 -0
  89. package/lib/engine/tools/monitor.mjs +82 -0
  90. package/lib/engine/tools/notebook-edit.mjs +218 -0
  91. package/lib/engine/tools/read.mjs +103 -0
  92. package/lib/engine/tools/schedule-wakeup.mjs +45 -0
  93. package/lib/engine/tools/schema.mjs +144 -0
  94. package/lib/engine/tools/send-message.mjs +77 -0
  95. package/lib/engine/tools/session.mjs +70 -0
  96. package/lib/engine/tools/todo.mjs +144 -0
  97. package/lib/engine/tools/toolsearch.mjs +217 -0
  98. package/lib/engine/tools/walk.mjs +193 -0
  99. package/lib/engine/tools/web-switch.mjs +31 -0
  100. package/lib/engine/tools/webfetch-html.mjs +387 -0
  101. package/lib/engine/tools/webfetch-net.mjs +340 -0
  102. package/lib/engine/tools/webfetch.mjs +198 -0
  103. package/lib/engine/tools/websearch.mjs +91 -0
  104. package/lib/engine/tools/workflow.mjs +95 -0
  105. package/lib/engine/tools/write.mjs +76 -0
  106. package/lib/engine/tui/line-editor.mjs +137 -0
  107. package/lib/engine/tui/render.mjs +86 -0
  108. package/lib/engine/tui/tui.mjs +274 -0
  109. package/lib/engine/wire/anthropic-messages.mjs +263 -0
  110. package/lib/engine/wire/effort.mjs +36 -0
  111. package/lib/engine/wire/errors.mjs +496 -0
  112. package/lib/engine/wire/http.mjs +441 -0
  113. package/lib/engine/wire/index.mjs +76 -0
  114. package/lib/engine/wire/openai-chat.mjs +332 -0
  115. package/lib/engine/wire/prompt-cache.mjs +79 -0
  116. package/lib/engine/wire/search.mjs +140 -0
  117. package/lib/engine/wire/sse.mjs +114 -0
  118. package/lib/engine/wire/stall.mjs +349 -0
  119. package/lib/engine/wire/token-provider.mjs +175 -0
  120. package/lib/engine/wire/usage.mjs +192 -0
  121. package/lib/engine/workflow/host.mjs +524 -0
  122. package/lib/engine/workflow/journal.mjs +188 -0
  123. package/lib/engine/workflow/json-schema.mjs +171 -0
  124. package/lib/engine/workflow/meta.mjs +329 -0
  125. package/lib/engine/workflow/notifications.mjs +52 -0
  126. package/lib/engine/workflow/runtime.mjs +447 -0
  127. package/lib/engine/workflow/sandbox.mjs +534 -0
  128. package/lib/engine/workflow/worker.mjs +141 -0
  129. package/lib/engine/workflow/worktree.mjs +74 -0
  130. package/lib/execution/disposition.mjs +1 -1
  131. package/lib/execution/intake.mjs +10 -0
  132. package/lib/execution/surface-policy.mjs +15 -0
  133. package/lib/learning/curator.mjs +8 -6
  134. package/lib/learning/reflect.mjs +8 -6
  135. package/lib/model-router/catalog/cohort.yaml +137 -0
  136. package/lib/model-router/catalog.mjs +118 -1
  137. package/lib/model-router/economics.mjs +9 -0
  138. package/lib/model-router/failover.mjs +67 -16
  139. package/lib/model-router/llm-task.mjs +39 -3
  140. package/lib/model-router/resolve.mjs +95 -3
  141. package/lib/model-router/spawn.mjs +46 -47
  142. package/lib/model-router/taxonomy.mjs +126 -4
  143. package/lib/org/cost-sync.mjs +141 -11
  144. package/lib/org/inbound/broadcast.mjs +289 -0
  145. package/lib/org/inbound/collective.mjs +375 -0
  146. package/lib/org/inbound/directedness.mjs +96 -8
  147. package/lib/org/inbound/facts.mjs +82 -4
  148. package/lib/org/inbound/hydrate.mjs +555 -51
  149. package/lib/org/inbound/project.mjs +22 -0
  150. package/lib/org/inbound/surfaces.mjs +14 -0
  151. package/lib/org/llm-token.mjs +879 -0
  152. package/lib/org/mesh.mjs +61 -0
  153. package/lib/org/messaging.mjs +3 -1
  154. package/lib/org/protocol.checksum +1 -1
  155. package/lib/org/protocol.mjs +15 -0
  156. package/lib/org/quota.mjs +520 -0
  157. package/lib/org/tool-surface.mjs +104 -16
  158. package/lib/org/ui-parity.mjs +16 -1
  159. package/lib/org/work-ledger.mjs +37 -6
  160. package/lib/rate-guard.mjs +114 -1
  161. package/lib/resource-governor.mjs +41 -6
  162. package/lib/runtime/adapter.mjs +823 -0
  163. package/lib/runtime/child-env.mjs +191 -0
  164. package/lib/runtime/legacy-shell-guard.mjs +97 -0
  165. package/lib/runtime/seat-engine.mjs +162 -0
  166. package/lib/session/ask-ledger.mjs +271 -0
  167. package/lib/session/current-work.mjs +676 -0
  168. package/lib/session/feed-core.mjs +40 -3
  169. package/lib/session/launch-args.mjs +56 -4
  170. package/lib/session/status-summary.mjs +26 -9
  171. package/lib/session/upgrade-notice.mjs +42 -0
  172. package/lib/setup/claude-probe.mjs +117 -13
  173. package/lib/setup/enrich.mjs +13 -10
  174. package/lib/setup/sections/model.mjs +39 -13
  175. package/lib/telemetry/collect.mjs +208 -9
  176. package/lib/upgrade/ignored-drift.mjs +105 -0
  177. package/lib/voice/post-call-brief.mjs +30 -17
  178. package/package.json +15 -3
  179. package/plugins/maestro-skills/skills/board-work.md +5 -0
  180. package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
  181. package/plugins/maestro-skills/skills/main-session.md +18 -7
  182. package/scripts/ci/check-tarball-fidelity.mjs +126 -2
  183. package/scripts/ci/run-tests.mjs +47 -19
  184. package/scripts/cohort-llm/api-key-helper.mjs +92 -0
  185. package/scripts/collective/hook-runner.mjs +29 -2
  186. package/scripts/continuous-monitor.sh +13 -0
  187. package/scripts/cost/track-claude-usage.mjs +15 -0
  188. package/scripts/daemon/agent-daemon.mjs +408 -20
  189. package/scripts/daemon/assurance.mjs +48 -12
  190. package/scripts/daemon/cadence-consumer.mjs +218 -68
  191. package/scripts/daemon/cadence-handlers.mjs +73 -4
  192. package/scripts/daemon/classifier.mjs +75 -26
  193. package/scripts/daemon/context-compiler.mjs +104 -59
  194. package/scripts/daemon/deliver.mjs +30 -1
  195. package/scripts/daemon/dispatcher.mjs +804 -157
  196. package/scripts/daemon/health.mjs +14 -1
  197. package/scripts/daemon/lib/session-router.mjs +310 -42
  198. package/scripts/daemon/maestro-daemon.mjs +11 -0
  199. package/scripts/daemon/prompt-builder.mjs +121 -12
  200. package/scripts/daemon/responder.mjs +315 -146
  201. package/scripts/daemon/sdk-version.mjs +98 -16
  202. package/scripts/eval/probe-gateway.mjs +635 -0
  203. package/scripts/eval/replay/extract.mjs +270 -0
  204. package/scripts/eval/replay/grade.mjs +260 -0
  205. package/scripts/eval/replay/lib/config.mjs +50 -0
  206. package/scripts/eval/replay/lib/effects.mjs +65 -0
  207. package/scripts/eval/replay/lib/fixture.mjs +188 -0
  208. package/scripts/eval/replay/lib/judge.mjs +72 -0
  209. package/scripts/eval/replay/lib/redact.mjs +136 -0
  210. package/scripts/eval/replay/lib/sandbox.mjs +170 -0
  211. package/scripts/eval/replay/lib/schema-check.mjs +63 -0
  212. package/scripts/eval/replay/lib/transcript.mjs +76 -0
  213. package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
  214. package/scripts/eval/replay/report.mjs +185 -0
  215. package/scripts/eval/replay/run.mjs +404 -0
  216. package/scripts/fleet/rollout.mjs +1094 -0
  217. package/scripts/hooks/pre-send-audit.sh +36 -245
  218. package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
  219. package/scripts/hooks/validate-state-yaml.sh +190 -0
  220. package/scripts/huddle/huddle-llm.mjs +361 -0
  221. package/scripts/huddle/huddle-server.mjs +46 -121
  222. package/scripts/local-triggers/autoupdate.sh +448 -78
  223. package/scripts/local-triggers/run-trigger.sh +13 -0
  224. package/scripts/maintenance/pin-integrity.mjs +364 -0
  225. package/scripts/poll-slack-events.sh +41 -9
  226. package/scripts/poller/slack-socket-mode.mjs +28 -3
  227. package/scripts/session/supervisor.mjs +80 -13
  228. package/scripts/spawn-session.sh +13 -0
  229. package/bin/maestro.test.mjs +0 -1574
  230. package/lib/action-executor.test.mjs +0 -871
  231. package/lib/archetype.test.mjs +0 -132
  232. package/lib/assurance/plan-note.test.mjs +0 -234
  233. package/lib/assurance/room-budget.test.mjs +0 -486
  234. package/lib/assurance/tier.test.mjs +0 -174
  235. package/lib/autonomy.test.mjs +0 -66
  236. package/lib/backlog.test.mjs +0 -302
  237. package/lib/backup/policy.test.mjs +0 -305
  238. package/lib/budget-escalate.test.mjs +0 -232
  239. package/lib/budget-guard.envelope.test.mjs +0 -476
  240. package/lib/budget-guard.test.mjs +0 -427
  241. package/lib/cadence-bus-requeue.test.mjs +0 -83
  242. package/lib/cadence-bus-schedule.test.mjs +0 -194
  243. package/lib/cadence-bus.test.mjs +0 -720
  244. package/lib/cadences.test.mjs +0 -230
  245. package/lib/capability/inventory.test.mjs +0 -232
  246. package/lib/capability.test.mjs +0 -78
  247. package/lib/channels/base-adapter.test.mjs +0 -590
  248. package/lib/channels/channels.test.mjs +0 -371
  249. package/lib/channels/contract.test.mjs +0 -162
  250. package/lib/channels/inbox-item.test.mjs +0 -368
  251. package/lib/channels/orgmail/adapter.test.mjs +0 -448
  252. package/lib/channels/pairing.test.mjs +0 -270
  253. package/lib/channels/repeat-suppressor.test.mjs +0 -134
  254. package/lib/channels/slack-adapter.test.mjs +0 -212
  255. package/lib/channels/telegram-adapter.test.mjs +0 -306
  256. package/lib/channels/voice/adapter.test.mjs +0 -278
  257. package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
  258. package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
  259. package/lib/charter.test.mjs +0 -89
  260. package/lib/claude-bin.test.mjs +0 -131
  261. package/lib/cli/board.test.mjs +0 -227
  262. package/lib/cli/design.test.mjs +0 -270
  263. package/lib/cli/doctor-checks.test.mjs +0 -336
  264. package/lib/cli/global-setup-extras.test.mjs +0 -462
  265. package/lib/cli/inbox.test.mjs +0 -230
  266. package/lib/cli/session-ack.test.mjs +0 -63
  267. package/lib/cli/session.test.mjs +0 -613
  268. package/lib/collective/capture.test.mjs +0 -121
  269. package/lib/collective/cards.test.mjs +0 -114
  270. package/lib/collective/config.test.mjs +0 -123
  271. package/lib/collective/global-config.test.mjs +0 -220
  272. package/lib/collective/global-skills.test.mjs +0 -126
  273. package/lib/collective/presence.test.mjs +0 -95
  274. package/lib/collective/recall.test.mjs +0 -116
  275. package/lib/collective/vendor-skills.test.mjs +0 -306
  276. package/lib/comms/send-gate.test.mjs +0 -770
  277. package/lib/comms.test.mjs +0 -41
  278. package/lib/cost/ledger-row.test.mjs +0 -183
  279. package/lib/design/design-md.test.mjs +0 -318
  280. package/lib/design/fixtures/DESIGN.golden.md +0 -238
  281. package/lib/design/fixtures/PRODUCT.golden.md +0 -67
  282. package/lib/design/fixtures/foundation.json +0 -133
  283. package/lib/design/refresh-gate.test.mjs +0 -144
  284. package/lib/design/write.test.mjs +0 -241
  285. package/lib/diagnostics/alerts.test.mjs +0 -318
  286. package/lib/diagnostics/backup-freshness.test.mjs +0 -185
  287. package/lib/diagnostics/counters.test.mjs +0 -206
  288. package/lib/diagnostics/events.test.mjs +0 -290
  289. package/lib/diagnostics/otel.test.mjs +0 -196
  290. package/lib/diagnostics/trace.test.mjs +0 -251
  291. package/lib/env-compat.test.mjs +0 -104
  292. package/lib/execution/disposition.test.mjs +0 -553
  293. package/lib/execution/drive.test.mjs +0 -270
  294. package/lib/execution/effects.test.mjs +0 -344
  295. package/lib/execution/intake.test.mjs +0 -389
  296. package/lib/execution/journal.test.mjs +0 -261
  297. package/lib/execution/match.test.mjs +0 -235
  298. package/lib/execution/pipeline.test.mjs +0 -392
  299. package/lib/execution/route.test.mjs +0 -186
  300. package/lib/execution/surface-policy.test.mjs +0 -162
  301. package/lib/fs-atomic.test.mjs +0 -72
  302. package/lib/fs-ownership.test.mjs +0 -158
  303. package/lib/goals/admission.test.mjs +0 -164
  304. package/lib/goals/classify.test.mjs +0 -167
  305. package/lib/goals/collaborate.test.mjs +0 -336
  306. package/lib/goals/gaps.test.mjs +0 -284
  307. package/lib/goals/loop.test.mjs +0 -845
  308. package/lib/hooks/bus.test.mjs +0 -387
  309. package/lib/identity/persona.test.mjs +0 -142
  310. package/lib/kpi-sensors.test.mjs +0 -278
  311. package/lib/kpi.test.mjs +0 -244
  312. package/lib/learning/config.test.mjs +0 -75
  313. package/lib/learning/counters.test.mjs +0 -69
  314. package/lib/learning/curator-consolidate.test.mjs +0 -238
  315. package/lib/learning/curator.test.mjs +0 -106
  316. package/lib/learning/reflect.test.mjs +0 -0
  317. package/lib/learning/session-index.test.mjs +0 -125
  318. package/lib/learning/skill-writer.test.mjs +0 -210
  319. package/lib/mandate/audit.test.mjs +0 -195
  320. package/lib/mandate/contract.test.mjs +0 -185
  321. package/lib/mandate/derive.test.mjs +0 -274
  322. package/lib/mandate/model.test.mjs +0 -164
  323. package/lib/mandate/refresh.test.mjs +0 -389
  324. package/lib/mcp/server.test.mjs +0 -426
  325. package/lib/model-router/auth-profiles.test.mjs +0 -580
  326. package/lib/model-router/catalog.test.mjs +0 -385
  327. package/lib/model-router/economics.test.mjs +0 -438
  328. package/lib/model-router/failover.test.mjs +0 -439
  329. package/lib/model-router/health.test.mjs +0 -338
  330. package/lib/model-router/integration-coverage.test.mjs +0 -831
  331. package/lib/model-router/integration.test.mjs +0 -564
  332. package/lib/model-router/ledger.test.mjs +0 -415
  333. package/lib/model-router/llm-task.test.mjs +0 -392
  334. package/lib/model-router/org-credentials.test.mjs +0 -265
  335. package/lib/model-router/pricing-refresh.test.mjs +0 -286
  336. package/lib/model-router/reconcile.test.mjs +0 -316
  337. package/lib/model-router/repair.test.mjs +0 -180
  338. package/lib/model-router/spawn.test.mjs +0 -446
  339. package/lib/model-router/taxonomy.test.mjs +0 -410
  340. package/lib/model-router.test.mjs +0 -1207
  341. package/lib/org/activity.test.mjs +0 -134
  342. package/lib/org/approvals.test.mjs +0 -216
  343. package/lib/org/awareness.test.mjs +0 -159
  344. package/lib/org/board-mine-cache.test.mjs +0 -53
  345. package/lib/org/board.test.mjs +0 -187
  346. package/lib/org/bootstrap-context.test.mjs +0 -153
  347. package/lib/org/client.test.mjs +0 -1206
  348. package/lib/org/cohort-client.test.mjs +0 -126
  349. package/lib/org/cost-sync.test.mjs +0 -153
  350. package/lib/org/doctor.test.mjs +0 -346
  351. package/lib/org/engagement-ledger.test.mjs +0 -112
  352. package/lib/org/engagement.test.mjs +0 -739
  353. package/lib/org/handoff.test.mjs +0 -269
  354. package/lib/org/inbound/directedness.test.mjs +0 -668
  355. package/lib/org/inbound/facts.test.mjs +0 -471
  356. package/lib/org/inbound/hydrate.test.mjs +0 -453
  357. package/lib/org/inbound/index.test.mjs +0 -429
  358. package/lib/org/inbound/project.test.mjs +0 -287
  359. package/lib/org/integration-tools.test.mjs +0 -160
  360. package/lib/org/keys.test.mjs +0 -92
  361. package/lib/org/knowledge.test.mjs +0 -326
  362. package/lib/org/leases.test.mjs +0 -235
  363. package/lib/org/mesh-directives.test.mjs +0 -110
  364. package/lib/org/mesh-integration.test.mjs +0 -127
  365. package/lib/org/mesh.test.mjs +0 -400
  366. package/lib/org/messaging.test.mjs +0 -471
  367. package/lib/org/param-contract.test.mjs +0 -477
  368. package/lib/org/policy.test.mjs +0 -237
  369. package/lib/org/protocol.checksum.test.mjs +0 -90
  370. package/lib/org/protocol.test.mjs +0 -323
  371. package/lib/org/push.test.mjs +0 -792
  372. package/lib/org/registry.test.mjs +0 -100
  373. package/lib/org/resource-tools.test.mjs +0 -361
  374. package/lib/org/tool-access.test.mjs +0 -144
  375. package/lib/org/tool-surface-integration.test.mjs +0 -120
  376. package/lib/org/tool-surface.test.mjs +0 -1268
  377. package/lib/org/typing.test.mjs +0 -291
  378. package/lib/org/ui-parity.test.mjs +0 -560
  379. package/lib/org/verify.test.mjs +0 -194
  380. package/lib/org/work-ledger.test.mjs +0 -273
  381. package/lib/plan/adoption-e2e.test.mjs +0 -366
  382. package/lib/plan/budget-enforcement.test.mjs +0 -400
  383. package/lib/plan/compile.test.mjs +0 -382
  384. package/lib/plan/emit.test.mjs +0 -269
  385. package/lib/plan/explain.test.mjs +0 -188
  386. package/lib/prompts/parallelism.test.mjs +0 -177
  387. package/lib/rag/rag.test.mjs +0 -505
  388. package/lib/rate-guard.test.mjs +0 -272
  389. package/lib/reactive-gate.test.mjs +0 -57
  390. package/lib/render.test.mjs +0 -68
  391. package/lib/resource-governor.test.mjs +0 -488
  392. package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
  393. package/lib/scheduling/jitter.test.mjs +0 -140
  394. package/lib/secrets/broker.test.mjs +0 -280
  395. package/lib/secrets/providers.test.mjs +0 -274
  396. package/lib/security/audit-engine.test.mjs +0 -424
  397. package/lib/security/coerce-args.test.mjs +0 -281
  398. package/lib/security/dangerous-tools.test.mjs +0 -68
  399. package/lib/security/external-content.test.mjs +0 -84
  400. package/lib/security/redact.test.mjs +0 -441
  401. package/lib/security/secret-equal.test.mjs +0 -55
  402. package/lib/session/config.test.mjs +0 -92
  403. package/lib/session/feed-core.test.mjs +0 -198
  404. package/lib/session/first-run.test.mjs +0 -121
  405. package/lib/session/frontdoor.test.mjs +0 -205
  406. package/lib/session/handoffs.test.mjs +0 -183
  407. package/lib/session/identity.test.mjs +0 -180
  408. package/lib/session/inbox-claims.test.mjs +0 -286
  409. package/lib/session/launch-args.test.mjs +0 -157
  410. package/lib/session/liveness.test.mjs +0 -100
  411. package/lib/session/status-summary.test.mjs +0 -118
  412. package/lib/session-permissions.test.mjs +0 -120
  413. package/lib/setup/claude-probe.test.mjs +0 -187
  414. package/lib/setup/completeness.test.mjs +0 -110
  415. package/lib/setup/context-pack.test.mjs +0 -89
  416. package/lib/setup/enrich.test.mjs +0 -115
  417. package/lib/setup/enroll-from-cohort.test.mjs +0 -300
  418. package/lib/setup/integration.test.mjs +0 -162
  419. package/lib/setup/io.test.mjs +0 -77
  420. package/lib/setup/runner.test.mjs +0 -132
  421. package/lib/setup/sections/identity.test.mjs +0 -234
  422. package/lib/setup/sections/inventory.test.mjs +0 -198
  423. package/lib/setup/sections/learning.test.mjs +0 -81
  424. package/lib/setup/sections/mandate.test.mjs +0 -388
  425. package/lib/setup/sections/messaging.test.mjs +0 -127
  426. package/lib/setup/sections/model.test.mjs +0 -240
  427. package/lib/setup/sections/org.test.mjs +0 -346
  428. package/lib/setup/sections/orgmail.test.mjs +0 -118
  429. package/lib/setup/sections/recovery.test.mjs +0 -98
  430. package/lib/setup/sections/subagents.test.mjs +0 -429
  431. package/lib/setup/sections/verify.test.mjs +0 -175
  432. package/lib/setup/sot.test.mjs +0 -81
  433. package/lib/setup/state.test.mjs +0 -115
  434. package/lib/singleton.test.mjs +0 -151
  435. package/lib/subagents/cli.test.mjs +0 -389
  436. package/lib/subagents/client.test.mjs +0 -309
  437. package/lib/subagents/gap.test.mjs +0 -234
  438. package/lib/subagents/lock.test.mjs +0 -248
  439. package/lib/subagents/manifest.test.mjs +0 -175
  440. package/lib/subagents/refs.test.mjs +0 -204
  441. package/lib/subagents/resolve.test.mjs +0 -422
  442. package/lib/subagents/schema.test.mjs +0 -328
  443. package/lib/telemetry/alerts.test.mjs +0 -109
  444. package/lib/telemetry/collect.test.mjs +0 -1274
  445. package/lib/tool-definitions-integration.test.mjs +0 -83
  446. package/lib/tool-definitions.test.mjs +0 -437
  447. package/lib/upgrade/global-refresh.test.mjs +0 -65
  448. package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
  449. package/lib/upgrade/post-steps.test.mjs +0 -200
  450. package/lib/upgrade/verify.test.mjs +0 -164
  451. package/lib/util/fetch-timeout.test.mjs +0 -202
  452. package/lib/util/reconnect.test.mjs +0 -369
  453. package/lib/util/unhandled.test.mjs +0 -216
  454. package/lib/voice/outbound.test.mjs +0 -69
  455. package/lib/voice/session-rotation.test.mjs +0 -114
  456. package/lib/voice/stt.test.mjs +0 -226
  457. package/lib/voice/voice.test.mjs +0 -990
  458. package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
  459. package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
  460. package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
  461. package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
  462. package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
  463. package/scripts/ci/check-skill-packs.test.mjs +0 -495
  464. package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
  465. package/scripts/ci/check.test.mjs +0 -194
  466. package/scripts/ci/conformance-org-api.test.mjs +0 -425
  467. package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
  468. package/scripts/collective/hook-runner.test.mjs +0 -173
  469. package/scripts/cost/fleet-digest.test.mjs +0 -207
  470. package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
  471. package/scripts/cost/track-claude-usage.test.mjs +0 -148
  472. package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
  473. package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
  474. package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
  475. package/scripts/daemon/agent-daemon.test.mjs +0 -995
  476. package/scripts/daemon/assurance-e2e.test.mjs +0 -613
  477. package/scripts/daemon/assurance.test.mjs +0 -1791
  478. package/scripts/daemon/board-mirror.test.mjs +0 -165
  479. package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
  480. package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
  481. package/scripts/daemon/cadence-consumer.test.mjs +0 -776
  482. package/scripts/daemon/cadence-handlers.test.mjs +0 -837
  483. package/scripts/daemon/classifier-identity.test.mjs +0 -137
  484. package/scripts/daemon/classifier.test.mjs +0 -266
  485. package/scripts/daemon/classify-kind.test.mjs +0 -40
  486. package/scripts/daemon/context-compiler.test.mjs +0 -300
  487. package/scripts/daemon/deliver.test.mjs +0 -564
  488. package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
  489. package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
  490. package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
  491. package/scripts/daemon/execution-ladder.test.mjs +0 -470
  492. package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
  493. package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
  494. package/scripts/daemon/inbox-deferral.test.mjs +0 -336
  495. package/scripts/daemon/inbox-wake.test.mjs +0 -199
  496. package/scripts/daemon/integration.test.mjs +0 -149
  497. package/scripts/daemon/lib/self-echo.test.mjs +0 -153
  498. package/scripts/daemon/lib/session-router.test.mjs +0 -295
  499. package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
  500. package/scripts/daemon/prompt-builder.test.mjs +0 -344
  501. package/scripts/daemon/responder-cost.test.mjs +0 -68
  502. package/scripts/daemon/responder-history.test.mjs +0 -185
  503. package/scripts/daemon/sdk-version.test.mjs +0 -31
  504. package/scripts/daemon/session-lock.test.mjs +0 -252
  505. package/scripts/daemon/session-outcomes.test.mjs +0 -533
  506. package/scripts/daemon/typing-registry.test.mjs +0 -102
  507. package/scripts/hooks/pre-send-audit.test.mjs +0 -354
  508. package/scripts/huddle/huddle-prompt.test.mjs +0 -176
  509. package/scripts/local-triggers/autoupdate.test.mjs +0 -518
  510. package/scripts/local-triggers/generate-plists.test.mjs +0 -456
  511. package/scripts/media-generation/brand-clause.test.mjs +0 -135
  512. package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
  513. package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
  514. package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
  515. package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
  516. package/scripts/poller/slack-socket-mode.test.mjs +0 -805
  517. package/scripts/poller-launchd/install.test.mjs +0 -243
  518. package/scripts/restore-from-backup.test.mjs +0 -181
  519. package/scripts/session/feed.test.mjs +0 -196
  520. package/scripts/session/supervisor-sh.test.mjs +0 -218
  521. package/scripts/session/supervisor.test.mjs +0 -482
  522. package/scripts/setup/configure-macos.test.mjs +0 -306
  523. package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
  524. package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
  525. package/scripts/setup/generate-capability.test.mjs +0 -134
  526. package/scripts/setup/init-agent.test.mjs +0 -370
  527. package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
  528. package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
  529. package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
@@ -0,0 +1,191 @@
1
+ /**
2
+ * lib/runtime/child-env.mjs — the ONE child-env builder for every runtime spawn.
3
+ *
4
+ * Every lane that starts an agent runtime (today the `claude` binary) builds its
5
+ * child environment here, through `buildRuntimeEnv`. There are two shapes:
6
+ *
7
+ * STOCK no retarget. The child keeps the seat's own Claude credential
8
+ * (`CLAUDE_CODE_OAUTH_TOKEN`, keychain, or a Console key the lane
9
+ * owns). Foreign `*_API_KEY` / `*_AUTH_TOKEN` / `*_SECRET` /
10
+ * `*_ACCESS_KEY` / `*_PRIVATE_KEY` values are scrubbed (§7.3).
11
+ *
12
+ * RETARGET the router pointed the session at a third-party backend
13
+ * (`ANTHROPIC_BASE_URL` in the retarget set). This is where the old
14
+ * builder leaked: its scrub regex ends in `_AUTH_TOKEN$`, which does
15
+ * not match `CLAUDE_CODE_OAUTH_TOKEN`, so a Max subscription token
16
+ * rode into a child whose base URL was someone else's server. With
17
+ * only a base URL set, "a saved claude.ai login remains the active
18
+ * credential" — the token would have been sent to that server
19
+ * (F1 §5.3). A retarget therefore ALWAYS:
20
+ * - scrubs `CLAUDE_CODE_OAUTH_*` and every `*_OAUTH_TOKEN`;
21
+ * - scrubs every inherited `ANTHROPIC_*` variable, then injects
22
+ * only the allowlisted retarget keys;
23
+ * - refuses (a returned error, never a throw) when the retarget
24
+ * carries no usable `ANTHROPIC_AUTH_TOKEN`, or carries a
25
+ * subscription OAuth token (`sk-ant-oat…`) as that token;
26
+ * - forces `ANTHROPIC_API_KEY=""` (no keychain fallthrough) and
27
+ * `CLAUDE_CODE_ATTRIBUTION_HEADER=0` (a third-party prompt cache
28
+ * is poisoned by the per-request attribution header).
29
+ *
30
+ * Pure: no process.env read, no clock, no I/O. The caller passes the base env.
31
+ *
32
+ * @module lib/runtime/child-env
33
+ */
34
+
35
+ "use strict";
36
+
37
+ /**
38
+ * Env keys a retarget set may introduce. Everything else in a retarget set is
39
+ * dropped, so an internal marker (e.g. `__credFingerprint`) can never reach a
40
+ * child.
41
+ */
42
+ export const RETARGET_KEYS = Object.freeze(new Set([
43
+ "ANTHROPIC_BASE_URL",
44
+ "ANTHROPIC_AUTH_TOKEN",
45
+ "ANTHROPIC_API_KEY",
46
+ "ANTHROPIC_MODEL",
47
+ "ANTHROPIC_SMALL_FAST_MODEL",
48
+ "CLAUDE_CODE_ATTRIBUTION_HEADER",
49
+ "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS",
50
+ // Slot → model mapping (design §4.7: ANTHROPIC_SMALL_FAST_MODEL is deprecated).
51
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
52
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
53
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
54
+ "ANTHROPIC_DEFAULT_FABLE_MODEL",
55
+ "CLAUDE_CODE_SUBAGENT_MODEL",
56
+ // The cohort-llm helper credential (see COHORT_HELPER_KEY below).
57
+ "COHORT_LLM_BASE_URL",
58
+ "COHORT_LLM_API_KEY_HELPER",
59
+ "CLAUDE_CODE_API_KEY_HELPER_TTL_MS",
60
+ ]));
61
+
62
+ /**
63
+ * A cohort-llm retarget authenticates with an `apiKeyHelper` that prints the
64
+ * seat's short-lived token, not with a static ANTHROPIC_AUTH_TOKEN. Claude Code
65
+ * ranks ANTHROPIC_AUTH_TOKEN ABOVE apiKeyHelper (code.claude.com/docs/en/iam,
66
+ * "Authentication precedence"), so a static token would pin the session to a
67
+ * token that dies after at most an hour. The helper counts as the retarget's
68
+ * credential only when the retarget names the SAME gateway in
69
+ * COHORT_LLM_BASE_URL and ANTHROPIC_BASE_URL — a Cohort seat token is never
70
+ * handed to a third-party base URL. The runtime adapter turns the helper
71
+ * command into `--settings {"apiKeyHelper": …}`.
72
+ */
73
+ export const COHORT_HELPER_KEY = "COHORT_LLM_API_KEY_HELPER";
74
+
75
+ const trimUrl = (u) => (typeof u === "string" ? u.trim().replace(/\/+$/, "") : "");
76
+
77
+ /** Does this retarget authenticate through the cohort-llm apiKeyHelper? */
78
+ export function isCohortHelperRetarget(retarget) {
79
+ const set = retarget && typeof retarget === "object" ? retarget : {};
80
+ const helper = set[COHORT_HELPER_KEY];
81
+ return isRetarget(set) && typeof helper === "string" && helper.trim() !== "" &&
82
+ trimUrl(set.COHORT_LLM_BASE_URL) !== "" && trimUrl(set.COHORT_LLM_BASE_URL) === trimUrl(set.ANTHROPIC_BASE_URL);
83
+ }
84
+
85
+ /** Prefix of a Claude subscription OAuth token (`claude setup-token` output). */
86
+ const SUBSCRIPTION_TOKEN_PREFIX = /^sk-ant-oat/i;
87
+
88
+ /**
89
+ * Credential-shaped in EVERY shape (stock and retarget). Unchanged from the
90
+ * historical §7.3 scrub so the stock path stays byte-compatible: it keeps the
91
+ * seat's `CLAUDE_CODE_OAUTH_TOKEN`, which a stock Anthropic spawn needs.
92
+ * @param {string} k
93
+ */
94
+ export function isCredentialKey(k) {
95
+ return /(_API_KEY|_AUTH_TOKEN|_SECRET|_ACCESS_KEY|_PRIVATE_KEY)$/i.test(k) || k === "ANTHROPIC_API_KEY";
96
+ }
97
+
98
+ /**
99
+ * Additionally scrubbed on a retarget: the Claude subscription credential in
100
+ * any spelling, and the whole inherited `ANTHROPIC_*` namespace (credentials,
101
+ * a stale base URL, custom headers) — the retarget set re-injects what the
102
+ * child actually needs.
103
+ * @param {string} k
104
+ */
105
+ export function isRetargetScrubbedKey(k) {
106
+ return (
107
+ isCredentialKey(k) ||
108
+ /^CLAUDE_CODE_OAUTH/i.test(k) ||
109
+ /_OAUTH_TOKEN$/i.test(k) ||
110
+ /^ANTHROPIC_/i.test(k) ||
111
+ /^COHORT_LLM_TOKEN$/i.test(k)
112
+ );
113
+ }
114
+
115
+ /** Does a retarget set actually point the child at another backend? */
116
+ export function isRetarget(retarget) {
117
+ return !!(retarget && typeof retarget === "object" &&
118
+ typeof retarget.ANTHROPIC_BASE_URL === "string" && retarget.ANTHROPIC_BASE_URL.trim() !== "");
119
+ }
120
+
121
+ /**
122
+ * Build a child env.
123
+ *
124
+ * @param {object} o
125
+ * @param {object} o.baseEnv the parent env to start from (never mutated)
126
+ * @param {object} [o.retarget] the router's envForSpawn, or {} / null
127
+ * @param {boolean} [o.keepAnthropicApiKey=false] stock only: keep the parent's
128
+ * ANTHROPIC_API_KEY (a Console key the lane owns) instead of scrubbing it
129
+ * @returns {{ok:true, env:object, retargeting:boolean} |
130
+ * {ok:false, error:{code:"retarget_without_token"|"retarget_with_subscription_token", message:string}}}
131
+ */
132
+ export function buildRuntimeEnv({ baseEnv, retarget = {}, keepAnthropicApiKey = false } = {}) {
133
+ const src = baseEnv && typeof baseEnv === "object" ? baseEnv : {};
134
+ const set = retarget && typeof retarget === "object" ? retarget : {};
135
+ const retargeting = isRetarget(set);
136
+
137
+ const viaHelper = retargeting && isCohortHelperRetarget(set);
138
+ if (retargeting && typeof set[COHORT_HELPER_KEY] === "string" && set[COHORT_HELPER_KEY].trim() !== "" && !viaHelper) {
139
+ return {
140
+ ok: false,
141
+ error: {
142
+ code: "retarget_helper_mismatch",
143
+ message: `refusing to retarget to ${set.ANTHROPIC_BASE_URL}: the cohort-llm key helper is only valid for the gateway named in COHORT_LLM_BASE_URL`,
144
+ },
145
+ };
146
+ }
147
+ if (retargeting && !viaHelper) {
148
+ const token = set.ANTHROPIC_AUTH_TOKEN;
149
+ if (typeof token !== "string" || token.trim() === "") {
150
+ return {
151
+ ok: false,
152
+ error: {
153
+ code: "retarget_without_token",
154
+ message: `refusing to retarget to ${set.ANTHROPIC_BASE_URL}: no ANTHROPIC_AUTH_TOKEN for that backend (the seat's own Claude credential is never sent to a third party)`,
155
+ },
156
+ };
157
+ }
158
+ if (SUBSCRIPTION_TOKEN_PREFIX.test(token.trim())) {
159
+ return {
160
+ ok: false,
161
+ error: {
162
+ code: "retarget_with_subscription_token",
163
+ message: `refusing to retarget to ${set.ANTHROPIC_BASE_URL}: the token is a Claude subscription OAuth token, which may never be sent to a third-party endpoint`,
164
+ },
165
+ };
166
+ }
167
+ }
168
+
169
+ const out = {};
170
+ for (const [k, v] of Object.entries(src)) {
171
+ if (retargeting ? isRetargetScrubbedKey(k) : isCredentialKey(k)) continue;
172
+ out[k] = v;
173
+ }
174
+ if (!retargeting && keepAnthropicApiKey && typeof src.ANTHROPIC_API_KEY === "string") {
175
+ out.ANTHROPIC_API_KEY = src.ANTHROPIC_API_KEY;
176
+ }
177
+ for (const [k, v] of Object.entries(set)) {
178
+ if (RETARGET_KEYS.has(k)) out[k] = v;
179
+ }
180
+ if (retargeting) {
181
+ // Empty string, NOT unset: an unset key lets Claude Code fall through to a
182
+ // keychain login against api.anthropic.com.
183
+ out.ANTHROPIC_API_KEY = "";
184
+ out.CLAUDE_CODE_ATTRIBUTION_HEADER = "0";
185
+ // The helper must be the credential in use: a static token would outrank it.
186
+ if (viaHelper) delete out.ANTHROPIC_AUTH_TOKEN;
187
+ }
188
+ return { ok: true, env: out, retargeting, viaHelper };
189
+ }
190
+
191
+ export default { buildRuntimeEnv, isCredentialKey, isRetargetScrubbedKey, isRetarget, isCohortHelperRetarget, RETARGET_KEYS, COHORT_HELPER_KEY };
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lib/runtime/legacy-shell-guard.mjs — the legacy shell lanes are retired for engine-cohort seats (W4-E1, row 36).
4
+ *
5
+ * Three shell scripts run the `claude` binary directly, outside the runtime
6
+ * adapter: scripts/spawn-session.sh, scripts/continuous-monitor.sh and
7
+ * scripts/local-triggers/run-trigger.sh. They are RETIRED for a seat whose
8
+ * config/agent.json `runtime.engine` is `cohort`, not ported:
9
+ *
10
+ * - each has a maintained JS successor that already goes through
11
+ * `buildSpawn` with the seat's engine — `maestro session spawn` (peers) and
12
+ * the dispatcher for spawn-session.sh, the poller + dispatcher for
13
+ * continuous-monitor.sh, the cadence bus
14
+ * (`scripts/cadence/enqueue-cadence-tick.mjs`) for run-trigger.sh;
15
+ * - no daemon lane, generated plist or cadence calls them (doctor already
16
+ * flags plists that still call run-trigger.sh);
17
+ * - porting them would keep a third spawn path to hold at parity with the
18
+ * adapter (argv mapping, credential scrub, send gate, spend cap) for tools
19
+ * an operator runs by hand.
20
+ *
21
+ * Each script calls this guard first. On an engine-cohort seat the guard
22
+ * refuses (exit 3, the reason on stderr) — running `claude` there would spend
23
+ * the seat's Anthropic credential on work the org routed to cohort-llm and
24
+ * bypass the engine's in-process send gate. On a claude seat it exits 0 and the
25
+ * script behaves exactly as before. `maestro doctor` warns on engine-cohort
26
+ * seats that the lanes are retired.
27
+ *
28
+ * node lib/runtime/legacy-shell-guard.mjs <script-name> <agent-root>
29
+ *
30
+ * @module lib/runtime/legacy-shell-guard
31
+ */
32
+
33
+ "use strict";
34
+
35
+ import { pathToFileURL } from "node:url";
36
+ import { realpathSync } from "node:fs";
37
+ import { readSeatEngine, SHELL_LEGACY_LANES } from "./adapter.mjs";
38
+
39
+ /** The exit code a retired lane stops with. */
40
+ export const LEGACY_LANE_REFUSED_EXIT = 3;
41
+
42
+ /** The successor to use instead of each retired script. */
43
+ export const LEGACY_LANE_SUCCESSORS = Object.freeze({
44
+ "spawn-session.sh": "maestro session spawn --name <slug> \"<prompt>\" (or let the dispatcher take the work)",
45
+ "continuous-monitor.sh": "the maestro daemon's pollers and dispatcher",
46
+ "run-trigger.sh": "node scripts/cadence/enqueue-cadence-tick.mjs <trigger> --source=manual",
47
+ });
48
+
49
+ /**
50
+ * May a legacy shell lane run on this seat? PURE.
51
+ * @param {{engine:string, script:string}} o
52
+ * @returns {{allowed:true}|{allowed:false, exitCode:number, message:string}}
53
+ */
54
+ export function legacyShellLaneVerdict({ engine, script }) {
55
+ if (engine !== "cohort") return { allowed: true };
56
+ const name = String(script || "").split("/").pop() || "this script";
57
+ const successor = LEGACY_LANE_SUCCESSORS[name];
58
+ return {
59
+ allowed: false,
60
+ exitCode: LEGACY_LANE_REFUSED_EXIT,
61
+ message:
62
+ `${name} is retired on this seat: runtime.engine is "cohort", and this legacy lane runs the claude binary directly, ` +
63
+ `outside the runtime adapter.${successor ? ` Use ${successor}.` : ""}`,
64
+ };
65
+ }
66
+
67
+ /** The retired scripts' names, from the adapter's register. */
68
+ export function legacyLaneNames() {
69
+ return SHELL_LEGACY_LANES.map((l) => l.path.split("/").pop());
70
+ }
71
+
72
+ /**
73
+ * The CLI edge.
74
+ * @param {string[]} argv [script, agentRoot]
75
+ * @param {{readSeatEngine?:(root:string)=>string, stderr?:{write:(s:string)=>void}}} [deps]
76
+ * @returns {number} exit code
77
+ */
78
+ export function main(argv, deps = {}) {
79
+ const [script, agentRoot] = argv;
80
+ if (!script || !agentRoot) {
81
+ (deps.stderr || process.stderr).write("usage: legacy-shell-guard.mjs <script-name> <agent-root>\n");
82
+ return 2;
83
+ }
84
+ const v = legacyShellLaneVerdict({ engine: (deps.readSeatEngine || readSeatEngine)(agentRoot), script });
85
+ if (v.allowed) return 0;
86
+ (deps.stderr || process.stderr).write(`${v.message}\n`);
87
+ return v.exitCode;
88
+ }
89
+
90
+ const isEntry = (() => {
91
+ try {
92
+ return process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href;
93
+ } catch {
94
+ return false;
95
+ }
96
+ })();
97
+ if (isEntry) process.exitCode = main(process.argv.slice(2));
@@ -0,0 +1,162 @@
1
+ /**
2
+ * lib/runtime/seat-engine.mjs — which engine a spawn runs, decided once per spawn (W4-E1, CF-44, row 5).
3
+ *
4
+ * Every JavaScript site that launches a session — the supervisor's main
5
+ * session, `maestro session spawn` peers, and the daemon's dispatcher, resume,
6
+ * cadence, responder, classifier and ack lanes — asks this module ONCE per
7
+ * spawn for the seat's engine (config/agent.json `runtime.engine`) and spreads
8
+ * the answer into `buildSpawn`:
9
+ *
10
+ * engine claude `{}` — the buildSpawn input, and so the argv and env, are
11
+ * byte-for-byte what they were before this module existed.
12
+ * engine cohort `{engine:"cohort", cohortToken, agentRoot}` — the adapter
13
+ * launches the Cohort Engine (`cli.mjs run` for run lanes,
14
+ * `cli.mjs session` for main-session and peer) with the seat
15
+ * token and the token helper, every Claude credential scrubbed.
16
+ *
17
+ * Reading the config on every spawn is the rollback: flipping `runtime.engine`
18
+ * back to `claude` restores the claude binary on the NEXT spawn, with no
19
+ * restart (design §8.4: "Rollback is one flag flip").
20
+ *
21
+ * An engine-cohort seat never falls back to claude. With no seat token the
22
+ * adapter returns `cohort_token_unavailable` and the lane reports a failure —
23
+ * running claude instead would spend the seat's Anthropic credential on work
24
+ * the org routed to cohort-llm.
25
+ *
26
+ * The decisions (`seatEngineFields`, `engineRunShape`, `sessionBudgetUsd`) are
27
+ * pure; `seatTokenSync` / `seatToken` are the edge.
28
+ *
29
+ * @module lib/runtime/seat-engine
30
+ */
31
+
32
+ "use strict";
33
+
34
+ import { isRetarget } from "./child-env.mjs";
35
+ import { isCohortRouted, readSeatEngine } from "./adapter.mjs";
36
+
37
+ /**
38
+ * The buildSpawn fields for a seat's engine. PURE.
39
+ * `baseUrl` is the gateway the seat token was minted against (the token
40
+ * manager's `baseUrl`, from config/org.yaml `llmBaseUrl` or the env): the engine
41
+ * must talk to the same gateway, never the adapter's default.
42
+ * @param {{engine:string, agentRoot?:string|null, token?:string|null, baseUrl?:string|null}} o
43
+ * @returns {{}|{engine:"cohort", cohortToken:string|undefined, agentRoot:string|undefined, cohortBaseUrl?:string}}
44
+ */
45
+ export function seatEngineFields({ engine, agentRoot = null, token = null, baseUrl = null }) {
46
+ if (engine !== "cohort") return {};
47
+ return {
48
+ engine: "cohort",
49
+ cohortToken: typeof token === "string" && token ? token : undefined,
50
+ agentRoot: typeof agentRoot === "string" && agentRoot ? agentRoot : undefined,
51
+ ...(typeof baseUrl === "string" && baseUrl ? { cohortBaseUrl: baseUrl } : {}),
52
+ };
53
+ }
54
+
55
+ /**
56
+ * What a routed run lane passes for engine cohort. PURE.
57
+ *
58
+ * The engine talks to cohort-llm directly, so a router retarget never applies:
59
+ * model the router's flag when the router chose the cohort provider (a
60
+ * cohort-* tier), else the lane's own Anthropic slot (sonnet/opus/haiku),
61
+ * which the adapter maps to a Cohort tier. A third-party id is never
62
+ * handed to the engine.
63
+ * knobs the router's --max-turns/--effort/--agents, unless they were sized for
64
+ * a third-party backend (CF-11).
65
+ * retarget `{}`.
66
+ *
67
+ * @param {{target?:object|null, laneModel?:string|null}} o
68
+ * @returns {{model:string|null, knobs:object|null, retarget:{}}}
69
+ */
70
+ export function engineRunShape({ target = null, laneModel = null }) {
71
+ const t = target && typeof target === "object" ? target : null;
72
+ const cohortTarget = t ? isCohortRouted({ target: t }) : false;
73
+ const foreign = t ? !cohortTarget && isRetarget(t.envForSpawn) : false;
74
+ const model = cohortTarget && t && t.modelFlag ? String(t.modelFlag) : laneModel ? String(laneModel) : null;
75
+ return { model, knobs: foreign ? null : t, retarget: {} };
76
+ }
77
+
78
+ /** The smallest per-session cap passed: one model call's worth at most. */
79
+ export const MIN_SESSION_BUDGET_USD = 0.01;
80
+
81
+ /**
82
+ * The per-session spend cap for an engine-cohort dispatcher session, from the
83
+ * seat's funded envelope (budget-guard `dailyAllowance`). PURE.
84
+ *
85
+ * A session may not spend more than one day's binding allowance (the lower of
86
+ * the envelope's share for today and the local cap). No funded envelope → no
87
+ * cap is invented (null): the budget guard's bands still govern the seat.
88
+ * An envelope with nothing left today gets {@link MIN_SESSION_BUDGET_USD}.
89
+ *
90
+ * @param {{funded?:boolean, allowanceUSD?:number}|null|undefined} allowance
91
+ * @returns {number|null}
92
+ */
93
+ export function sessionBudgetUsd(allowance) {
94
+ if (!allowance || allowance.funded !== true) return null;
95
+ const usd = Number(allowance.allowanceUSD);
96
+ if (!Number.isFinite(usd)) return null;
97
+ const cents = Math.ceil(Math.max(0, usd) * 100) / 100;
98
+ return Math.max(MIN_SESSION_BUDGET_USD, cents);
99
+ }
100
+
101
+ // ---------------------------------------------------------------------------
102
+ // Edge: the seat token
103
+ // ---------------------------------------------------------------------------
104
+
105
+ /**
106
+ * A usable seat token right now, without a network call (a synchronous spawn
107
+ * path). null when none is cached.
108
+ * @param {{peek?:(o:{allowStale:boolean})=>({token?:string}|null)}|null} tokenManager
109
+ */
110
+ export function seatTokenSync(tokenManager) {
111
+ try {
112
+ const t = tokenManager && typeof tokenManager.peek === "function" ? tokenManager.peek({ allowStale: true }) : null;
113
+ return t && typeof t.token === "string" && t.token ? t.token : null;
114
+ } catch {
115
+ return null;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * A seat token: the cached one, else minted through the manager. null when the
121
+ * seat cannot get one (no OrgApiKey, the gateway refuses) — never throws.
122
+ * @param {{peek?:Function, getToken?:Function}|null} tokenManager
123
+ * @returns {Promise<string|null>}
124
+ */
125
+ export async function seatToken(tokenManager) {
126
+ const cached = seatTokenSync(tokenManager);
127
+ if (cached) return cached;
128
+ try {
129
+ const t = tokenManager && typeof tokenManager.getToken === "function" ? await tokenManager.getToken() : null;
130
+ return t && t.ok !== false && typeof t.token === "string" && t.token ? t.token : null;
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+
136
+ /**
137
+ * The seat's engine and its buildSpawn fields, for a lane that may wait for a
138
+ * token (responder, classifier, ack, the supervisor, `session spawn`). A claude
139
+ * seat reads config/agent.json and nothing else — no token manager is touched.
140
+ * Never throws.
141
+ * @param {string} agentRoot
142
+ * @param {{readSeatEngine?:(root:string)=>string, tokenManager?:(root:string)=>any}} [deps]
143
+ * @returns {Promise<{engine:"claude"|"cohort", fields:object}>}
144
+ */
145
+ export async function resolveSeatSpawn(agentRoot, deps = {}) {
146
+ let engine = "claude";
147
+ try {
148
+ engine = (deps.readSeatEngine || readSeatEngine)(agentRoot) === "cohort" ? "cohort" : "claude";
149
+ } catch {
150
+ engine = "claude"; // unreadable config: the default engine, as readSeatEngine answers
151
+ }
152
+ if (engine !== "cohort") return { engine, fields: {} };
153
+ let manager = null;
154
+ try {
155
+ manager = deps.tokenManager ? deps.tokenManager(agentRoot) : (await import("../org/llm-token.mjs")).seatTokenManager({ agentRoot });
156
+ } catch {
157
+ manager = null; // no seat key: the adapter refuses the spawn (cohort_token_unavailable)
158
+ }
159
+ return { engine, fields: seatEngineFields({ engine, agentRoot, token: await seatToken(manager), baseUrl: manager && typeof manager.baseUrl === "string" ? manager.baseUrl : null }) };
160
+ }
161
+
162
+ export default { seatEngineFields, engineRunShape, sessionBudgetUsd, seatTokenSync, seatToken, resolveSeatSpawn, MIN_SESSION_BUDGET_USD };