@coreplane/switchboard 1.239.0 → 1.240.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/dist/assets/config/config.example.yaml +6 -0
  2. package/dist/assets/deploy/cloudflare-memory/worker.ts +115 -1
  3. package/dist/assets/deploy/cloudflare-memory/wrangler.template.jsonc +7 -1
  4. package/dist/assets/deploy/cloudflare-resident/worker.ts +223 -70
  5. package/dist/assets/deploy/secrets.manifest.json +1 -1
  6. package/dist/assets/package-lock.json +207 -3
  7. package/dist/assets/package.json +2 -1
  8. package/dist/assets/source.json +3 -3
  9. package/dist/assets/src/core/authz/actor.ts +33 -2
  10. package/dist/assets/src/core/authz/policy.ts +6 -0
  11. package/dist/assets/src/core/coordinator/contract.ts +12 -1
  12. package/dist/assets/src/core/coordinator/driver.ts +13 -0
  13. package/dist/assets/src/core/costs.ts +1114 -0
  14. package/dist/assets/src/core/costsSnapshotStore.ts +209 -0
  15. package/dist/assets/src/core/delivery.ts +4 -11
  16. package/dist/assets/src/core/deliverySnapshotStore.ts +12 -28
  17. package/dist/assets/src/core/ingressTokens.ts +27 -13
  18. package/dist/assets/src/core/runLedger/types.ts +3 -0
  19. package/dist/assets/src/core/runRecord.ts +10 -3
  20. package/dist/assets/src/core/schedules.ts +2 -1
  21. package/dist/assets/src/core/ship/coordinator.ts +70 -0
  22. package/dist/assets/src/core/snapshotAge.ts +30 -0
  23. package/dist/assets/src/core/stateWorkerRef.ts +41 -0
  24. package/dist/assets/src/execution/residentAutoRebuild.ts +73 -0
  25. package/dist/assets/src/execution/residentRefresh.ts +25 -3
  26. package/dist/assets/src/execution/restoreWaiters.ts +61 -0
  27. package/dist/assets/src/mcp/registry.ts +7 -0
  28. package/dist/assets/web/dist/.vite/manifest.json +507 -427
  29. package/dist/assets/web/dist/assets/AppShell-CM_fh-WW.js +1 -0
  30. package/dist/assets/web/dist/assets/CostsPage-BD3w5j_S.js +2 -0
  31. package/dist/assets/web/dist/assets/DeliveryPage-BtvzKA1m.js +1 -0
  32. package/dist/assets/web/dist/assets/HomePage-BU6aRCSe.js +2 -0
  33. package/dist/assets/web/dist/assets/NotFoundPage-DwOX1HaZ.js +1 -0
  34. package/dist/assets/web/dist/assets/{ResidentDetailPage-CrfCd8fx.js → ResidentDetailPage-CUAOh5d9.js} +1 -1
  35. package/dist/assets/web/dist/assets/ResidentsIndexPage-B3KUlYy2.js +1 -0
  36. package/dist/assets/web/dist/assets/RunFoldRow-Dulcbg25.js +1 -0
  37. package/dist/assets/web/dist/assets/RunRoutePage-DGoGrQZq.js +6 -0
  38. package/dist/assets/web/dist/assets/RunsIndexPage-37W7OZbC.js +1 -0
  39. package/dist/assets/web/dist/assets/{RunsTabs-XpCqeWu4.js → RunsTabs-BnkvCBrM.js} +1 -1
  40. package/dist/assets/web/dist/assets/ScheduledPage-C1y9jgAk.js +1 -0
  41. package/dist/assets/web/dist/assets/SettingsPage-ggfB-Rqr.js +1 -0
  42. package/dist/assets/web/dist/assets/SlackMark-VDNs7Vjh.js +1 -0
  43. package/dist/assets/web/dist/assets/Slideover-CX-LEklF.js +1 -0
  44. package/dist/assets/web/dist/assets/{StatusDot-DkXALvKf.js → StatusDot-CiByEtoR.js} +1 -1
  45. package/dist/assets/web/dist/assets/{Tooltip-DtLIyi5P.js → Tooltip-DyRxk8A8.js} +1 -1
  46. package/dist/assets/web/dist/assets/UnitRoutePage-CnWyOizV.js +1 -0
  47. package/dist/assets/web/dist/assets/{angular-html-DYtV9uIN.js → angular-html-DAQ_1T1v.js} +1 -1
  48. package/dist/assets/web/dist/assets/{angular-ts-DF2P25Zp.js → angular-ts-D4kxRVp1.js} +1 -1
  49. package/dist/assets/web/dist/assets/{apl-Ff96wxko.js → apl-Dy07l64y.js} +1 -1
  50. package/dist/assets/web/dist/assets/{astro-LbBnZna-.js → astro-DZIbTlc7.js} +1 -1
  51. package/dist/assets/web/dist/assets/{blade-DltuxeBW.js → blade-CmSXWX3l.js} +1 -1
  52. package/dist/assets/web/dist/assets/{c-DBg7yuPx.js → c-ggzVdJLK.js} +1 -1
  53. package/dist/assets/web/dist/assets/{chapel-C83hUAds.js → chapel-Bo1wktsG.js} +1 -1
  54. package/dist/assets/web/dist/assets/{cobol-DB0yV_2D.js → cobol-DJUmtKM2.js} +1 -1
  55. package/dist/assets/web/dist/assets/{coffee-Bpih6Kzl.js → coffee-BZWOVz4C.js} +1 -1
  56. package/dist/assets/web/dist/assets/{cpp-CU00ZeRn.js → cpp-Dtk39yMw.js} +1 -1
  57. package/dist/assets/web/dist/assets/{crystal-f8ImJkux.js → crystal-CGf_-Zoj.js} +1 -1
  58. package/dist/assets/web/dist/assets/{css-4VrC4ISo.js → css-CX2fcL4u.js} +1 -1
  59. package/dist/assets/web/dist/assets/delivery-CTdOqpVK.js +1 -0
  60. package/dist/assets/web/dist/assets/{dist-DtA7JiH5.js → dist-D8TaC961.js} +2 -2
  61. package/dist/assets/web/dist/assets/durationTone-DXG-3R7_.js +1 -0
  62. package/dist/assets/web/dist/assets/{edge-BwFDzfS_.js → edge-BYS8FtgQ.js} +1 -1
  63. package/dist/assets/web/dist/assets/{elixir-wwIYIpJm.js → elixir-fhUpi3nO.js} +1 -1
  64. package/dist/assets/web/dist/assets/{elm-DyDuM3v3.js → elm-DAQNiwsN.js} +1 -1
  65. package/dist/assets/web/dist/assets/{erb-DFJBEVrh.js → erb-CWzEys6U.js} +1 -1
  66. package/dist/assets/web/dist/assets/eventSource-tRprhqm7.js +1 -0
  67. package/dist/assets/web/dist/assets/favicon-D1hkyC5j.js +1 -0
  68. package/dist/assets/web/dist/assets/{git-rebase-CuDv-44X.js → git-rebase-9rY3p-Rw.js} +1 -1
  69. package/dist/assets/web/dist/assets/{glimmer-js-ZFnrm4J3.js → glimmer-js-tY7hy0nE.js} +1 -1
  70. package/dist/assets/web/dist/assets/{glimmer-ts-XY4Yqshp.js → glimmer-ts-CTrLv5JF.js} +1 -1
  71. package/dist/assets/web/dist/assets/{glsl-xnR8efx0.js → glsl-BRJbiDfq.js} +1 -1
  72. package/dist/assets/web/dist/assets/{graphql-D-gO5tnP.js → graphql-B-MtVLh2.js} +1 -1
  73. package/dist/assets/web/dist/assets/{hack-CSxbW4ax.js → hack-BtIkOypQ.js} +1 -1
  74. package/dist/assets/web/dist/assets/{haml-D4ar42QT.js → haml-CoOH6gfa.js} +1 -1
  75. package/dist/assets/web/dist/assets/{handlebars-CMLbDE7o.js → handlebars-DgrRu-GP.js} +1 -1
  76. package/dist/assets/web/dist/assets/{html-CVekU4Fs.js → html-DZaaI7ca.js} +1 -1
  77. package/dist/assets/web/dist/assets/{html-derivative-St3HHw_N.js → html-derivative-DgHvT-qZ.js} +1 -1
  78. package/dist/assets/web/dist/assets/{http-Mon0DWHS.js → http-CvAd51yz.js} +1 -1
  79. package/dist/assets/web/dist/assets/{hurl-Cbl5IvBs.js → hurl-CXGqAfzx.js} +1 -1
  80. package/dist/assets/web/dist/assets/{localIso-CNA-bhS-.js → indexFormat-B-pd4r7Y.js} +1 -1
  81. package/dist/assets/web/dist/assets/{indexRow-FLJu5mR9.js → indexRow-Cse3JGb0.js} +1 -1
  82. package/dist/assets/web/dist/assets/{java-Bprck1l-.js → java-CIQStIXF.js} +1 -1
  83. package/dist/assets/web/dist/assets/{javascript-C73G1-UR.js → javascript-WbH8s7E3.js} +1 -1
  84. package/dist/assets/web/dist/assets/{jinja-C4DuRxYJ.js → jinja-DzyWEVKC.js} +1 -1
  85. package/dist/assets/web/dist/assets/{jison-B2U03GEC.js → jison-CrT-zCa-.js} +1 -1
  86. package/dist/assets/web/dist/assets/{json-CvTZUDzx.js → json-lHjpjXMQ.js} +1 -1
  87. package/dist/assets/web/dist/assets/{jsx-DMWKCzwo.js → jsx-WTwYCHW6.js} +1 -1
  88. package/dist/assets/web/dist/assets/{julia-Czn7bV_3.js → julia-Bqpk9H7E.js} +1 -1
  89. package/dist/assets/web/dist/assets/{just-BBxpNfvC.js → just-LdXk1r3m.js} +1 -1
  90. package/dist/assets/web/dist/assets/{latex-Bw9yg5mr.js → latex-h_y2A5KD.js} +1 -1
  91. package/dist/assets/web/dist/assets/{liquid-BRCjaydE.js → liquid-CY7bF2_p.js} +1 -1
  92. package/dist/assets/web/dist/assets/localIso-L06jV29p.js +1 -0
  93. package/dist/assets/web/dist/assets/{lua-DUu2KIC0.js → lua-oQ7XVZOY.js} +1 -1
  94. package/dist/assets/web/dist/assets/main-CGO6fQ8k.js +28 -0
  95. package/dist/assets/web/dist/assets/main-O8UXRuEv.css +1 -0
  96. package/dist/assets/web/dist/assets/{marko-CZJZIlSQ.js → marko-zv_qZ4QV.js} +1 -1
  97. package/dist/assets/web/dist/assets/{mdc-BmClq6fd.js → mdc-Dl4kL_YK.js} +1 -1
  98. package/dist/assets/web/dist/assets/{nginx-Bmt3xSEm.js → nginx-CAHCZj4F.js} +1 -1
  99. package/dist/assets/web/dist/assets/{nim-Da-i0utK.js → nim-BOtmwCJH.js} +1 -1
  100. package/dist/assets/web/dist/assets/{org-BvAre2qP.js → org-DspQk3HQ.js} +1 -1
  101. package/dist/assets/web/dist/assets/{perl-v9WwFFtB.js → perl-CAXmvVl0.js} +1 -1
  102. package/dist/assets/web/dist/assets/{php-DTU4Zyze.js → php-CMUx4VyM.js} +1 -1
  103. package/dist/assets/web/dist/assets/{pug-DhTwEqTO.js → pug-B55xVJTv.js} +1 -1
  104. package/dist/assets/web/dist/assets/{qml-BUD9AC_c.js → qml-DsNKCCRk.js} +1 -1
  105. package/dist/assets/web/dist/assets/{r-CAnu56n7.js → r-DbhP0VvO.js} +1 -1
  106. package/dist/assets/web/dist/assets/{razor-Dn0P4gAq.js → razor-BCpE6P-p.js} +1 -1
  107. package/dist/assets/web/dist/assets/{regexp-CZyBRaVW.js → regexp-BllsjiN4.js} +1 -1
  108. package/dist/assets/web/dist/assets/{rst-Ckyd5UsY.js → rst-CO5Rpq9V.js} +1 -1
  109. package/dist/assets/web/dist/assets/{ruby-BBQ62fsx.js → ruby-C2A4OgQq.js} +1 -1
  110. package/dist/assets/web/dist/assets/{sas-CW35hMxG.js → sas-Butzoyql.js} +1 -1
  111. package/dist/assets/web/dist/assets/{scss-CpV8pF4J.js → scss-PEUwJBpf.js} +1 -1
  112. package/dist/assets/web/dist/assets/settingsApi-priOPiwu.js +1 -0
  113. package/dist/assets/web/dist/assets/{shellscript-CRJvsmE1.js → shellscript-3Yhq0khE.js} +1 -1
  114. package/dist/assets/web/dist/assets/{shellsession-CyriUZxf.js → shellsession-04Hkb7m3.js} +1 -1
  115. package/dist/assets/web/dist/assets/{soy-D5QzYUeg.js → soy-BnId73cP.js} +1 -1
  116. package/dist/assets/web/dist/assets/{sql-CUBf_Mse.js → sql-BKwdc0ch.js} +1 -1
  117. package/dist/assets/web/dist/assets/sseReplay-DutHNghE.js +9 -0
  118. package/dist/assets/web/dist/assets/{stata-B-4n4ITz.js → stata-BPPtNkay.js} +1 -1
  119. package/dist/assets/web/dist/assets/{surrealql-RuWZBLtr.js → surrealql-CDPChcYP.js} +1 -1
  120. package/dist/assets/web/dist/assets/{svelte-CO5YzCsK.js → svelte-B15DIQ-z.js} +1 -1
  121. package/dist/assets/web/dist/assets/{templ-DbkWVaBF.js → templ-D-rp_AiB.js} +1 -1
  122. package/dist/assets/web/dist/assets/{tex-IuxoEcId.js → tex-BnVDCD7p.js} +1 -1
  123. package/dist/assets/web/dist/assets/{ts-tags-g6dGQPjd.js → ts-tags-cpujdyAR.js} +1 -1
  124. package/dist/assets/web/dist/assets/{tsx-WnXwiyH2.js → tsx-D1vO4L72.js} +1 -1
  125. package/dist/assets/web/dist/assets/{twig-Lx1G7PnY.js → twig-oQGnQGRc.js} +1 -1
  126. package/dist/assets/web/dist/assets/{typescript-BQd7biLF.js → typescript-CKSFpXiH.js} +1 -1
  127. package/dist/assets/web/dist/assets/{typst-D2lXPHK7.js → typst-DKHFo8BF.js} +1 -1
  128. package/dist/assets/web/dist/assets/{vue-4wVQD9y9.js → vue-BstokpiS.js} +1 -1
  129. package/dist/assets/web/dist/assets/{vue-html-DZPaRte4.js → vue-html-DpCp0_Sz.js} +1 -1
  130. package/dist/assets/web/dist/assets/{vue-vine-DbmZCmu-.js → vue-vine-y5d5wUb1.js} +1 -1
  131. package/dist/assets/web/dist/assets/{xml-DV16szyo.js → xml-Br2hx5Ax.js} +1 -1
  132. package/dist/assets/web/dist/assets/{xsl-eo5-1sk0.js → xsl-Bc8Cobap.js} +1 -1
  133. package/dist/assets/web/dist/assets/{yaml-BXdX8HZf.js → yaml-LOITy_I1.js} +1 -1
  134. package/dist/cli.js +2314 -1571
  135. package/package.json +1 -1
  136. package/dist/assets/web/dist/assets/AppShell-MYHNxJks.js +0 -1
  137. package/dist/assets/web/dist/assets/CostsPage-DKk9OjB0.js +0 -2
  138. package/dist/assets/web/dist/assets/DeliveryPage-Kz6js49i.js +0 -1
  139. package/dist/assets/web/dist/assets/NotFoundPage-BXLrQQzy.js +0 -1
  140. package/dist/assets/web/dist/assets/ResidentsIndexPage-BdW0k2h3.js +0 -1
  141. package/dist/assets/web/dist/assets/RunFoldRow-CbTd9SiS.js +0 -9
  142. package/dist/assets/web/dist/assets/RunRoutePage-br0H-8Pz.js +0 -6
  143. package/dist/assets/web/dist/assets/RunsIndexPage-Bnzb15zH.js +0 -1
  144. package/dist/assets/web/dist/assets/ScheduledPage-NLhjzHAz.js +0 -1
  145. package/dist/assets/web/dist/assets/SettingsPage-D-i0uVw-.js +0 -1
  146. package/dist/assets/web/dist/assets/UnitRoutePage-DGXukEAH.js +0 -1
  147. package/dist/assets/web/dist/assets/durationTone-CYMux25J.js +0 -1
  148. package/dist/assets/web/dist/assets/favicon-CSt-qDvc.js +0 -1
  149. package/dist/assets/web/dist/assets/main-CFHF2RvQ.css +0 -1
  150. package/dist/assets/web/dist/assets/main-Dht0in4v.js +0 -28
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.239.0",
3
+ "version": "1.240.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "switchboard",
9
- "version": "1.239.0",
9
+ "version": "1.240.0",
10
10
  "license": "Apache-2.0",
