@cohortapp/agent-sdk 2.17.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 (526) hide show
  1. package/.claude/settings.json +18 -0
  2. package/.env.example +18 -5
  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/setup-wizard.md +1 -1
  9. package/docs/runbooks/fleet-rollout.md +156 -0
  10. package/docs/runbooks/mac-mini-bootstrap.md +12 -14
  11. package/lib/action-executor.js +19 -3
  12. package/lib/budget-guard.mjs +279 -3
  13. package/lib/channels/base-adapter.mjs +3 -1
  14. package/lib/channels/contract.mjs +2 -1
  15. package/lib/channels/inbox-item.mjs +8 -0
  16. package/lib/claude-bin.mjs +5 -6
  17. package/lib/cli/doctor-checks.mjs +141 -10
  18. package/lib/cli/global-setup-extras.mjs +5 -1
  19. package/lib/cli/inbox.mjs +100 -15
  20. package/lib/cli/seat-auth.mjs +463 -0
  21. package/lib/cli/session.mjs +80 -12
  22. package/lib/collective/capture.mjs +8 -6
  23. package/lib/collective/global-config.mjs +63 -1
  24. package/lib/collective/presence.mjs +142 -5
  25. package/lib/comms/send-gate.mjs +559 -1
  26. package/lib/diagnostics/alerts.mjs +49 -0
  27. package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
  28. package/lib/engine/agents/definitions.mjs +343 -0
  29. package/lib/engine/agents/persist.mjs +275 -0
  30. package/lib/engine/agents/runtime.mjs +748 -0
  31. package/lib/engine/agents/usage.mjs +95 -0
  32. package/lib/engine/auth-status.mjs +139 -0
  33. package/lib/engine/budget.mjs +194 -0
  34. package/lib/engine/cli.mjs +1204 -0
  35. package/lib/engine/commands/index.mjs +269 -0
  36. package/lib/engine/context/budget.mjs +219 -0
  37. package/lib/engine/context/cache.mjs +125 -0
  38. package/lib/engine/context/child-env.mjs +215 -0
  39. package/lib/engine/context/compaction.mjs +342 -0
  40. package/lib/engine/context/images.mjs +90 -0
  41. package/lib/engine/context/instructions.mjs +327 -0
  42. package/lib/engine/context/lazy-instructions.mjs +169 -0
  43. package/lib/engine/context/manager.mjs +182 -0
  44. package/lib/engine/context/real-path.mjs +91 -0
  45. package/lib/engine/context/secret-values.mjs +163 -0
  46. package/lib/engine/context/settings.mjs +274 -0
  47. package/lib/engine/context/stream-input.mjs +159 -0
  48. package/lib/engine/guard.mjs +152 -0
  49. package/lib/engine/hooks.mjs +713 -0
  50. package/lib/engine/loop.mjs +560 -0
  51. package/lib/engine/mcp/client.mjs +254 -0
  52. package/lib/engine/mcp/config.mjs +301 -0
  53. package/lib/engine/mcp/http.mjs +201 -0
  54. package/lib/engine/mcp/index.mjs +146 -0
  55. package/lib/engine/mcp/jsonrpc.mjs +147 -0
  56. package/lib/engine/mcp/naming.mjs +66 -0
  57. package/lib/engine/mcp/resources.mjs +89 -0
  58. package/lib/engine/mcp/results.mjs +133 -0
  59. package/lib/engine/mcp/stdio.mjs +137 -0
  60. package/lib/engine/mcp/supervisor.mjs +116 -0
  61. package/lib/engine/messages.mjs +104 -0
  62. package/lib/engine/output/json.mjs +164 -0
  63. package/lib/engine/output/stream-json.mjs +266 -0
  64. package/lib/engine/permissions.mjs +845 -0
  65. package/lib/engine/process-identity.mjs +164 -0
  66. package/lib/engine/process-tree.mjs +551 -0
  67. package/lib/engine/prompt.mjs +60 -0
  68. package/lib/engine/session/store.mjs +299 -0
  69. package/lib/engine/session-runtime/args.mjs +97 -0
  70. package/lib/engine/session-runtime/host.mjs +143 -0
  71. package/lib/engine/session-runtime/inbox.mjs +122 -0
  72. package/lib/engine/session-runtime/notifications.mjs +129 -0
  73. package/lib/engine/session-runtime/registry.mjs +328 -0
  74. package/lib/engine/session-runtime/runner.mjs +344 -0
  75. package/lib/engine/session-runtime/socket.mjs +212 -0
  76. package/lib/engine/session-runtime/wakeup.mjs +115 -0
  77. package/lib/engine/skills/index.mjs +321 -0
  78. package/lib/engine/tools/bash-background.mjs +533 -0
  79. package/lib/engine/tools/bash.mjs +216 -0
  80. package/lib/engine/tools/edit.mjs +97 -0
  81. package/lib/engine/tools/glob.mjs +81 -0
  82. package/lib/engine/tools/grep.mjs +224 -0
  83. package/lib/engine/tools/index.mjs +84 -0
  84. package/lib/engine/tools/list-agents.mjs +32 -0
  85. package/lib/engine/tools/ls.mjs +127 -0
  86. package/lib/engine/tools/monitor.mjs +82 -0
  87. package/lib/engine/tools/notebook-edit.mjs +218 -0
  88. package/lib/engine/tools/read.mjs +103 -0
  89. package/lib/engine/tools/schedule-wakeup.mjs +45 -0
  90. package/lib/engine/tools/schema.mjs +144 -0
  91. package/lib/engine/tools/send-message.mjs +77 -0
  92. package/lib/engine/tools/session.mjs +70 -0
  93. package/lib/engine/tools/todo.mjs +144 -0
  94. package/lib/engine/tools/toolsearch.mjs +217 -0
  95. package/lib/engine/tools/walk.mjs +193 -0
  96. package/lib/engine/tools/web-switch.mjs +31 -0
  97. package/lib/engine/tools/webfetch-html.mjs +387 -0
  98. package/lib/engine/tools/webfetch-net.mjs +340 -0
  99. package/lib/engine/tools/webfetch.mjs +198 -0
  100. package/lib/engine/tools/websearch.mjs +91 -0
  101. package/lib/engine/tools/workflow.mjs +95 -0
  102. package/lib/engine/tools/write.mjs +76 -0
  103. package/lib/engine/tui/line-editor.mjs +137 -0
  104. package/lib/engine/tui/render.mjs +86 -0
  105. package/lib/engine/tui/tui.mjs +274 -0
  106. package/lib/engine/wire/anthropic-messages.mjs +263 -0
  107. package/lib/engine/wire/effort.mjs +36 -0
  108. package/lib/engine/wire/errors.mjs +496 -0
  109. package/lib/engine/wire/http.mjs +441 -0
  110. package/lib/engine/wire/index.mjs +76 -0
  111. package/lib/engine/wire/openai-chat.mjs +332 -0
  112. package/lib/engine/wire/prompt-cache.mjs +79 -0
  113. package/lib/engine/wire/search.mjs +140 -0
  114. package/lib/engine/wire/sse.mjs +114 -0
  115. package/lib/engine/wire/stall.mjs +349 -0
  116. package/lib/engine/wire/token-provider.mjs +175 -0
  117. package/lib/engine/wire/usage.mjs +192 -0
  118. package/lib/engine/workflow/host.mjs +524 -0
  119. package/lib/engine/workflow/journal.mjs +188 -0
  120. package/lib/engine/workflow/json-schema.mjs +171 -0
  121. package/lib/engine/workflow/meta.mjs +329 -0
  122. package/lib/engine/workflow/notifications.mjs +52 -0
  123. package/lib/engine/workflow/runtime.mjs +447 -0
  124. package/lib/engine/workflow/sandbox.mjs +534 -0
  125. package/lib/engine/workflow/worker.mjs +141 -0
  126. package/lib/engine/workflow/worktree.mjs +74 -0
  127. package/lib/execution/disposition.mjs +1 -1
  128. package/lib/execution/intake.mjs +10 -0
  129. package/lib/execution/surface-policy.mjs +15 -0
  130. package/lib/learning/curator.mjs +8 -6
  131. package/lib/learning/reflect.mjs +8 -6
  132. package/lib/model-router/catalog/cohort.yaml +137 -0
  133. package/lib/model-router/catalog.mjs +118 -1
  134. package/lib/model-router/failover.mjs +67 -16
  135. package/lib/model-router/llm-task.mjs +39 -3
  136. package/lib/model-router/resolve.mjs +89 -3
  137. package/lib/model-router/spawn.mjs +46 -47
  138. package/lib/model-router/taxonomy.mjs +126 -4
  139. package/lib/org/cost-sync.mjs +141 -11
  140. package/lib/org/inbound/broadcast.mjs +289 -0
  141. package/lib/org/inbound/collective.mjs +375 -0
  142. package/lib/org/inbound/directedness.mjs +96 -8
  143. package/lib/org/inbound/facts.mjs +78 -2
  144. package/lib/org/inbound/project.mjs +22 -0
  145. package/lib/org/inbound/surfaces.mjs +14 -0
  146. package/lib/org/llm-token.mjs +879 -0
  147. package/lib/org/mesh.mjs +61 -0
  148. package/lib/org/messaging.mjs +3 -1
  149. package/lib/org/protocol.checksum +1 -1
  150. package/lib/org/protocol.mjs +15 -0
  151. package/lib/org/quota.mjs +520 -0
  152. package/lib/org/tool-surface.mjs +104 -16
  153. package/lib/org/ui-parity.mjs +16 -1
  154. package/lib/org/work-ledger.mjs +37 -6
  155. package/lib/rate-guard.mjs +114 -1
  156. package/lib/resource-governor.mjs +41 -6
  157. package/lib/runtime/adapter.mjs +823 -0
  158. package/lib/runtime/child-env.mjs +191 -0
  159. package/lib/runtime/legacy-shell-guard.mjs +97 -0
  160. package/lib/runtime/seat-engine.mjs +162 -0
  161. package/lib/session/ask-ledger.mjs +271 -0
  162. package/lib/session/current-work.mjs +676 -0
  163. package/lib/session/feed-core.mjs +40 -3
  164. package/lib/session/launch-args.mjs +56 -4
  165. package/lib/session/status-summary.mjs +26 -9
  166. package/lib/session/upgrade-notice.mjs +42 -0
  167. package/lib/setup/claude-probe.mjs +117 -13
  168. package/lib/setup/enrich.mjs +13 -10
  169. package/lib/setup/sections/model.mjs +39 -13
  170. package/lib/telemetry/collect.mjs +208 -9
  171. package/lib/upgrade/ignored-drift.mjs +105 -0
  172. package/lib/voice/post-call-brief.mjs +30 -17
  173. package/package.json +13 -3
  174. package/plugins/maestro-skills/skills/board-work.md +5 -0
  175. package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
  176. package/plugins/maestro-skills/skills/main-session.md +18 -7
  177. package/scripts/ci/check-tarball-fidelity.mjs +126 -2
  178. package/scripts/ci/run-tests.mjs +47 -19
  179. package/scripts/cohort-llm/api-key-helper.mjs +92 -0
  180. package/scripts/collective/hook-runner.mjs +29 -2
  181. package/scripts/continuous-monitor.sh +13 -0
  182. package/scripts/cost/track-claude-usage.mjs +15 -0
  183. package/scripts/daemon/agent-daemon.mjs +408 -20
  184. package/scripts/daemon/assurance.mjs +48 -12
  185. package/scripts/daemon/cadence-consumer.mjs +218 -68
  186. package/scripts/daemon/cadence-handlers.mjs +73 -4
  187. package/scripts/daemon/classifier.mjs +75 -26
  188. package/scripts/daemon/context-compiler.mjs +51 -37
  189. package/scripts/daemon/deliver.mjs +30 -1
  190. package/scripts/daemon/dispatcher.mjs +595 -149
  191. package/scripts/daemon/health.mjs +14 -1
  192. package/scripts/daemon/maestro-daemon.mjs +11 -0
  193. package/scripts/daemon/prompt-builder.mjs +24 -0
  194. package/scripts/daemon/responder.mjs +246 -79
  195. package/scripts/daemon/sdk-version.mjs +98 -16
  196. package/scripts/eval/probe-gateway.mjs +635 -0
  197. package/scripts/eval/replay/extract.mjs +270 -0
  198. package/scripts/eval/replay/grade.mjs +260 -0
  199. package/scripts/eval/replay/lib/config.mjs +50 -0
  200. package/scripts/eval/replay/lib/effects.mjs +65 -0
  201. package/scripts/eval/replay/lib/fixture.mjs +188 -0
  202. package/scripts/eval/replay/lib/judge.mjs +72 -0
  203. package/scripts/eval/replay/lib/redact.mjs +136 -0
  204. package/scripts/eval/replay/lib/sandbox.mjs +170 -0
  205. package/scripts/eval/replay/lib/schema-check.mjs +63 -0
  206. package/scripts/eval/replay/lib/transcript.mjs +76 -0
  207. package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
  208. package/scripts/eval/replay/report.mjs +185 -0
  209. package/scripts/eval/replay/run.mjs +404 -0
  210. package/scripts/fleet/rollout.mjs +1094 -0
  211. package/scripts/hooks/pre-send-audit.sh +36 -245
  212. package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
  213. package/scripts/hooks/validate-state-yaml.sh +190 -0
  214. package/scripts/huddle/huddle-llm.mjs +361 -0
  215. package/scripts/huddle/huddle-server.mjs +46 -121
  216. package/scripts/local-triggers/autoupdate.sh +448 -78
  217. package/scripts/local-triggers/run-trigger.sh +13 -0
  218. package/scripts/maintenance/pin-integrity.mjs +364 -0
  219. package/scripts/poll-slack-events.sh +41 -9
  220. package/scripts/poller/slack-socket-mode.mjs +28 -3
  221. package/scripts/session/supervisor.mjs +80 -13
  222. package/scripts/spawn-session.sh +13 -0
  223. package/bin/maestro.test.mjs +0 -1574
  224. package/lib/action-executor.test.mjs +0 -871
  225. package/lib/archetype.test.mjs +0 -132
  226. package/lib/assurance/plan-note.test.mjs +0 -234
  227. package/lib/assurance/room-budget.test.mjs +0 -486
  228. package/lib/assurance/tier.test.mjs +0 -174
  229. package/lib/autonomy.test.mjs +0 -66
  230. package/lib/backlog.test.mjs +0 -302
  231. package/lib/backup/policy.test.mjs +0 -305
  232. package/lib/budget-escalate.test.mjs +0 -232
  233. package/lib/budget-guard.envelope.test.mjs +0 -476
  234. package/lib/budget-guard.test.mjs +0 -427
  235. package/lib/cadence-bus-requeue.test.mjs +0 -83
  236. package/lib/cadence-bus-schedule.test.mjs +0 -194
  237. package/lib/cadence-bus.test.mjs +0 -720
  238. package/lib/cadences.test.mjs +0 -230
  239. package/lib/capability/inventory.test.mjs +0 -232
  240. package/lib/capability.test.mjs +0 -78
  241. package/lib/channels/base-adapter.test.mjs +0 -590
  242. package/lib/channels/channels.test.mjs +0 -371
  243. package/lib/channels/contract.test.mjs +0 -162
  244. package/lib/channels/inbox-item.test.mjs +0 -368
  245. package/lib/channels/orgmail/adapter.test.mjs +0 -448
  246. package/lib/channels/pairing.test.mjs +0 -270
  247. package/lib/channels/repeat-suppressor.test.mjs +0 -134
  248. package/lib/channels/slack-adapter.test.mjs +0 -212
  249. package/lib/channels/telegram-adapter.test.mjs +0 -306
  250. package/lib/channels/voice/adapter.test.mjs +0 -278
  251. package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
  252. package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
  253. package/lib/charter.test.mjs +0 -89
  254. package/lib/claude-bin.test.mjs +0 -131
  255. package/lib/cli/board.test.mjs +0 -227
  256. package/lib/cli/design.test.mjs +0 -270
  257. package/lib/cli/doctor-checks.test.mjs +0 -336
  258. package/lib/cli/global-setup-extras.test.mjs +0 -462
  259. package/lib/cli/inbox.test.mjs +0 -230
  260. package/lib/cli/session-ack.test.mjs +0 -63
  261. package/lib/cli/session.test.mjs +0 -613
  262. package/lib/collective/capture.test.mjs +0 -121
  263. package/lib/collective/cards.test.mjs +0 -114
  264. package/lib/collective/config.test.mjs +0 -123
  265. package/lib/collective/global-config.test.mjs +0 -220
  266. package/lib/collective/global-skills.test.mjs +0 -126
  267. package/lib/collective/presence.test.mjs +0 -95
  268. package/lib/collective/recall.test.mjs +0 -116
  269. package/lib/collective/vendor-skills.test.mjs +0 -306
  270. package/lib/comms/send-gate.test.mjs +0 -770
  271. package/lib/comms.test.mjs +0 -41
  272. package/lib/context/budget.test.mjs +0 -252
  273. package/lib/context/history-scope.test.mjs +0 -79
  274. package/lib/cost/ledger-row.test.mjs +0 -183
  275. package/lib/design/design-md.test.mjs +0 -318
  276. package/lib/design/fixtures/DESIGN.golden.md +0 -238
  277. package/lib/design/fixtures/PRODUCT.golden.md +0 -67
  278. package/lib/design/fixtures/foundation.json +0 -133
  279. package/lib/design/refresh-gate.test.mjs +0 -144
  280. package/lib/design/write.test.mjs +0 -241
  281. package/lib/diagnostics/alerts.test.mjs +0 -318
  282. package/lib/diagnostics/backup-freshness.test.mjs +0 -185
  283. package/lib/diagnostics/counters.test.mjs +0 -206
  284. package/lib/diagnostics/events.test.mjs +0 -290
  285. package/lib/diagnostics/otel.test.mjs +0 -196
  286. package/lib/diagnostics/trace.test.mjs +0 -251
  287. package/lib/env-compat.test.mjs +0 -104
  288. package/lib/execution/disposition.test.mjs +0 -553
  289. package/lib/execution/drive.test.mjs +0 -270
  290. package/lib/execution/effects.test.mjs +0 -344
  291. package/lib/execution/intake.test.mjs +0 -389
  292. package/lib/execution/journal.test.mjs +0 -261
  293. package/lib/execution/match.test.mjs +0 -235
  294. package/lib/execution/pipeline.test.mjs +0 -392
  295. package/lib/execution/route.test.mjs +0 -186
  296. package/lib/execution/surface-policy.test.mjs +0 -162
  297. package/lib/fs-atomic.test.mjs +0 -72
  298. package/lib/fs-ownership.test.mjs +0 -158
  299. package/lib/goals/admission.test.mjs +0 -164
  300. package/lib/goals/classify.test.mjs +0 -167
  301. package/lib/goals/collaborate.test.mjs +0 -336
  302. package/lib/goals/gaps.test.mjs +0 -284
  303. package/lib/goals/loop.test.mjs +0 -845
  304. package/lib/hooks/bus.test.mjs +0 -387
  305. package/lib/identity/persona.test.mjs +0 -142
  306. package/lib/kpi-sensors.test.mjs +0 -278
  307. package/lib/kpi.test.mjs +0 -244
  308. package/lib/learning/config.test.mjs +0 -75
  309. package/lib/learning/counters.test.mjs +0 -69
  310. package/lib/learning/curator-consolidate.test.mjs +0 -238
  311. package/lib/learning/curator.test.mjs +0 -106
  312. package/lib/learning/reflect.test.mjs +0 -0
  313. package/lib/learning/session-index.test.mjs +0 -125
  314. package/lib/learning/skill-writer.test.mjs +0 -210
  315. package/lib/mandate/audit.test.mjs +0 -195
  316. package/lib/mandate/contract.test.mjs +0 -185
  317. package/lib/mandate/derive.test.mjs +0 -274
  318. package/lib/mandate/model.test.mjs +0 -164
  319. package/lib/mandate/refresh.test.mjs +0 -389
  320. package/lib/mcp/server.test.mjs +0 -426
  321. package/lib/model-router/auth-profiles.test.mjs +0 -580
  322. package/lib/model-router/catalog.test.mjs +0 -385
  323. package/lib/model-router/economics.test.mjs +0 -438
  324. package/lib/model-router/failover.test.mjs +0 -439
  325. package/lib/model-router/health.test.mjs +0 -338
  326. package/lib/model-router/integration-coverage.test.mjs +0 -831
  327. package/lib/model-router/integration.test.mjs +0 -564
  328. package/lib/model-router/ledger.test.mjs +0 -415
  329. package/lib/model-router/llm-task.test.mjs +0 -392
  330. package/lib/model-router/org-credentials.test.mjs +0 -265
  331. package/lib/model-router/pricing-refresh.test.mjs +0 -286
  332. package/lib/model-router/reconcile.test.mjs +0 -316
  333. package/lib/model-router/repair.test.mjs +0 -180
  334. package/lib/model-router/spawn.test.mjs +0 -446
  335. package/lib/model-router/taxonomy.test.mjs +0 -410
  336. package/lib/model-router.test.mjs +0 -1207
  337. package/lib/org/activity.test.mjs +0 -134
  338. package/lib/org/approvals.test.mjs +0 -216
  339. package/lib/org/awareness.test.mjs +0 -159
  340. package/lib/org/board-mine-cache.test.mjs +0 -53
  341. package/lib/org/board.test.mjs +0 -187
  342. package/lib/org/bootstrap-context.test.mjs +0 -153
  343. package/lib/org/client.test.mjs +0 -1206
  344. package/lib/org/cohort-client.test.mjs +0 -126
  345. package/lib/org/cost-sync.test.mjs +0 -153
  346. package/lib/org/doctor.test.mjs +0 -346
  347. package/lib/org/engagement-ledger.test.mjs +0 -112
  348. package/lib/org/engagement.test.mjs +0 -739
  349. package/lib/org/handoff.test.mjs +0 -269
  350. package/lib/org/inbound/directedness.test.mjs +0 -668
  351. package/lib/org/inbound/facts.test.mjs +0 -471
  352. package/lib/org/inbound/hydrate.test.mjs +0 -908
  353. package/lib/org/inbound/index.test.mjs +0 -429
  354. package/lib/org/inbound/project.test.mjs +0 -287
  355. package/lib/org/integration-tools.test.mjs +0 -160
  356. package/lib/org/keys.test.mjs +0 -92
  357. package/lib/org/knowledge.test.mjs +0 -326
  358. package/lib/org/leases.test.mjs +0 -235
  359. package/lib/org/mesh-directives.test.mjs +0 -110
  360. package/lib/org/mesh-integration.test.mjs +0 -127
  361. package/lib/org/mesh.test.mjs +0 -400
  362. package/lib/org/messaging.test.mjs +0 -471
  363. package/lib/org/param-contract.test.mjs +0 -477
  364. package/lib/org/policy.test.mjs +0 -237
  365. package/lib/org/protocol.checksum.test.mjs +0 -90
  366. package/lib/org/protocol.test.mjs +0 -323
  367. package/lib/org/push.test.mjs +0 -792
  368. package/lib/org/registry.test.mjs +0 -100
  369. package/lib/org/resource-tools.test.mjs +0 -361
  370. package/lib/org/tool-access.test.mjs +0 -144
  371. package/lib/org/tool-surface-integration.test.mjs +0 -120
  372. package/lib/org/tool-surface.test.mjs +0 -1268
  373. package/lib/org/typing.test.mjs +0 -291
  374. package/lib/org/ui-parity.test.mjs +0 -560
  375. package/lib/org/verify.test.mjs +0 -194
  376. package/lib/org/work-ledger.test.mjs +0 -273
  377. package/lib/plan/adoption-e2e.test.mjs +0 -366
  378. package/lib/plan/budget-enforcement.test.mjs +0 -400
  379. package/lib/plan/compile.test.mjs +0 -382
  380. package/lib/plan/emit.test.mjs +0 -269
  381. package/lib/plan/explain.test.mjs +0 -188
  382. package/lib/prompts/parallelism.test.mjs +0 -177
  383. package/lib/rag/rag.test.mjs +0 -505
  384. package/lib/rate-guard.test.mjs +0 -272
  385. package/lib/reactive-gate.test.mjs +0 -57
  386. package/lib/render.test.mjs +0 -68
  387. package/lib/resource-governor.test.mjs +0 -488
  388. package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
  389. package/lib/scheduling/jitter.test.mjs +0 -140
  390. package/lib/secrets/broker.test.mjs +0 -280
  391. package/lib/secrets/providers.test.mjs +0 -274
  392. package/lib/security/audit-engine.test.mjs +0 -424
  393. package/lib/security/coerce-args.test.mjs +0 -281
  394. package/lib/security/dangerous-tools.test.mjs +0 -68
  395. package/lib/security/external-content.test.mjs +0 -84
  396. package/lib/security/redact.test.mjs +0 -441
  397. package/lib/security/secret-equal.test.mjs +0 -55
  398. package/lib/session/config.test.mjs +0 -92
  399. package/lib/session/feed-core.test.mjs +0 -198
  400. package/lib/session/first-run.test.mjs +0 -121
  401. package/lib/session/frontdoor.test.mjs +0 -205
  402. package/lib/session/handoffs.test.mjs +0 -183
  403. package/lib/session/identity.test.mjs +0 -180
  404. package/lib/session/inbox-claims.test.mjs +0 -286
  405. package/lib/session/launch-args.test.mjs +0 -157
  406. package/lib/session/liveness.test.mjs +0 -100
  407. package/lib/session/status-summary.test.mjs +0 -118
  408. package/lib/session-permissions.test.mjs +0 -120
  409. package/lib/setup/claude-probe.test.mjs +0 -187
  410. package/lib/setup/completeness.test.mjs +0 -110
  411. package/lib/setup/context-pack.test.mjs +0 -89
  412. package/lib/setup/enrich.test.mjs +0 -115
  413. package/lib/setup/enroll-from-cohort.test.mjs +0 -300
  414. package/lib/setup/integration.test.mjs +0 -162
  415. package/lib/setup/io.test.mjs +0 -77
  416. package/lib/setup/runner.test.mjs +0 -132
  417. package/lib/setup/sections/identity.test.mjs +0 -234
  418. package/lib/setup/sections/inventory.test.mjs +0 -198
  419. package/lib/setup/sections/learning.test.mjs +0 -81
  420. package/lib/setup/sections/mandate.test.mjs +0 -388
  421. package/lib/setup/sections/messaging.test.mjs +0 -127
  422. package/lib/setup/sections/model.test.mjs +0 -240
  423. package/lib/setup/sections/org.test.mjs +0 -346
  424. package/lib/setup/sections/orgmail.test.mjs +0 -118
  425. package/lib/setup/sections/recovery.test.mjs +0 -98
  426. package/lib/setup/sections/subagents.test.mjs +0 -429
  427. package/lib/setup/sections/verify.test.mjs +0 -175
  428. package/lib/setup/sot.test.mjs +0 -81
  429. package/lib/setup/state.test.mjs +0 -115
  430. package/lib/singleton.test.mjs +0 -151
  431. package/lib/subagents/cli.test.mjs +0 -389
  432. package/lib/subagents/client.test.mjs +0 -309
  433. package/lib/subagents/gap.test.mjs +0 -234
  434. package/lib/subagents/lock.test.mjs +0 -248
  435. package/lib/subagents/manifest.test.mjs +0 -175
  436. package/lib/subagents/refs.test.mjs +0 -204
  437. package/lib/subagents/resolve.test.mjs +0 -422
  438. package/lib/subagents/schema.test.mjs +0 -328
  439. package/lib/telemetry/alerts.test.mjs +0 -109
  440. package/lib/telemetry/collect.test.mjs +0 -1274
  441. package/lib/tool-definitions-integration.test.mjs +0 -83
  442. package/lib/tool-definitions.test.mjs +0 -437
  443. package/lib/upgrade/global-refresh.test.mjs +0 -65
  444. package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
  445. package/lib/upgrade/post-steps.test.mjs +0 -200
  446. package/lib/upgrade/verify.test.mjs +0 -164
  447. package/lib/util/fetch-timeout.test.mjs +0 -202
  448. package/lib/util/reconnect.test.mjs +0 -369
  449. package/lib/util/unhandled.test.mjs +0 -216
  450. package/lib/voice/outbound.test.mjs +0 -69
  451. package/lib/voice/session-rotation.test.mjs +0 -114
  452. package/lib/voice/stt.test.mjs +0 -226
  453. package/lib/voice/voice.test.mjs +0 -990
  454. package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
  455. package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
  456. package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
  457. package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
  458. package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
  459. package/scripts/ci/check-skill-packs.test.mjs +0 -495
  460. package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
  461. package/scripts/ci/check.test.mjs +0 -194
  462. package/scripts/ci/conformance-org-api.test.mjs +0 -425
  463. package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
  464. package/scripts/collective/hook-runner.test.mjs +0 -173
  465. package/scripts/cost/fleet-digest.test.mjs +0 -207
  466. package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
  467. package/scripts/cost/track-claude-usage.test.mjs +0 -148
  468. package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
  469. package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
  470. package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
  471. package/scripts/daemon/agent-daemon.test.mjs +0 -995
  472. package/scripts/daemon/assurance-e2e.test.mjs +0 -613
  473. package/scripts/daemon/assurance.test.mjs +0 -1791
  474. package/scripts/daemon/board-mirror.test.mjs +0 -165
  475. package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
  476. package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
  477. package/scripts/daemon/cadence-consumer.test.mjs +0 -776
  478. package/scripts/daemon/cadence-handlers.test.mjs +0 -837
  479. package/scripts/daemon/classifier-identity.test.mjs +0 -137
  480. package/scripts/daemon/classifier.test.mjs +0 -266
  481. package/scripts/daemon/classify-kind.test.mjs +0 -40
  482. package/scripts/daemon/context-compiler.test.mjs +0 -406
  483. package/scripts/daemon/deliver.test.mjs +0 -564
  484. package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
  485. package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
  486. package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
  487. package/scripts/daemon/dispatcher-session-continuity.test.mjs +0 -365
  488. package/scripts/daemon/execution-ladder.test.mjs +0 -470
  489. package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
  490. package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
  491. package/scripts/daemon/inbox-deferral.test.mjs +0 -336
  492. package/scripts/daemon/inbox-wake.test.mjs +0 -199
  493. package/scripts/daemon/integration.test.mjs +0 -149
  494. package/scripts/daemon/lib/self-echo.test.mjs +0 -153
  495. package/scripts/daemon/lib/session-router.test.mjs +0 -554
  496. package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
  497. package/scripts/daemon/prompt-builder.test.mjs +0 -556
  498. package/scripts/daemon/responder-cost.test.mjs +0 -68
  499. package/scripts/daemon/responder-history.test.mjs +0 -221
  500. package/scripts/daemon/sdk-version.test.mjs +0 -31
  501. package/scripts/daemon/session-lock.test.mjs +0 -252
  502. package/scripts/daemon/session-outcomes.test.mjs +0 -533
  503. package/scripts/daemon/typing-registry.test.mjs +0 -102
  504. package/scripts/hooks/pre-send-audit.test.mjs +0 -354
  505. package/scripts/huddle/huddle-prompt.test.mjs +0 -176
  506. package/scripts/local-triggers/autoupdate.test.mjs +0 -518
  507. package/scripts/local-triggers/generate-plists.test.mjs +0 -456
  508. package/scripts/media-generation/brand-clause.test.mjs +0 -135
  509. package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
  510. package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
  511. package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
  512. package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
  513. package/scripts/poller/slack-socket-mode.test.mjs +0 -805
  514. package/scripts/poller-launchd/install.test.mjs +0 -243
  515. package/scripts/restore-from-backup.test.mjs +0 -181
  516. package/scripts/session/feed.test.mjs +0 -196
  517. package/scripts/session/supervisor-sh.test.mjs +0 -218
  518. package/scripts/session/supervisor.test.mjs +0 -482
  519. package/scripts/setup/configure-macos.test.mjs +0 -306
  520. package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
  521. package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
  522. package/scripts/setup/generate-capability.test.mjs +0 -134
  523. package/scripts/setup/init-agent.test.mjs +0 -370
  524. package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
  525. package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
  526. 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 };