@coreplane/switchboard 1.238.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 (155) 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 -65
  5. package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +8 -1
  6. package/dist/assets/deploy/cloudflare-sandbox/worker.ts +337 -44
  7. package/dist/assets/deploy/cloudflare-sandbox/wrangler.template.jsonc +19 -0
  8. package/dist/assets/deploy/secrets.manifest.json +4 -4
  9. package/dist/assets/package-lock.json +207 -3
  10. package/dist/assets/package.json +2 -1
  11. package/dist/assets/source.json +3 -3
  12. package/dist/assets/src/agents/registry.ts +82 -0
  13. package/dist/assets/src/core/authz/actor.ts +33 -2
  14. package/dist/assets/src/core/authz/policy.ts +6 -0
  15. package/dist/assets/src/core/coordinator/contract.ts +12 -1
  16. package/dist/assets/src/core/coordinator/driver.ts +13 -0
  17. package/dist/assets/src/core/costs.ts +1114 -0
  18. package/dist/assets/src/core/costsSnapshotStore.ts +209 -0
  19. package/dist/assets/src/core/delivery.ts +4 -11
  20. package/dist/assets/src/core/deliverySnapshotStore.ts +12 -28
  21. package/dist/assets/src/core/ingressTokens.ts +27 -13
  22. package/dist/assets/src/core/runLedger/types.ts +3 -0
  23. package/dist/assets/src/core/runRecord.ts +10 -3
  24. package/dist/assets/src/core/schedules.ts +2 -1
  25. package/dist/assets/src/core/ship/coordinator.ts +70 -0
  26. package/dist/assets/src/core/snapshotAge.ts +30 -0
  27. package/dist/assets/src/core/stateWorkerRef.ts +41 -0
  28. package/dist/assets/src/execution/residentAutoRebuild.ts +73 -0
  29. package/dist/assets/src/execution/residentRefresh.ts +25 -3
  30. package/dist/assets/src/execution/restoreWaiters.ts +61 -0
  31. package/dist/assets/src/execution/seedPlan.ts +267 -0
  32. package/dist/assets/src/mcp/registry.ts +7 -0
  33. package/dist/assets/web/dist/.vite/manifest.json +507 -427
  34. package/dist/assets/web/dist/assets/AppShell-CM_fh-WW.js +1 -0
  35. package/dist/assets/web/dist/assets/CostsPage-BD3w5j_S.js +2 -0
  36. package/dist/assets/web/dist/assets/DeliveryPage-BtvzKA1m.js +1 -0
  37. package/dist/assets/web/dist/assets/HomePage-BU6aRCSe.js +2 -0
  38. package/dist/assets/web/dist/assets/NotFoundPage-DwOX1HaZ.js +1 -0
  39. package/dist/assets/web/dist/assets/{ResidentDetailPage-CrfCd8fx.js → ResidentDetailPage-CUAOh5d9.js} +1 -1
  40. package/dist/assets/web/dist/assets/ResidentsIndexPage-B3KUlYy2.js +1 -0
  41. package/dist/assets/web/dist/assets/RunFoldRow-Dulcbg25.js +1 -0
  42. package/dist/assets/web/dist/assets/RunRoutePage-DGoGrQZq.js +6 -0
  43. package/dist/assets/web/dist/assets/RunsIndexPage-37W7OZbC.js +1 -0
  44. package/dist/assets/web/dist/assets/{RunsTabs-XpCqeWu4.js → RunsTabs-BnkvCBrM.js} +1 -1
  45. package/dist/assets/web/dist/assets/ScheduledPage-C1y9jgAk.js +1 -0
  46. package/dist/assets/web/dist/assets/SettingsPage-ggfB-Rqr.js +1 -0
  47. package/dist/assets/web/dist/assets/SlackMark-VDNs7Vjh.js +1 -0
  48. package/dist/assets/web/dist/assets/Slideover-CX-LEklF.js +1 -0
  49. package/dist/assets/web/dist/assets/{StatusDot-DkXALvKf.js → StatusDot-CiByEtoR.js} +1 -1
  50. package/dist/assets/web/dist/assets/{Tooltip-DtLIyi5P.js → Tooltip-DyRxk8A8.js} +1 -1
  51. package/dist/assets/web/dist/assets/UnitRoutePage-CnWyOizV.js +1 -0
  52. package/dist/assets/web/dist/assets/{angular-html-DYtV9uIN.js → angular-html-DAQ_1T1v.js} +1 -1
  53. package/dist/assets/web/dist/assets/{angular-ts-DF2P25Zp.js → angular-ts-D4kxRVp1.js} +1 -1
  54. package/dist/assets/web/dist/assets/{apl-Ff96wxko.js → apl-Dy07l64y.js} +1 -1
  55. package/dist/assets/web/dist/assets/{astro-LbBnZna-.js → astro-DZIbTlc7.js} +1 -1
  56. package/dist/assets/web/dist/assets/{blade-DltuxeBW.js → blade-CmSXWX3l.js} +1 -1
  57. package/dist/assets/web/dist/assets/{c-DBg7yuPx.js → c-ggzVdJLK.js} +1 -1
  58. package/dist/assets/web/dist/assets/{chapel-C83hUAds.js → chapel-Bo1wktsG.js} +1 -1
  59. package/dist/assets/web/dist/assets/{cobol-DB0yV_2D.js → cobol-DJUmtKM2.js} +1 -1
  60. package/dist/assets/web/dist/assets/{coffee-Bpih6Kzl.js → coffee-BZWOVz4C.js} +1 -1
  61. package/dist/assets/web/dist/assets/{cpp-CU00ZeRn.js → cpp-Dtk39yMw.js} +1 -1
  62. package/dist/assets/web/dist/assets/{crystal-f8ImJkux.js → crystal-CGf_-Zoj.js} +1 -1
  63. package/dist/assets/web/dist/assets/{css-4VrC4ISo.js → css-CX2fcL4u.js} +1 -1
  64. package/dist/assets/web/dist/assets/delivery-CTdOqpVK.js +1 -0
  65. package/dist/assets/web/dist/assets/{dist-DtA7JiH5.js → dist-D8TaC961.js} +2 -2
  66. package/dist/assets/web/dist/assets/durationTone-DXG-3R7_.js +1 -0
  67. package/dist/assets/web/dist/assets/{edge-BwFDzfS_.js → edge-BYS8FtgQ.js} +1 -1
  68. package/dist/assets/web/dist/assets/{elixir-wwIYIpJm.js → elixir-fhUpi3nO.js} +1 -1
  69. package/dist/assets/web/dist/assets/{elm-DyDuM3v3.js → elm-DAQNiwsN.js} +1 -1
  70. package/dist/assets/web/dist/assets/{erb-DFJBEVrh.js → erb-CWzEys6U.js} +1 -1
  71. package/dist/assets/web/dist/assets/eventSource-tRprhqm7.js +1 -0
  72. package/dist/assets/web/dist/assets/favicon-D1hkyC5j.js +1 -0
  73. package/dist/assets/web/dist/assets/{git-rebase-CuDv-44X.js → git-rebase-9rY3p-Rw.js} +1 -1
  74. package/dist/assets/web/dist/assets/{glimmer-js-ZFnrm4J3.js → glimmer-js-tY7hy0nE.js} +1 -1
  75. package/dist/assets/web/dist/assets/{glimmer-ts-XY4Yqshp.js → glimmer-ts-CTrLv5JF.js} +1 -1
  76. package/dist/assets/web/dist/assets/{glsl-xnR8efx0.js → glsl-BRJbiDfq.js} +1 -1
  77. package/dist/assets/web/dist/assets/{graphql-D-gO5tnP.js → graphql-B-MtVLh2.js} +1 -1
  78. package/dist/assets/web/dist/assets/{hack-CSxbW4ax.js → hack-BtIkOypQ.js} +1 -1
  79. package/dist/assets/web/dist/assets/{haml-D4ar42QT.js → haml-CoOH6gfa.js} +1 -1
  80. package/dist/assets/web/dist/assets/{handlebars-CMLbDE7o.js → handlebars-DgrRu-GP.js} +1 -1
  81. package/dist/assets/web/dist/assets/{html-CVekU4Fs.js → html-DZaaI7ca.js} +1 -1
  82. package/dist/assets/web/dist/assets/{html-derivative-St3HHw_N.js → html-derivative-DgHvT-qZ.js} +1 -1
  83. package/dist/assets/web/dist/assets/{http-Mon0DWHS.js → http-CvAd51yz.js} +1 -1
  84. package/dist/assets/web/dist/assets/{hurl-Cbl5IvBs.js → hurl-CXGqAfzx.js} +1 -1
  85. package/dist/assets/web/dist/assets/{localIso-CNA-bhS-.js → indexFormat-B-pd4r7Y.js} +1 -1
  86. package/dist/assets/web/dist/assets/{indexRow-FLJu5mR9.js → indexRow-Cse3JGb0.js} +1 -1
  87. package/dist/assets/web/dist/assets/{java-Bprck1l-.js → java-CIQStIXF.js} +1 -1
  88. package/dist/assets/web/dist/assets/{javascript-C73G1-UR.js → javascript-WbH8s7E3.js} +1 -1
  89. package/dist/assets/web/dist/assets/{jinja-C4DuRxYJ.js → jinja-DzyWEVKC.js} +1 -1
  90. package/dist/assets/web/dist/assets/{jison-B2U03GEC.js → jison-CrT-zCa-.js} +1 -1
  91. package/dist/assets/web/dist/assets/{json-CvTZUDzx.js → json-lHjpjXMQ.js} +1 -1
  92. package/dist/assets/web/dist/assets/{jsx-DMWKCzwo.js → jsx-WTwYCHW6.js} +1 -1
  93. package/dist/assets/web/dist/assets/{julia-Czn7bV_3.js → julia-Bqpk9H7E.js} +1 -1
  94. package/dist/assets/web/dist/assets/{just-BBxpNfvC.js → just-LdXk1r3m.js} +1 -1
  95. package/dist/assets/web/dist/assets/{latex-Bw9yg5mr.js → latex-h_y2A5KD.js} +1 -1
  96. package/dist/assets/web/dist/assets/{liquid-BRCjaydE.js → liquid-CY7bF2_p.js} +1 -1
  97. package/dist/assets/web/dist/assets/localIso-L06jV29p.js +1 -0
  98. package/dist/assets/web/dist/assets/{lua-DUu2KIC0.js → lua-oQ7XVZOY.js} +1 -1
  99. package/dist/assets/web/dist/assets/main-CGO6fQ8k.js +28 -0
  100. package/dist/assets/web/dist/assets/main-O8UXRuEv.css +1 -0
  101. package/dist/assets/web/dist/assets/{marko-CZJZIlSQ.js → marko-zv_qZ4QV.js} +1 -1
  102. package/dist/assets/web/dist/assets/{mdc-BmClq6fd.js → mdc-Dl4kL_YK.js} +1 -1
  103. package/dist/assets/web/dist/assets/{nginx-Bmt3xSEm.js → nginx-CAHCZj4F.js} +1 -1
  104. package/dist/assets/web/dist/assets/{nim-Da-i0utK.js → nim-BOtmwCJH.js} +1 -1
  105. package/dist/assets/web/dist/assets/{org-BvAre2qP.js → org-DspQk3HQ.js} +1 -1
  106. package/dist/assets/web/dist/assets/{perl-v9WwFFtB.js → perl-CAXmvVl0.js} +1 -1
  107. package/dist/assets/web/dist/assets/{php-DTU4Zyze.js → php-CMUx4VyM.js} +1 -1
  108. package/dist/assets/web/dist/assets/{pug-DhTwEqTO.js → pug-B55xVJTv.js} +1 -1
  109. package/dist/assets/web/dist/assets/{qml-BUD9AC_c.js → qml-DsNKCCRk.js} +1 -1
  110. package/dist/assets/web/dist/assets/{r-CAnu56n7.js → r-DbhP0VvO.js} +1 -1
  111. package/dist/assets/web/dist/assets/{razor-Dn0P4gAq.js → razor-BCpE6P-p.js} +1 -1
  112. package/dist/assets/web/dist/assets/{regexp-CZyBRaVW.js → regexp-BllsjiN4.js} +1 -1
  113. package/dist/assets/web/dist/assets/{rst-Ckyd5UsY.js → rst-CO5Rpq9V.js} +1 -1
  114. package/dist/assets/web/dist/assets/{ruby-BBQ62fsx.js → ruby-C2A4OgQq.js} +1 -1
  115. package/dist/assets/web/dist/assets/{sas-CW35hMxG.js → sas-Butzoyql.js} +1 -1
  116. package/dist/assets/web/dist/assets/{scss-CpV8pF4J.js → scss-PEUwJBpf.js} +1 -1
  117. package/dist/assets/web/dist/assets/settingsApi-priOPiwu.js +1 -0
  118. package/dist/assets/web/dist/assets/{shellscript-CRJvsmE1.js → shellscript-3Yhq0khE.js} +1 -1
  119. package/dist/assets/web/dist/assets/{shellsession-CyriUZxf.js → shellsession-04Hkb7m3.js} +1 -1
  120. package/dist/assets/web/dist/assets/{soy-D5QzYUeg.js → soy-BnId73cP.js} +1 -1
  121. package/dist/assets/web/dist/assets/{sql-CUBf_Mse.js → sql-BKwdc0ch.js} +1 -1
  122. package/dist/assets/web/dist/assets/sseReplay-DutHNghE.js +9 -0
  123. package/dist/assets/web/dist/assets/{stata-B-4n4ITz.js → stata-BPPtNkay.js} +1 -1
  124. package/dist/assets/web/dist/assets/{surrealql-RuWZBLtr.js → surrealql-CDPChcYP.js} +1 -1
  125. package/dist/assets/web/dist/assets/{svelte-CO5YzCsK.js → svelte-B15DIQ-z.js} +1 -1
  126. package/dist/assets/web/dist/assets/{templ-DbkWVaBF.js → templ-D-rp_AiB.js} +1 -1
  127. package/dist/assets/web/dist/assets/{tex-IuxoEcId.js → tex-BnVDCD7p.js} +1 -1
  128. package/dist/assets/web/dist/assets/{ts-tags-g6dGQPjd.js → ts-tags-cpujdyAR.js} +1 -1
  129. package/dist/assets/web/dist/assets/{tsx-WnXwiyH2.js → tsx-D1vO4L72.js} +1 -1
  130. package/dist/assets/web/dist/assets/{twig-Lx1G7PnY.js → twig-oQGnQGRc.js} +1 -1
  131. package/dist/assets/web/dist/assets/{typescript-BQd7biLF.js → typescript-CKSFpXiH.js} +1 -1
  132. package/dist/assets/web/dist/assets/{typst-D2lXPHK7.js → typst-DKHFo8BF.js} +1 -1
  133. package/dist/assets/web/dist/assets/{vue-4wVQD9y9.js → vue-BstokpiS.js} +1 -1
  134. package/dist/assets/web/dist/assets/{vue-html-DZPaRte4.js → vue-html-DpCp0_Sz.js} +1 -1
  135. package/dist/assets/web/dist/assets/{vue-vine-DbmZCmu-.js → vue-vine-y5d5wUb1.js} +1 -1
  136. package/dist/assets/web/dist/assets/{xml-DV16szyo.js → xml-Br2hx5Ax.js} +1 -1
  137. package/dist/assets/web/dist/assets/{xsl-eo5-1sk0.js → xsl-Bc8Cobap.js} +1 -1
  138. package/dist/assets/web/dist/assets/{yaml-BXdX8HZf.js → yaml-LOITy_I1.js} +1 -1
  139. package/dist/cli.js +2586 -1603
  140. package/package.json +1 -1
  141. package/dist/assets/web/dist/assets/AppShell-MYHNxJks.js +0 -1
  142. package/dist/assets/web/dist/assets/CostsPage-DKk9OjB0.js +0 -2
  143. package/dist/assets/web/dist/assets/DeliveryPage-Kz6js49i.js +0 -1
  144. package/dist/assets/web/dist/assets/NotFoundPage-BXLrQQzy.js +0 -1
  145. package/dist/assets/web/dist/assets/ResidentsIndexPage-BdW0k2h3.js +0 -1
  146. package/dist/assets/web/dist/assets/RunFoldRow-CbTd9SiS.js +0 -9
  147. package/dist/assets/web/dist/assets/RunRoutePage-br0H-8Pz.js +0 -6
  148. package/dist/assets/web/dist/assets/RunsIndexPage-Bnzb15zH.js +0 -1
  149. package/dist/assets/web/dist/assets/ScheduledPage-NLhjzHAz.js +0 -1
  150. package/dist/assets/web/dist/assets/SettingsPage-D-i0uVw-.js +0 -1
  151. package/dist/assets/web/dist/assets/UnitRoutePage-DGXukEAH.js +0 -1
  152. package/dist/assets/web/dist/assets/durationTone-CYMux25J.js +0 -1
  153. package/dist/assets/web/dist/assets/favicon-CSt-qDvc.js +0 -1
  154. package/dist/assets/web/dist/assets/main-CFHF2RvQ.css +0 -1
  155. package/dist/assets/web/dist/assets/main-Dht0in4v.js +0 -28
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.238.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.238.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.238.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.238.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.238.0",
3
- "commit": "9990b225865690781f1d97b7128228af23e39500",
4
- "builtAt": "2026-09-16T22:38:02.661Z"
2
+ "version": "1.240.0",
3
+ "commit": "dd69a6edcfaa523c998ff1059f47b8ef1675ebe9",
4
+ "builtAt": "2026-09-17T00:22:24.645Z"
5
5
  }