11
11
  "workspaces": [
12
12
  "web",
@@ -34,6 +34,7 @@
34
34
  "devDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "0.85.1",
36
36
  "@eslint/js": "^10.0.1",
37
+ "@opencode/cli": "^2.0.3",
37
38
  "@opencode/protocol": "2.0.3",
38
39
  "@opencode/schema": "2.0.3",
39
40
  "@types/node": "^24.0.0",
@@ -6242,6 +6243,209 @@
6242
6243
  "dev": true,
6243
6244
  "license": "MIT"
6244
6245
  },
6246
+ "node_modules/@opencode/cli": {
6247
+ "version": "2.0.3",
6248
+ "resolved": "https://registry.npmjs.org/@opencode/cli/-/cli-2.0.3.tgz",
6249
+ "integrity": "sha512-FC4+2a5kwdKS2o/pIcGCscpSQB7PuhBObwGMfqnx/2XtoaZBMtSq/99nuEdeDNAFvy1qyK6mp2hwvoiMWsiI4w==",
6250
+ "cpu": [
6251
+ "arm64",
6252
+ "x64"
6253
+ ],
6254
+ "dev": true,
6255
+ "hasInstallScript": true,
6256
+ "license": "MIT",
6257
+ "os": [
6258
+ "darwin",
6259
+ "linux",
6260
+ "win32"
6261
+ ],
6262
+ "bin": {
6263
+ "opencode": "bin/opencode.exe",
6264
+ "opencode2": "bin/opencode.exe"
6265
+ },
6266
+ "optionalDependencies": {
6267
+ "@opencode/cli-darwin-arm64": "2.0.3",
6268
+ "@opencode/cli-darwin-x64": "2.0.3",
6269
+ "@opencode/cli-darwin-x64-baseline": "2.0.3",
6270
+ "@opencode/cli-linux-arm64": "2.0.3",
6271
+ "@opencode/cli-linux-arm64-musl": "2.0.3",
6272
+ "@opencode/cli-linux-x64": "2.0.3",
6273
+ "@opencode/cli-linux-x64-baseline": "2.0.3",
6274
+ "@opencode/cli-linux-x64-baseline-musl": "2.0.3",
6275
+ "@opencode/cli-linux-x64-musl": "2.0.3",
6276
+ "@opencode/cli-windows-arm64": "2.0.3",
6277
+ "@opencode/cli-windows-x64": "2.0.3",
6278
+ "@opencode/cli-windows-x64-baseline": "2.0.3"
6279
+ }
6280
+ },
6281
+ "node_modules/@opencode/cli-darwin-arm64": {
6282
+ "version": "2.0.3",
6283
+ "resolved": "https://registry.npmjs.org/@opencode/cli-darwin-arm64/-/cli-darwin-arm64-2.0.3.tgz",
6284
+ "integrity": "sha512-2JzNaHmMHUCk2uLXo2kCKCs81KOzErt7V7ypFFp5hUCIXRPjt9D7C5CKsz2GKWfpHRivUKILKrfUS9MpYzfq6A==",
6285
+ "cpu": [
6286
+ "arm64"
6287
+ ],
6288
+ "dev": true,
6289
+ "license": "MIT",
6290
+ "optional": true,
6291
+ "os": [
6292
+ "darwin"
6293
+ ]
6294
+ },
6295
+ "node_modules/@opencode/cli-darwin-x64": {
6296
+ "version": "2.0.3",
6297
+ "resolved": "https://registry.npmjs.org/@opencode/cli-darwin-x64/-/cli-darwin-x64-2.0.3.tgz",
6298
+ "integrity": "sha512-dMAH/N5KD10Wlct2BbCa8tEV6SiPgBg1kF9Ud7N7ZUctMEeGoz3fqZTrcGrQz7yoAkyyHhGgq+gmxqobwrAhhg==",
6299
+ "cpu": [
6300
+ "x64"
6301
+ ],
6302
+ "dev": true,
6303
+ "license": "MIT",
6304
+ "optional": true,
6305
+ "os": [
6306
+ "darwin"
6307
+ ]
6308
+ },
6309
+ "node_modules/@opencode/cli-darwin-x64-baseline": {
6310
+ "version": "2.0.3",
6311
+ "resolved": "https://registry.npmjs.org/@opencode/cli-darwin-x64-baseline/-/cli-darwin-x64-baseline-2.0.3.tgz",
6312
+ "integrity": "sha512-sm9ZjG2KOk/v4ht6WHAo+pAeOfxnnImwT5rFWNIn15fVlXncbWH2QmKWDC3Nf/h7vpgeghZ1UBbBmo8fP3lBCA==",
6313
+ "cpu": [
6314
+ "x64"
6315
+ ],
6316
+ "dev": true,
6317
+ "license": "MIT",
6318
+ "optional": true,
6319
+ "os": [
6320
+ "darwin"
6321
+ ]
6322
+ },
6323
+ "node_modules/@opencode/cli-linux-arm64": {
6324
+ "version": "2.0.3",
6325
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-arm64/-/cli-linux-arm64-2.0.3.tgz",
6326
+ "integrity": "sha512-q3QhCIW5CxkmJjzKI6GXJ89M0OF9lOsi1e3e4YTvQL6Htv0S7eHyZ+3Wg0UYQaoYqegAf3vBoYiPR3Z9ieIVrQ==",
6327
+ "cpu": [
6328
+ "arm64"
6329
+ ],
6330
+ "dev": true,
6331
+ "license": "MIT",
6332
+ "optional": true,
6333
+ "os": [
6334
+ "linux"
6335
+ ]
6336
+ },
6337
+ "node_modules/@opencode/cli-linux-arm64-musl": {
6338
+ "version": "2.0.3",
6339
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.0.3.tgz",
6340
+ "integrity": "sha512-cif0oXReK/lVZ9kFplNc3XTNM3uuAKLIgcfcEIVMbjTivLzdHe0O5Dp8y7rakJOdXqQ5yM1k6oP8kP2rfpitxg==",
6341
+ "cpu": [
6342
+ "arm64"
6343
+ ],
6344
+ "dev": true,
6345
+ "license": "MIT",
6346
+ "optional": true,
6347
+ "os": [
6348
+ "linux"
6349
+ ]
6350
+ },
6351
+ "node_modules/@opencode/cli-linux-x64": {
6352
+ "version": "2.0.3",
6353
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64/-/cli-linux-x64-2.0.3.tgz",
6354
+ "integrity": "sha512-H8m5m4g1Z/zkx1O8+pos7euLYpY/zgc5NTdUbZZ7Dh8xQ35qoHCnJjt9H8Y1hnpm4ClNKDVHmEISw/qPiskX5A==",
6355
+ "cpu": [
6356
+ "x64"
6357
+ ],
6358
+ "dev": true,
6359
+ "license": "MIT",
6360
+ "optional": true,
6361
+ "os": [
6362
+ "linux"
6363
+ ]
6364
+ },
6365
+ "node_modules/@opencode/cli-linux-x64-baseline": {
6366
+ "version": "2.0.3",
6367
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-baseline/-/cli-linux-x64-baseline-2.0.3.tgz",
6368
+ "integrity": "sha512-14CFor+PFx7tPAFOB3uEcg2EOQZNB1gK4uit4p8gfN30FK7kwNHBjs/m79QGICPMjwZrCOVdZ3ZiI+AgbjanjA==",
6369
+ "cpu": [
6370
+ "x64"
6371
+ ],
6372
+ "dev": true,
6373
+ "license": "MIT",
6374
+ "optional": true,
6375
+ "os": [
6376
+ "linux"
6377
+ ]
6378
+ },
6379
+ "node_modules/@opencode/cli-linux-x64-baseline-musl": {
6380
+ "version": "2.0.3",
6381
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-baseline-musl/-/cli-linux-x64-baseline-musl-2.0.3.tgz",
6382
+ "integrity": "sha512-AYMNzjwPU63FjqjKLEm61s2tBL7+yipt/lzn+2eMpPHYGggV2urJH9TEME2+mReENeYFfOSItPR7gWLX1p2g5A==",
6383
+ "cpu": [
6384
+ "x64"
6385
+ ],
6386
+ "dev": true,
6387
+ "license": "MIT",
6388
+ "optional": true,
6389
+ "os": [
6390
+ "linux"
6391
+ ]
6392
+ },
6393
+ "node_modules/@opencode/cli-linux-x64-musl": {
6394
+ "version": "2.0.3",
6395
+ "resolved": "https://registry.npmjs.org/@opencode/cli-linux-x64-musl/-/cli-linux-x64-musl-2.0.3.tgz",
6396
+ "integrity": "sha512-YDZCk0MddTJ8lDwlEmE5bVWF5R13nDpLEQPcCA5IY2njB/y2g6UaAiIVbJE1rVmFd7/Z7JmyB2X3z60uk3C/dA==",
6397
+ "cpu": [
6398
+ "x64"
6399
+ ],
6400
+ "dev": true,
6401
+ "license": "MIT",
6402
+ "optional": true,
6403
+ "os": [
6404
+ "linux"
6405
+ ]
6406
+ },
6407
+ "node_modules/@opencode/cli-windows-arm64": {
6408
+ "version": "2.0.3",
6409
+ "resolved": "https://registry.npmjs.org/@opencode/cli-windows-arm64/-/cli-windows-arm64-2.0.3.tgz",
6410
+ "integrity": "sha512-WQuojS+6O6YNlRsal9kbePiEEv4hZHVL7l7ILRnlyZSLx7M2ynTOUahtGzC42AbdH9sdIa4OGQDmDwcbfCqHuA==",
6411
+ "cpu": [
6412
+ "arm64"
6413
+ ],
6414
+ "dev": true,
6415
+ "license": "MIT",
6416
+ "optional": true,
6417
+ "os": [
6418
+ "win32"
6419
+ ]
6420
+ },
6421
+ "node_modules/@opencode/cli-windows-x64": {
6422
+ "version": "2.0.3",
6423
+ "resolved": "https://registry.npmjs.org/@opencode/cli-windows-x64/-/cli-windows-x64-2.0.3.tgz",
6424
+ "integrity": "sha512-4pCiryt3LZG4dCkhvDOiTttzBECE36HUKe5uwCSAu9Ny7Sh2H1iVw1XFKo3QYqh6XdkWa9Uyza0lqLB6SSAGTw==",
6425
+ "cpu": [
6426
+ "x64"
6427
+ ],
6428
+ "dev": true,
6429
+ "license": "MIT",
6430
+ "optional": true,
6431
+ "os": [
6432
+ "win32"
6433
+ ]
6434
+ },
6435
+ "node_modules/@opencode/cli-windows-x64-baseline": {
6436
+ "version": "2.0.3",
6437
+ "resolved": "https://registry.npmjs.org/@opencode/cli-windows-x64-baseline/-/cli-windows-x64-baseline-2.0.3.tgz",
6438
+ "integrity": "sha512-9R6QdvoEd6bxv+Izi2kwg+85Mc3lCoTRgAsTZpNadVaRgAcU8vzEjjgrzFM6gLr8j+65EgG7vtP1gCVhfyQRwg==",
6439
+ "cpu": [
6440
+ "x64"
6441
+ ],
6442
+ "dev": true,
6443
+ "license": "MIT",
6444
+ "optional": true,
6445
+ "os": [
6446
+ "win32"
6447
+ ]
6448
+ },
6245
6449
  "node_modules/@opencode/protocol": {
6246
6450
  "version": "2.0.3",
6247
6451
  "resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.3.tgz",
@@ -20241,7 +20445,7 @@
20241
20445
  },