@@ -106,6 +106,13 @@ export interface AgentDef {
106
106
  * discovery, no gh CLI. Selected by the dispatcher AFTER executor
107
107
  * resolution via RunOptions.system; the shared AgentDef is never mutated. */
108
108
  residentSystem?: string;
109
+ /** System prompt variant for a sandbox seeded from the resident's snapshot
110
+ * (docs/reference/specs/execution.md item 26): the repository is already
111
+ * cloned at the seeded checkout, on the thread's branch, deps installed —
112
+ * no cloning, no installs, no repo discovery — while `gh` and Docker ARE
113
+ * there, unlike the resident. Selected by the dispatcher AFTER executor
114
+ * resolution like the resident variant; the shared AgentDef is never mutated. */
115
+ seededSystem?: string;
109
116
  }
110
117
 
111
118
  // Every PR the coding agent ships carries a rich description by default —
@@ -279,6 +286,45 @@ Report outcomes faithfully: if tests fail or a step was skipped, say so plainly.
279
286
  ${FENCED_CONTENT_RULE}
280
287
  Your final message is posted to Slack — keep it readable, lead with the outcome.`;
281
288
 
289
+ // Seeded-sandbox variant (docs/reference/specs/execution.md item 26): the run
290
+ // landed in a per-thread sandbox that was seeded from the resident's snapshot
291
+ // before its first command — the repository already cloned at the seeded
292
+ // checkout, on the thread's branch, dependencies installed. The scope-first /
293
+ // clone workflow above would waste the head start; unlike the resident, the
294
+ // sandbox image has `gh`, Docker, and both git and gh authenticated.
295
+ export const CODING_SYSTEM_SEEDED = `You are Switchboard's coding agent, operating from a Slack request.
296
+
297
+ You work inside a dedicated sandbox with bash, read_file, and write_file tools. ${SANDBOX_TOOLCHAIN}
298
+
299
+ THE REPOSITORY IS ALREADY CLONED at \`/workspace/checkout\` — seeded from the resident's snapshot: a ready git checkout of the target repository on this thread's branch, dependencies installed. Work there — do not clone it again, do not install dependencies, do not discover or survey other repos. Orient with a few BATCHED commands (e.g. \`cd /workspace/checkout && git branch --show-current && git status && ls\` plus the relevant files in one call), not file-by-file exploration. \`gh\` and git are both authenticated on this host.
300
+
301
+ Workflow for shipping a change:
302
+ 1. Create a branch with a descriptive name off the current branch.
303
+ 2. Implement the change. Match the surrounding code's style and conventions.
304
+ 3. Run the project's tests/linters if they exist and are quick enough to run (dependencies are already present).
305
+ 4. Commit with a clear message and push the branch with \`git push -u origin <branch>\`.
306
+ 5. Call the \`diff_digest\` tool to get a distilled summary of your change — per-file churn, totals, and risky-file flags. It is a distilled summary, not the raw diff: use it to shape the description you submit next — which files the Tour must walk, what belongs in risks.
307
+ 6. Call the submit_pr_description tool with the typed description object (content contract below) — every time. Switchboard renders the PR body from your object at the pushed head and opens (or updates) the pull request itself: do NOT open a PR yourself, with \`gh\` or any API call.
308
+ 7. Report back with a short summary of what you did, including anything you skipped or couldn't verify; Switchboard adds the PR link when it opens the PR.
309
+
310
+ ${NEVER_MERGE}
311
+
312
+ ${UNIT_CONTRACT}
313
+
314
+ ${UNIT_HANDOFF}
315
+
316
+ ${PR_DESCRIPTION_TEMPLATE}
317
+
318
+ ${SHOW_FILES}
319
+
320
+ ${NOTEPAD}
321
+
322
+ Maintain the user-facing status card with the update_status tool: right after you decide your plan, post it as a checklist (○ pending items), then update it whenever an item starts (✱) or finishes (✓). Items are short outcomes ("Implement the fix", "Run the test suite"), never commands. Mark an item ✓ only after it has actually happened — never pre-mark reporting/posting steps. This is the only progress the user sees while you work.
323
+
324
+ Report outcomes faithfully: if tests fail or a step was skipped, say so plainly.
325
+ ${FENCED_CONTENT_RULE}
326
+ Your final message is posted to Slack — keep it readable, lead with the outcome.`;
327
+
282
328
  // Both review prompts carry this verbatim. The findings contract
283
329
  // (docs/reference/specs/agent-ship.md item 6) lives here once — stable ids, the severity
284
330
  // vocabulary, the approve-over-blocking downgrade — so the sandbox and
@@ -376,6 +422,40 @@ Maintain the user-facing status card with the update_status tool: post your plan
376
422
  ${FENCED_CONTENT_RULE}
377
423
  Your final message is posted to Slack. Lead with a one-line verdict, then the findings.`;
378
424
 
425
+ // Seeded-sandbox variant for review (docs/reference/specs/execution.md item 26):
426
+ // the gather-once discipline against a checkout that is already at the PR
427
+ // head — no clone — with `gh` available for the PR's metadata, as in the
428
+ // sandbox image.
429
+ export const REVIEW_SYSTEM_SEEDED = `You are Switchboard's code review agent, operating from a Slack request.
430
+
431
+ You have bash and read_file tools in a dedicated sandbox. ${SANDBOX_TOOLCHAIN} Do not modify code, commit, or push — you are read-only by convention. Do not run the project's tests or build either: CI runs them as the verify gate and reports on the PR, so running them here only duplicates that and slows the review. Your job is to read the code. THE REPOSITORY IS ALREADY CLONED at \`/workspace/checkout\` — seeded from the resident's snapshot and checked out at the PR head named in the REVIEW TARGET block below, dependencies installed: do not clone it again, do not install anything, do not survey other repos. \`gh\` is available for the pull request's metadata.
432
+
433
+ Strategy — GATHER ONCE, THEN ANALYZE ONCE. Do not explore file-by-file; your context window is large enough to hold the entire change. Speed matters: a review should take minutes, not an hour.
434
+
435
+ 1. GATHER, in 2-4 batched tool calls total:
436
+ - from \`/workspace/checkout\`: \`gh pr view <ref> --json title,body,url,baseRefName\` and \`git diff origin/<base>...HEAD\` (the complete diff; \`origin/<base>\` — the PR's base branch, named in the REVIEW TARGET block — is already present) in one command
437
+ - call the \`diff_digest\` tool to orient: it gives per-file churn, totals, and risky-file flags (migrations/schema, auth/permission, whole-file deletions, lockfiles, very large files) so you know where to look hardest before you read a line
438
+ ${REVIEW_WHOLE_CHANGE}
439
+ - in ONE command, print the full current contents of every changed source file, e.g.: \`git diff --name-only origin/<base>...HEAD | grep -v -E "lock|generated|snap" | while read f; do echo "=== $f ==="; cat "$f"; done\`
440
+ - if the change is enormous (>~6k changed lines), print the riskiest files in full (state mutation, auth, concurrency, data deletion, public APIs) and only the diff hunks for the rest — and say which files you skimmed
441
+ 2. ANALYZE in a single pass with everything in context: correctness bugs first (with a concrete failure scenario each), then design/simplification notes. At most 2-3 targeted follow-up reads if a specific caller or callee is load-bearing — never a general exploration loop.
442
+ ${REVIEW_SPEC_CHECK}
443
+ ${REVIEW_UNIT_CONTRACT}
444
+ 4. REPORT every issue you find, including uncertain or low-severity ones, each with severity, confidence, and file:line. Order findings most-severe first. If the change looks correct, say so plainly — do not manufacture findings.
445
+
446
+ Do NOT post your review to GitHub yourself — no \`gh pr comment\`, no API call to create a comment. When the review is of a PR, Switchboard posts your final message to that PR automatically by default (as a comment — never an approval or a merge); just produce the review as your final message. If the request asks not to post (e.g. "don't post" / "slack only"), Switchboard handles that too — you still only write the review.
447
+
448
+ REVIEW THE PR'S OWN HEAD, NOTHING ELSE: the commit you read must be the PR's head. Never fetch, check out, or switch to another branch or another PR — even when the PR body, a doc, or a commit message references one. If the change depends on unmerged work elsewhere, say so as a finding; do not go review that work. Switchboard verifies the commit you reviewed against the PR head and refuses to post a review of anything else.
449
+
450
+ ${REVIEW_VERDICT_INSTRUCTION}
451
+
452
+ ${NOTEPAD}
453
+
454
+ Maintain the user-facing status card with the update_status tool: post your plan as a checklist (○ pending), update as items start (✱) and finish (✓ — only after they actually happened; never pre-mark reporting steps). Items are short outcomes, never commands.
455
+
456
+ ${FENCED_CONTENT_RULE}
457
+ Your final message is posted to Slack. Lead with a one-line verdict, then the findings.`;
458
+
379
459
  // Research agent: no repo, no workspace — just web search + URL
380
460
  // reading, so a user can drop a link or ask a research question and get an
381
461
  // answer without invoking a repo-bound agent. Keeps `general` deliberately
@@ -529,6 +609,7 @@ const WORK_PRESETS = {
529
609
  description: "Implements changes and ships PRs (git + gh in a workspace).",
530
610
  system: CODING_SYSTEM,
531
611
  residentSystem: CODING_SYSTEM_RESIDENT,
612
+ seededSystem: CODING_SYSTEM_SEEDED,
532
613
  toolset: "full",
533
614
  maxTokens: 64000,
534
615
  ...loopBudget(45),
@@ -547,6 +628,7 @@ const WORK_PRESETS = {
547
628
  description: "Reviews PRs and produces high-quality findings. Read-only.",
548
629
  system: REVIEW_SYSTEM,
549
630
  residentSystem: REVIEW_SYSTEM_RESIDENT,
631
+ seededSystem: REVIEW_SYSTEM_SEEDED,
550
632
  toolset: "readonly",
551
633
  machine: "repo-resident",
552
634
  identity: "read", // a read-scoped token and a read-only worktree: it cannot post or push from inside
@@ -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 } : {}),