20242
20446
  "packages/switchboard": {
20243
20447
  "name": "@coreplane/switchboard",
20244
- "version": "1.239.0",
20448
+ "version": "1.240.0",
20245
20449
  "license": "Apache-2.0",
20246
20450
  "dependencies": {
20247
20451
  "@earendil-works/pi-ai": "0.85.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.239.0",
3
+ "version": "1.240.0",
4
4
  "private": true,
5
5
  "description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
6
6
  "license": "Apache-2.0",
@@ -91,6 +91,7 @@
91
91
  "devDependencies": {
92
92
  "@earendil-works/pi-coding-agent": "0.85.1",
93
93
  "@eslint/js": "^10.0.1",
94
+ "@opencode/cli": "^2.0.3",
94
95
  "@opencode/protocol": "2.0.3",
95
96
  "@opencode/schema": "2.0.3",
96
97
  "@types/node": "^24.0.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.239.0",
3
- "commit": "f8a99fe783b535df45b729baf09bf69557962c3a",
4
- "builtAt": "2026-09-16T23:24:01.904Z"
2
+ "version": "1.240.0",
3
+ "commit": "dd69a6edcfaa523c998ff1059f47b8ef1675ebe9",
4
+ "builtAt": "2026-09-17T00:22:24.645Z"
5
5
  }
@@ -76,6 +76,24 @@ export function resolveActor(input: ActorInput, grantsFor: GrantsLookup): Actor
76
76
  return { kind: kindFor(input.surface), id, grants: grantsFor(id), ...(origin ? { origin } : {}) };
77
77
  }
78
78
 
79
+ /** The identity fields a bound credential's message carries (`IncomingMessage`). */
80
+ interface BoundFields {
81
+ /** The credential's actor id when the sender is the person it is bound to. */
82
+ authenticatedAs?: string;
83
+ userName?: string;
84
+ }
85
+
86
+ /** The actor id whose grants govern a chat message: the credential that
87
+ * authenticated it when it was bound to a person (`authenticatedAs`), else
88
+ * the sender. Every `canRunAgent` / `canUseRepo` / `canManageRepos` /
89
+ * `canEditChannelConfig` question in the dispatch path asks about THIS id,
90
+ * never `msg.userId`: naming the person on a run must not lend the run the
91
+ * person's grants (authorization.md item 15). A relayed message (`postedBy`)
92
+ * is out of scope here — its gates are item 14's. */
93
+ export function grantsSubject(msg: { userId: string; authenticatedAs?: string }): string {
94
+ return msg.authenticatedAs ?? msg.userId;
95
+ }
96
+
79
97
  const CHAT_SURFACES: Readonly<Record<string, ActorSurface>> = {
80
98
  slack: "slack",
81
99
  http: "http",
@@ -89,11 +107,24 @@ const CHAT_SURFACES: Readonly<Record<string, ActorSurface>> = {
89
107
  * A namespace this module does not know stays a `user` with the id as given —
90
108
  * its grants are whatever config names for that id, never a guess. */
91
109
  export function resolveChatActor(
92
- msg: { userId: string; channelId: string; threadKey: string; postedBy?: string },
110
+ msg: { userId: string; channelId: string; threadKey: string; postedBy?: string } & BoundFields,
93
111
  grantsFor: GrantsLookup,
94
112
  ): Actor {
95
113
  const person = resolveNamespacedActor(msg.userId, msg, grantsFor);
96
- if (msg.postedBy === undefined) return person;
114
+ if (msg.postedBy === undefined) {
115
+ if (msg.authenticatedAs === undefined || msg.authenticatedAs === msg.userId) return person;
116
+ // A credential bound to a person (authorization.md item 15): the adapter
117
+ // proved the credential and config bound it to the person, so the actor IS
118
+ // the credential — its kind, its id, its grants, exactly as an unbound
119
+ // token's — and the person is its `self` and `asUser`, the same
120
+ // identity-not-authority link a dashboard session carries (record 0042).
121
+ const credential = resolveNamespacedActor(msg.authenticatedAs, msg, grantsFor);
122
+ return {
123
+ ...credential,
124
+ self: [credential.id, msg.userId],
125
+ asUser: { id: msg.userId, ...(msg.userName !== undefined ? { name: msg.userName } : {}) },
126
+ };
127
+ }
97
128
  // A request an app posted for a person (slack-channel.md item 13): the
98
129
  // message text named the person, and text is forgeable, so the person's
99
130
  // grants alone must never govern. The actor is the app, acting on the
@@ -81,6 +81,12 @@ export const POLICY: readonly Rule[] = [
81
81
  // `friction propose` files issues: the repo-management gate, now the `friction:write` grant.
82
82
  { action: "friction:write", resource: "command", when: [grant("friction:write")] },
83
83
 
84
+ // ── costs ────────────────────────────────────────────────────────────────
85
+ // `costs snapshot` reads both billing providers and replaces what every
86
+ // viewer of the costs page sees: the grant, never a baseline (the admins'
87
+ // `all` and a named `grants` entry hold it).
88
+ { action: "costs:write", resource: "command", when: [grant("costs:write")] },
89
+
84
90
  // ── repos ────────────────────────────────────────────────────────────────
85
91
  { action: "repo:read", resource: "command", when: [grant("repo:read")] },
86
92
  { action: "repo:write", resource: "repo", when: [grant("repo:write")] },
@@ -8,6 +8,8 @@
8
8
  // parent record the spawn route reads the requester from, and the names the
9
9
  // routes decide on.
10
10
  //
11
+ import type { AddressSeverity, AddressSeveritySource } from "../ship/coordinator.js";
12
+
11
13
  // A coordinator is a Workflow instance in the shim Worker whose children are
12
14
  // ordinary `dispatch()` runs as the requesting user. It holds no credential of
13
15
  // its own: every step is a call into the bot with the `coordinator` bearer,
@@ -126,9 +128,12 @@ export function coordinatorFields(tag: CoordinatorTag | undefined): {
126
128
  export interface CoordinatorInstance {
127
129
  id: string;
128
130
  kind: "ship";
129
- /** The requesting user (platform-namespaced), whose grants every child is authorized under. */
131
+ /** The requesting person (platform-namespaced); every child is dispatched as them. */
130
132
  userId: string;
131
133
  userName?: string;
134
+ /** The bound credential behind the person (authorization.md item 15), when
135
+ * there was one: every child is authorized under ITS grants, as the request was. */
136
+ authenticatedAs?: string;
132
137
  channelId: string;
133
138
  channelName?: string;
134
139
  /** The requesting thread: where the card lives and where a generated plan's
@@ -153,6 +158,11 @@ export interface CoordinatorInstance {
153
158
  * hand-off, answered by the plan route, checked at the merge door; absent
154
159
  * (a record written before the field existed) reads as `person`. */
155
160
  merge?: "runner" | "person";
161
+ /** The severity to address: resolved once by the hand-off
162
+ * (directive > user > channel > org) and written here beside `merge`, so
163
+ * the machine reads one value; absent reads as the default (`minor`, org). */
164
+ addressSeverity?: AddressSeverity;
165
+ addressSeveritySource?: AddressSeveritySource;
156
166
  /** The pipeline's caps as the profile gate clipped them: the rounds cap and the wall clock per unit. */
157
167
  caps?: { maxRounds: number; maxMinutes: number };
158
168
  /** The status card in the requesting thread, when the channel has one — what
@@ -234,6 +244,7 @@ export function isCoordinatorInstance(v: unknown): v is CoordinatorInstance {
234
244
  if (r.kind !== "ship") return false;
235
245
  if (!isText(r.userId) || !isText(r.channelId) || !isText(r.threadKey)) return false;
236
246
  if (!isOptionalText(r.userName) || !isOptionalText(r.channelName) || !isOptionalText(r.sourceUrl)) return false;
247
+ if (!isOptionalText(r.authenticatedAs)) return false;
237
248
  if (typeof r.repo !== "string" || !REPO_SLUG.test(r.repo)) return false;
238
249
  if (!isText(r.branch) || !isOptionalText(r.base)) return false;
239
250
  if (!isFinite(r.createdAt)) return false;
@@ -46,6 +46,9 @@ import {
46
46
  type ChildFacts,
47
47
  type MergeReadyFacts,
48
48
  type CoordinatorAction,
49
+ isAddressSeverity,
50
+ type AddressSeverity,
51
+ type AddressSeveritySource,
49
52
  type PlanGraph,
50
53
  type PlanUnitNode,
51
54
  type ShipCaps,
@@ -159,6 +162,9 @@ interface PlanFacts {
159
162
  planId?: string;
160
163
  /** Who merges, as the instance's field has it: the plan route answers it, `person` when absent. */
161
164
  merge: "runner" | "person";
165
+ /** The severity to address, beside `merge`: the level an approve's findings are held to, and which layer set it. */
166
+ addressSeverity: AddressSeverity;
167
+ addressSeveritySource: AddressSeveritySource;
162
168
  /** The instance's mark as the plan route answers it: a generated one-unit plan (a `plan` with no `path`). */
163
169
  generated: boolean;
164
170
  repo: string;
@@ -189,6 +195,11 @@ function readPlan(a: BotAnswer): PlanFacts {
189
195
  return {
190
196
  ...(typeof b.planId === "string" ? { planId: b.planId } : {}),
191
197
  merge: b.merge === "runner" ? "runner" : "person",
198
+ addressSeverity: isAddressSeverity(b.addressSeverity) ? b.addressSeverity : "minor",
199
+ addressSeveritySource:
200
+ b.addressSeveritySource === "run" || b.addressSeveritySource === "user" || b.addressSeveritySource === "channel"
201
+ ? b.addressSeveritySource
202
+ : "org",
192
203
  generated: b.generated === true,
193
204
  repo: b.repo,
194
205
  base: b.base,
@@ -465,6 +476,8 @@ async function runUnit(
465
476
  // seeded plan and `person` on a task, and the door re-checks it — the
466
477
  // branch's name never decides.
467
478
  merge: plan.merge,
479
+ addressSeverity: plan.addressSeverity,
480
+ addressSeveritySource: plan.addressSeveritySource,
468
481
  generated: plan.generated,
469
482
  ...(resume !== undefined ? { resume } : {}),
470
483
  ...(lastPush !== undefined ? { lastPush } : {}),