@wenathlan/saddle 2.0.150 → 2.0.152

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 (296) hide show
  1. package/Dockerfile +43 -23
  2. package/README.md +4 -4
  3. package/biome.jsonc +134 -0
  4. package/dist/App.d.ts +3 -0
  5. package/dist/App.js +50 -0
  6. package/dist/Sol/Sol.d.ts +3 -0
  7. package/dist/Sol/Sol.js +46 -0
  8. package/dist/Sol/agentbrowser/agentbrowser.d.ts +9 -0
  9. package/dist/Sol/agentbrowser/agentbrowser.js +121 -0
  10. package/dist/Sol/architecture/architecture.d.ts +9 -0
  11. package/dist/Sol/architecture/architecture.js +93 -0
  12. package/dist/Sol/compute/compute.d.ts +9 -0
  13. package/dist/Sol/compute/compute.js +22 -0
  14. package/dist/Sol/console/console.d.ts +15 -0
  15. package/dist/Sol/console/console.js +292 -0
  16. package/dist/Sol/dashboard/dashboard.d.ts +10 -0
  17. package/dist/Sol/dashboard/dashboard.js +181 -0
  18. package/dist/Sol/docs/docs.d.ts +9 -0
  19. package/dist/Sol/docs/docs.js +28 -0
  20. package/dist/Sol/home/home.d.ts +35 -0
  21. package/dist/Sol/home/home.js +239 -0
  22. package/dist/Sol/integrations/integrations.d.ts +9 -0
  23. package/dist/Sol/integrations/integrations.js +83 -0
  24. package/dist/Sol/intro/intro.d.ts +7 -0
  25. package/dist/Sol/intro/intro.js +102 -0
  26. package/dist/Sol/login/login.d.ts +16 -0
  27. package/dist/Sol/login/login.js +49 -0
  28. package/dist/Sol/notfound/notfound.d.ts +9 -0
  29. package/dist/Sol/notfound/notfound.js +15 -0
  30. package/dist/Sol/onboarding/onboarding.d.ts +25 -0
  31. package/dist/Sol/onboarding/onboarding.js +60 -0
  32. package/dist/Sol/playground/playground.d.ts +9 -0
  33. package/dist/Sol/playground/playground.js +127 -0
  34. package/dist/Sol/register/register.d.ts +16 -0
  35. package/dist/Sol/register/register.js +193 -0
  36. package/dist/Sol/shell/Shell.d.ts +124 -0
  37. package/dist/Sol/shell/Shell.js +335 -0
  38. package/dist/Sol/wingets/ComputeBootladder.d.ts +6 -0
  39. package/dist/Sol/wingets/ComputeBootladder.js +71 -0
  40. package/dist/Sol/wingets/ComputeModalitycatalog.d.ts +7 -0
  41. package/dist/Sol/wingets/ComputeModalitycatalog.js +71 -0
  42. package/dist/Sol/wingets/ConsoleApibadge.d.ts +7 -0
  43. package/dist/Sol/wingets/ConsoleApibadge.js +5 -0
  44. package/dist/Sol/wingets/ConsoleEdgelaw.d.ts +6 -0
  45. package/dist/Sol/wingets/ConsoleEdgelaw.js +36 -0
  46. package/dist/Sol/wingets/ConsoleEventstimeline.d.ts +19 -0
  47. package/dist/Sol/wingets/ConsoleEventstimeline.js +12 -0
  48. package/dist/Sol/wingets/ConsoleSnapshotcontrols.d.ts +8 -0
  49. package/dist/Sol/wingets/ConsoleSnapshotcontrols.js +8 -0
  50. package/dist/Sol/wingets/ConsoleSpecpanel.d.ts +21 -0
  51. package/dist/Sol/wingets/ConsoleSpecpanel.js +75 -0
  52. package/dist/Sol/wingets/ConsoleTerminal.d.ts +22 -0
  53. package/dist/Sol/wingets/ConsoleTerminal.js +77 -0
  54. package/dist/Sol/wingets/DashboardAccountpanel.d.ts +18 -0
  55. package/dist/Sol/wingets/DashboardAccountpanel.js +65 -0
  56. package/dist/Sol/wingets/DashboardAdminpanel.d.ts +6 -0
  57. package/dist/Sol/wingets/DashboardAdminpanel.js +90 -0
  58. package/dist/Sol/wingets/DashboardAuditlog.d.ts +8 -0
  59. package/dist/Sol/wingets/DashboardAuditlog.js +50 -0
  60. package/dist/Sol/wingets/DashboardCreatesandboxform.d.ts +10 -0
  61. package/dist/Sol/wingets/DashboardCreatesandboxform.js +71 -0
  62. package/dist/Sol/wingets/DashboardEventstimeline.d.ts +8 -0
  63. package/dist/Sol/wingets/DashboardEventstimeline.js +83 -0
  64. package/dist/Sol/wingets/DashboardGlobalsandboxestable.d.ts +8 -0
  65. package/dist/Sol/wingets/DashboardGlobalsandboxestable.js +57 -0
  66. package/dist/Sol/wingets/DashboardMeshnodestable.d.ts +8 -0
  67. package/dist/Sol/wingets/DashboardMeshnodestable.js +103 -0
  68. package/dist/Sol/wingets/DashboardSandboxlist.d.ts +10 -0
  69. package/dist/Sol/wingets/DashboardSandboxlist.js +163 -0
  70. package/dist/Sol/wingets/DashboardUserstable.d.ts +8 -0
  71. package/dist/Sol/wingets/DashboardUserstable.js +78 -0
  72. package/dist/Sol/wingets/HomeEntrygate.d.ts +23 -0
  73. package/dist/Sol/wingets/HomeEntrygate.js +73 -0
  74. package/dist/Sol/wingets/HomeMetricstrip.d.ts +9 -0
  75. package/dist/Sol/wingets/HomeMetricstrip.js +4 -0
  76. package/dist/Sol/wingets/HomeRuntimediagram.d.ts +1 -0
  77. package/dist/Sol/wingets/HomeRuntimediagram.js +22 -0
  78. package/dist/Sol/wingets/LoginForm.d.ts +19 -0
  79. package/dist/Sol/wingets/LoginForm.js +141 -0
  80. package/dist/Sol/wingets/RegisterPasswordconfirm.d.ts +13 -0
  81. package/dist/Sol/wingets/RegisterPasswordconfirm.js +16 -0
  82. package/dist/Sol/wingets/RegisterPasswordmeter.d.ts +19 -0
  83. package/dist/Sol/wingets/RegisterPasswordmeter.js +65 -0
  84. package/dist/Sol/wingets/RegisterUsernamerules.d.ts +11 -0
  85. package/dist/Sol/wingets/RegisterUsernamerules.js +16 -0
  86. package/dist/Sol/wingets/index.d.ts +39 -0
  87. package/dist/Sol/wingets/index.js +39 -0
  88. package/dist/alternatives.d.ts +508 -0
  89. package/dist/alternatives.js +950 -0
  90. package/dist/api.d.ts +154 -0
  91. package/dist/api.js +174 -0
  92. package/dist/auth.d.ts +268 -0
  93. package/dist/auth.js +476 -0
  94. package/dist/automation.d.ts +425 -0
  95. package/dist/automation.js +566 -0
  96. package/dist/browser.d.ts +561 -0
  97. package/dist/browser.js +1058 -0
  98. package/dist/capacitor.config.d.ts +45 -0
  99. package/dist/capacitor.config.js +48 -0
  100. package/dist/catalog.d.ts +43 -0
  101. package/dist/catalog.js +44 -0
  102. package/dist/cli.d.ts +16 -0
  103. package/dist/cli.js +168 -0
  104. package/dist/communication.d.ts +181 -0
  105. package/dist/communication.js +376 -0
  106. package/dist/compute.d.ts +1160 -0
  107. package/dist/compute.js +2272 -0
  108. package/dist/dashboardlib.d.ts +58 -0
  109. package/dist/dashboardlib.js +161 -0
  110. package/dist/db.d.ts +569 -0
  111. package/dist/db.js +1080 -0
  112. package/dist/distribution.d.ts +528 -0
  113. package/dist/distribution.js +810 -0
  114. package/dist/drizzle.config.d.ts +20 -0
  115. package/dist/drizzle.config.js +18 -0
  116. package/dist/edgelandes.d.ts +70 -0
  117. package/dist/edgelandes.host.d.ts +26 -0
  118. package/dist/edgelandes.host.js +1089 -0
  119. package/dist/edgelandes.inproc.d.ts +27 -0
  120. package/dist/edgelandes.inproc.js +952 -0
  121. package/dist/edgelandes.js +1133 -0
  122. package/dist/edgelandes.ninety.d.ts +31 -0
  123. package/dist/edgelandes.ninety.js +174 -0
  124. package/dist/edgelandes.virtual.d.ts +25 -0
  125. package/dist/edgelandes.virtual.js +629 -0
  126. package/dist/edgeplane.d.ts +114 -0
  127. package/dist/edgeplane.js +305 -0
  128. package/dist/examplelocaljob.d.ts +1 -0
  129. package/{docs/example-localjob.ts → dist/examplelocaljob.js} +0 -1
  130. package/dist/execution.d.ts +529 -0
  131. package/dist/execution.js +760 -0
  132. package/dist/family.d.ts +16 -0
  133. package/dist/family.js +42 -0
  134. package/dist/familyurl.d.ts +21 -0
  135. package/dist/familyurl.js +24 -0
  136. package/dist/format.d.ts +18 -0
  137. package/dist/format.js +59 -0
  138. package/dist/foundation.d.ts +172 -0
  139. package/dist/foundation.js +312 -0
  140. package/dist/index.d.ts +735 -0
  141. package/dist/index.js +1020 -0
  142. package/dist/integration.d.ts +235 -0
  143. package/dist/integration.js +228 -0
  144. package/dist/intelligence.d.ts +93 -0
  145. package/dist/intelligence.js +144 -0
  146. package/dist/isolation.d.ts +128 -0
  147. package/dist/isolation.js +95 -0
  148. package/dist/labels.d.ts +665 -0
  149. package/dist/labels.js +751 -0
  150. package/dist/localauth.d.ts +127 -0
  151. package/dist/localauth.js +413 -0
  152. package/dist/media.d.ts +343 -0
  153. package/dist/media.js +985 -0
  154. package/dist/mesh.d.ts +177 -0
  155. package/dist/mesh.js +468 -0
  156. package/dist/modalityregistry.d.ts +109 -0
  157. package/dist/modalityregistry.js +1386 -0
  158. package/dist/modes.d.ts +358 -0
  159. package/dist/modes.js +133 -0
  160. package/dist/onboardingstate.d.ts +79 -0
  161. package/dist/onboardingstate.js +282 -0
  162. package/dist/orchestrator.d.ts +1338 -0
  163. package/dist/orchestrator.js +4310 -0
  164. package/dist/packager/targetcli.js +4 -0
  165. package/dist/paths.d.ts +2 -0
  166. package/dist/paths.js +14 -0
  167. package/dist/performance.d.ts +415 -0
  168. package/dist/performance.js +826 -0
  169. package/dist/quantum.d.ts +809 -0
  170. package/dist/quantum.js +2072 -0
  171. package/dist/render.d.ts +380 -0
  172. package/dist/render.js +1072 -0
  173. package/dist/runall.d.ts +2 -0
  174. package/dist/runall.js +39 -0
  175. package/dist/runtimeprobe.d.ts +4 -0
  176. package/dist/runtimeprobe.js +8 -0
  177. package/dist/sandbox.d.ts +355 -0
  178. package/dist/sandbox.js +1721 -0
  179. package/dist/sandboxenvprofile.d.ts +29 -0
  180. package/dist/sandboxenvprofile.js +89 -0
  181. package/dist/sandboxprofile.d.ts +137 -0
  182. package/dist/sandboxprofile.js +241 -0
  183. package/dist/sandboxqueue.d.ts +108 -0
  184. package/dist/sandboxqueue.js +201 -0
  185. package/dist/sandboxquota.d.ts +121 -0
  186. package/dist/sandboxquota.js +236 -0
  187. package/dist/scheduler.d.ts +595 -0
  188. package/dist/scheduler.js +1258 -0
  189. package/dist/scriptlanes.d.ts +182 -0
  190. package/dist/scriptlanes.js +660 -0
  191. package/dist/scripts.buildengine.d.ts +1 -0
  192. package/dist/scripts.buildengine.js +39 -0
  193. package/dist/scripts.securitygate.d.ts +1 -0
  194. package/dist/scripts.securitygate.js +68 -0
  195. package/dist/scripts.validateflatnative.d.ts +1 -0
  196. package/dist/scripts.validateflatnative.js +72 -0
  197. package/dist/security.d.ts +500 -0
  198. package/dist/security.js +1169 -0
  199. package/dist/seedcatalog.d.ts +13 -0
  200. package/dist/seedcatalog.js +46 -0
  201. package/dist/server.d.ts +20 -0
  202. package/dist/server.js +53 -0
  203. package/dist/speccatalog.d.ts +31 -0
  204. package/dist/speccatalog.js +163 -0
  205. package/dist/tiers.d.ts +1001 -0
  206. package/dist/tiers.js +2169 -0
  207. package/dist/utils.d.ts +2 -0
  208. package/dist/utils.js +5 -0
  209. package/dist/vaulthandoff.d.ts +141 -0
  210. package/dist/vaulthandoff.js +444 -0
  211. package/dist/virtual.d.ts +640 -0
  212. package/dist/virtual.js +1284 -0
  213. package/dist/virtualcpu.d.ts +315 -0
  214. package/dist/virtualcpu.js +1180 -0
  215. package/dist/virtualgpu.d.ts +344 -0
  216. package/dist/virtualgpu.js +1000 -0
  217. package/dist/virtualization.d.ts +606 -0
  218. package/dist/virtualization.js +1186 -0
  219. package/dist/virtualmemory.d.ts +817 -0
  220. package/dist/virtualmemory.js +1795 -0
  221. package/dist/vite.config.d.ts +3 -0
  222. package/dist/vite.config.js +43 -0
  223. package/dist/vitest.config.d.ts +2 -0
  224. package/dist/vitest.config.js +25 -0
  225. package/dist/webserver.d.ts +166 -0
  226. package/dist/webserver.js +2226 -0
  227. package/dist/workloadlaw.d.ts +133 -0
  228. package/dist/workloadlaw.js +193 -0
  229. package/docker.config +13 -6
  230. package/docs/artifactavailability.md +2 -2
  231. package/docs/{containerplatforms-2.1.0.md → containerplatforms.2.1.0.md} +1 -1
  232. package/docs/{documentmap-1.8.12.md → documentmap.1.8.12.md} +1 -1
  233. package/docs/ninety.modalities.md +108 -0
  234. package/docs/planning.ninety.md +391 -0
  235. package/docs/{releasenotes-1.8.13.md → releasenotes.1.8.13.md} +2 -2
  236. package/docs/{releasenotes-1.8.14.md → releasenotes.1.8.14.md} +1 -1
  237. package/docs/{repo-synthesis-1.8.16.md → repo.synthesis.1.8.16.md} +1 -1
  238. package/docs/{todo-1.8.15.md → todo.1.8.15.md} +1 -1
  239. package/docs/{todo-1.8.16.md → todo.1.8.16.md} +5 -5
  240. package/docs/todo.md +2 -2
  241. package/docs/workloadlaw.md +104 -0
  242. package/index.ts +4 -3
  243. package/manifest.json +1 -1
  244. package/modalityregistry.ts +1493 -0
  245. package/orchestrator.ts +1 -1
  246. package/package.json +76 -37
  247. package/docs/CONVERSA.txt +0 -1523
  248. package/docs/architecture-1.8.19.png +0 -0
  249. package/docs/assets/architecture.svg +0 -45
  250. package/docs/assets/saddle-browser-trace.webp +0 -0
  251. package/docs/assets/saddle-hero-bridge.webp +0 -0
  252. package/docs/assets/saddle-mark.webp +0 -0
  253. package/docs/assets/saddle-runtime-map.webp +0 -0
  254. package/docs/assets/saddlemark.svg +0 -13
  255. package/docs/example-publicapi.ts +0 -7
  256. package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
  257. /package/docs/{architecture-1.8.19.md → architecture.1.8.19.md} +0 -0
  258. /package/docs/{architecture-1.8.19.mmd → architecture.1.8.19.mmd} +0 -0
  259. /package/docs/{artifactresearch-1.8.9.md → artifactresearch.1.8.9.md} +0 -0
  260. /package/docs/{batches-1816-1820.md → batches.1816.to.1820.md} +0 -0
  261. /package/docs/{brancharchive-2026-08-18.md → brancharchive.2026.08.18.md} +0 -0
  262. /package/docs/{containerplatforms-1.8.17.md → containerplatforms.1.8.17.md} +0 -0
  263. /package/docs/{e2ugh-engine.md → e2ugh.engine.md} +0 -0
  264. /package/docs/{flatbuildresearch-1.8.11.md → flatbuildresearch.1.8.11.md} +0 -0
  265. /package/docs/{licenseaudit-1.8.12.md → licenseaudit.1.8.12.md} +0 -0
  266. /package/docs/{mobileconversionresearch-1.8.10.md → mobileconversionresearch.1.8.10.md} +0 -0
  267. /package/docs/{native-wrappers.md → native.wrappers.md} +0 -0
  268. /package/docs/{nativeidentityresearch-1.8.11.md → nativeidentityresearch.1.8.11.md} +0 -0
  269. /package/docs/{releasenotes-1.8.12.md → releasenotes.1.8.12.md} +0 -0
  270. /package/docs/{releasenotes-1.8.15.md → releasenotes.1.8.15.md} +0 -0
  271. /package/docs/{releasenotes-1.8.16.md → releasenotes.1.8.16.md} +0 -0
  272. /package/docs/{releasenotes-1.8.17.md → releasenotes.1.8.17.md} +0 -0
  273. /package/docs/{releasenotes-1.8.18.md → releasenotes.1.8.18.md} +0 -0
  274. /package/docs/{releasenotes-1.8.19.md → releasenotes.1.8.19.md} +0 -0
  275. /package/docs/{reorganization-1.8.8.md → reorganization.1.8.8.md} +0 -0
  276. /package/docs/{reorganization-1.8.9.md → reorganization.1.8.9.md} +0 -0
  277. /package/docs/{repo-analysis-1.8.21.json → repo.analysis.1.8.21.json} +0 -0
  278. /package/docs/{repo-candidates-1.8.21.jsonl → repo.candidates.1.8.21.jsonl} +0 -0
  279. /package/docs/{repo-research-1.8.16.md → repo.research.1.8.16.md} +0 -0
  280. /package/docs/{repo-research-1.8.21.md → repo.research.1.8.21.md} +0 -0
  281. /package/docs/{repo-selected-1.8.21.json → repo.selected.1.8.21.json} +0 -0
  282. /package/docs/{repo-synthesis-1.8.21.md → repo.synthesis.1.8.21.md} +0 -0
  283. /package/docs/{research-1.8.18-isolation.md → research.1.8.18.isolation.md} +0 -0
  284. /package/docs/{research-1.8.19-virtual-browser.md → research.1.8.19.virtual.browser.md} +0 -0
  285. /package/docs/{scanningresearch-1.8.11.md → scanningresearch.1.8.11.md} +0 -0
  286. /package/docs/{securityaudit-1.8.7.md → securityaudit.1.8.7.md} +0 -0
  287. /package/docs/{securityreferences-1.8.11.md → securityreferences.1.8.11.md} +0 -0
  288. /package/docs/{securityresearch-1.8.11.md → securityresearch.1.8.11.md} +0 -0
  289. /package/docs/{signingresearch-1.8.12.md → signingresearch.1.8.12.md} +0 -0
  290. /package/docs/{tauri-glib-risk-1.8.11.md → tauri.glib.risk.1.8.11.md} +0 -0
  291. /package/docs/{todo-1.8.18.md → todo.1.8.18.md} +0 -0
  292. /package/docs/{todo-1.8.19.md → todo.1.8.19.md} +0 -0
  293. /package/docs/{toolchainresearch-1.8.9.md → toolchainresearch.1.8.9.md} +0 -0
  294. /package/docs/{web-duplicatecleanup.md → web.duplicatecleanup.md} +0 -0
  295. /package/docs/{web-ideas.md → web.ideas.md} +0 -0
  296. /package/docs/{workflowimprovements-2026-08-19.md → workflowimprovements.2026.08.19.md} +0 -0
@@ -0,0 +1,952 @@
1
+ // # edgelandes.inproc.ts — the in-process modality lanes of the ninety
2
+ // modalities wave (group b): the ram recipes, the delivery wire frames,
3
+ // the storage wire handshakes, the webcontainer seat and the local
4
+ // opt-in gate — nineteen registry modalities wired as honest pure
5
+ // typescript execution lanes that run inside the engine process itself.
6
+ // No host binary is spawned and no network socket is opened: the code
7
+ // field is the program or payload the lane interprets (a ram recipe
8
+ // manifest, a wire payload, a sql manifest, a javascript module) and the
9
+ // lane answers real computed output — mounted trees, framed bytes,
10
+ // handshake packets, captured exports. The laws every lane keeps:
11
+ // - the visitor law: everything runs server-side in the engine process,
12
+ // the visitor browser, gpu, cpu and storage are never touched (the
13
+ // local-optin lane is the only lane that may even name the visitor
14
+ // machine, and only under declared consent — and even then it answers
15
+ // a manifest, it never touches the machine);
16
+ // - the oom guard: every ram recipe reads its byte ceiling from
17
+ // inputs.budgetmb (the default 64 mb) and refuses to materialize a
18
+ // single byte over it (RAM_QUOTA_EXCEEDED), reading the declared size
19
+ // from the manifest numbers before any allocation rides;
20
+ // - the honest payload law: a lane whose manifest is not valid json or
21
+ // not the recipe's shape answers INVALID_LANE_PAYLOAD, a module that
22
+ // throws answers VM_MODULE_FAILED — no lane fakes a run;
23
+ // - the determinism law: fixed masks, fixed capability sets, fnv-1a
24
+ // hashes and stored-block zlib streams — the same payload answers the
25
+ // same bytes every run, no crypto, no randomness, no clock;
26
+ // - the artifact law: every lane answers one artifact under the mime its
27
+ // registry record declares (the wire, disk and frame bytes ride inside
28
+ // the artifact manifest as hex so the mime contract stays true).
29
+ import vm from "node:vm";
30
+ import { edgelaneerror } from "./edgelandes.ts";
31
+ /* ════════════════════════════════════════════════════════════════════ */
32
+ /* Section 2: the shared recipe surface — encoders, hashes and the manifest readers. */
33
+ /* ════════════════════════════════════════════════════════════════════ */
34
+ /** the artifact mime of the ram family (the registry record declares it). */
35
+ const rammime = "application/vnd.devthink.ram+json";
36
+ /** the artifact mime of the delivery family (the registry record declares it). */
37
+ const cdnmime = "application/vnd.devthink.cdn+json";
38
+ /** the artifact mime of the storage wire family (the registry record declares it). */
39
+ const storagemime = "application/vnd.devthink.storage+json";
40
+ /** the artifact mime of the browser family (the registry record declares it). */
41
+ const browsermime = "application/vnd.devthink.browser+json";
42
+ /** the artifact mime of the local family (the registry record declares it). */
43
+ const localmime = "application/vnd.devthink.local+json";
44
+ /** the default ram byte ceiling of the oom guard: 64 mb. */
45
+ const defaultbudgetmb = 64;
46
+ /** the bytes of one megabyte (the oom guard's unit). */
47
+ const bytespermib = 1048576;
48
+ /** the shared utf8 encoder of the lane surfaces. */
49
+ const utf8 = new TextEncoder();
50
+ /** the safe message of an unknown thrown value (no stack rides a lane answer). */
51
+ function errormessage(error) {
52
+ return error instanceof Error ? error.message : String(error ?? "unknown lane failure");
53
+ }
54
+ /** encodes one value as one stdout line (json when possible, string otherwise). */
55
+ function encodeline(value) {
56
+ try {
57
+ const encoded = JSON.stringify(value);
58
+ return encoded === undefined ? String(value) : encoded;
59
+ }
60
+ catch {
61
+ return String(value);
62
+ }
63
+ }
64
+ /** encodes bytes as lowercase hex (the manifest's byte carrying form). */
65
+ function tohex(bytes) {
66
+ let hex = "";
67
+ for (let index = 0; index < bytes.byteLength; index += 1)
68
+ hex += bytes[index].toString(16).padStart(2, "0");
69
+ return hex;
70
+ }
71
+ /** decodes one hex string into bytes: an even-length hex string only —
72
+ * anything else answers INVALID_LANE_PAYLOAD naming the manifest field. */
73
+ function fromhex(lane, value, field) {
74
+ if (typeof value !== "string" || value.length % 2 !== 0 || /[^0-9a-fA-F]/.test(value)) {
75
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires hex bytes in the manifest field ${field}`);
76
+ }
77
+ const bytes = new Uint8Array(value.length / 2);
78
+ for (let index = 0; index < bytes.byteLength; index += 1) {
79
+ bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16);
80
+ }
81
+ return bytes;
82
+ }
83
+ /** the fnv-1a 32 hash of one string, answered as 8 lowercase hex chars —
84
+ * the lane's deterministic content addressing (no crypto, no randomness). */
85
+ function fnv1a(text) {
86
+ let hash = 0x811c9dc5;
87
+ for (let index = 0; index < text.length; index += 1) {
88
+ hash ^= text.charCodeAt(index);
89
+ hash = Math.imul(hash, 0x01000193);
90
+ }
91
+ return (hash >>> 0).toString(16).padStart(8, "0");
92
+ }
93
+ /** the keyed fnv-1a 32 hash — the signer's key walks the offset basis
94
+ * before the message rides: the lane's documented deterministic signer,
95
+ * honest about never claiming aws sigv4. */
96
+ function keyedfnv1a(key, message) {
97
+ let hash = 0x811c9dc5;
98
+ for (let index = 0; index < key.length; index += 1) {
99
+ hash ^= key.charCodeAt(index);
100
+ hash = Math.imul(hash, 0x01000193);
101
+ }
102
+ for (let index = 0; index < message.length; index += 1) {
103
+ hash ^= message.charCodeAt(index);
104
+ hash = Math.imul(hash, 0x01000193);
105
+ }
106
+ return (hash >>> 0).toString(16).padStart(8, "0");
107
+ }
108
+ /** parses the code field as one json object manifest: a non-json payload
109
+ * or a non-object document answers INVALID_LANE_PAYLOAD. */
110
+ function parsemanifest(lane, code) {
111
+ let parsed;
112
+ try {
113
+ parsed = JSON.parse(code);
114
+ }
115
+ catch (error) {
116
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a json object manifest in the code field: ${errormessage(error)}`);
117
+ }
118
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
119
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a json object manifest in the code field`);
120
+ }
121
+ return parsed;
122
+ }
123
+ /** reads one non-negative safe integer manifest field. */
124
+ function manifestuint(lane, value, field) {
125
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
126
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a non-negative integer in the manifest field ${field}`);
127
+ }
128
+ return value;
129
+ }
130
+ /** reads one nonempty string manifest field. */
131
+ function manifesttext(lane, value, field) {
132
+ if (typeof value !== "string" || value.length === 0) {
133
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a nonempty string in the manifest field ${field}`);
134
+ }
135
+ return value;
136
+ }
137
+ /** reads one [offset, length] manifest pair of non-negative integers. */
138
+ function manifestwindow(lane, value, field) {
139
+ if (!Array.isArray(value) || value.length !== 2) {
140
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires an [offset, length] pair in the manifest field ${field}`);
141
+ }
142
+ return [manifestuint(lane, value[0], `${field}[0]`), manifestuint(lane, value[1], `${field}[1]`)];
143
+ }
144
+ /** reads one manifest file map (name → hex bytes), answering the decoded
145
+ * entries sorted by name (code point order — no locale walks the answer). */
146
+ function manifestfiles(lane, value, field) {
147
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
148
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a name to hex file map in the manifest field ${field}`);
149
+ }
150
+ const entries = [];
151
+ for (const [name, hex] of Object.entries(value)) {
152
+ if (name.length === 0) {
153
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} refuses an empty file name in the manifest field ${field}`);
154
+ }
155
+ entries.push([name, fromhex(lane, hex, `${field}.${name}`)]);
156
+ }
157
+ return entries.sort((left, right) => (left[0] < right[0] ? -1 : left[0] > right[0] ? 1 : 0));
158
+ }
159
+ /** reads the oom guard ceiling in bytes: inputs.budgetmb (a non-negative
160
+ * finite number of megabytes) or the 64 mb default. */
161
+ function ramceiling(inputs) {
162
+ if (typeof inputs === "object" && inputs !== null) {
163
+ const budget = inputs.budgetmb;
164
+ if (typeof budget === "number" && Number.isFinite(budget) && budget >= 0)
165
+ return budget * bytespermib;
166
+ }
167
+ return defaultbudgetmb * bytespermib;
168
+ }
169
+ /** the oom guard of every ram lane: the declared bytes the manifest asks
170
+ * the lane to materialize are refused over the ceiling before a single
171
+ * allocation rides. */
172
+ function assertramquota(lane, declaredbytes, inputs) {
173
+ const ceiling = ramceiling(inputs);
174
+ if (declaredbytes > ceiling) {
175
+ throw edgelaneerror("RAM_QUOTA_EXCEEDED", `the ram lane ${lane} refuses to materialize ${declaredbytes} bytes under its ${ceiling} byte ceiling (inputs.budgetmb)`);
176
+ }
177
+ }
178
+ /** answers one lane output whose stdout is the encodeline report and
179
+ * whose artifact is the json manifest under the lane mime. */
180
+ function lanereport(mime, report, manifest) {
181
+ return {
182
+ stdout: encodeline(report),
183
+ artifact: { mime, bytes: utf8.encode(JSON.stringify(manifest)) },
184
+ };
185
+ }
186
+ /* ════════════════════════════════════════════════════════════════════ */
187
+ /* Section 3: the ram family — the memory ladder recipes under the oom guard. */
188
+ /* ════════════════════════════════════════════════════════════════════ */
189
+ /** the rfc1950 adler32 checksum of one byte array (the stored-block
190
+ * zlib wrapper's closing word, big-endian in the stream). */
191
+ function adler32(bytes) {
192
+ let a = 1;
193
+ let b = 0;
194
+ for (let index = 0; index < bytes.byteLength; index += 1) {
195
+ a = (a + bytes[index]) % 65521;
196
+ b = (b + a) % 65521;
197
+ }
198
+ return ((b << 16) | a) >>> 0;
199
+ }
200
+ /** compresses one byte page with the lane's real stored-block zlib
201
+ * wrapper: the two byte rfc1950 header (0x78 0x01), the deflate stored
202
+ * blocks (bfinal on the last block, the len and one's-complement nlen
203
+ * little-endian, at most 65535 raw bytes per block) and the rfc1950
204
+ * adler32 checksum big-endian — a real, deterministic,
205
+ * decompressor-verifiable stream with no entropy coding. */
206
+ function storedzlib(page) {
207
+ const blockcount = Math.max(1, Math.ceil(page.byteLength / 65535));
208
+ const stream = new Uint8Array(2 + blockcount * 5 + page.byteLength + 4);
209
+ stream[0] = 0x78;
210
+ stream[1] = 0x01;
211
+ let offset = 2;
212
+ for (let index = 0; index < blockcount; index += 1) {
213
+ const start = index * 65535;
214
+ const chunk = page.subarray(start, Math.min(start + 65535, page.byteLength));
215
+ stream[offset] = index === blockcount - 1 ? 1 : 0;
216
+ offset += 1;
217
+ stream[offset] = chunk.byteLength & 0xff;
218
+ stream[offset + 1] = chunk.byteLength >> 8;
219
+ offset += 2;
220
+ const nlen = ~chunk.byteLength & 0xffff;
221
+ stream[offset] = nlen & 0xff;
222
+ stream[offset + 1] = nlen >> 8;
223
+ offset += 2;
224
+ stream.set(chunk, offset);
225
+ offset += chunk.byteLength;
226
+ }
227
+ const checksum = adler32(page);
228
+ stream[offset] = (checksum >>> 24) & 0xff;
229
+ stream[offset + 1] = (checksum >>> 16) & 0xff;
230
+ stream[offset + 2] = (checksum >>> 8) & 0xff;
231
+ stream[offset + 3] = checksum & 0xff;
232
+ return stream;
233
+ }
234
+ /** ram-tmpfs: the in-memory tmpfs lane. The code field is the mount
235
+ * manifest {"mount":"tmpfs","files":{"<name>":"<hex>"}}: the lane mounts
236
+ * the files into one in-memory tree (a map of path to bytes) under the
237
+ * oom guard and answers the mounted report — file count and total bytes
238
+ * on stdout, the serialized tree manifest as the artifact. */
239
+ async function ramtmpfslane(code, inputs, _deadline) {
240
+ const manifest = parsemanifest("ram-tmpfs", code);
241
+ if (manifest.mount !== "tmpfs") {
242
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", 'the ram-tmpfs lane requires the manifest field mount "tmpfs"');
243
+ }
244
+ const entries = manifestfiles("ram-tmpfs", manifest.files, "files");
245
+ const totalbytes = entries.reduce((sum, entry) => sum + entry[1].byteLength, 0);
246
+ assertramquota("ram-tmpfs", totalbytes, inputs);
247
+ const tree = new Map(entries);
248
+ const files = {};
249
+ for (const [name, bytes] of tree)
250
+ files[name] = tohex(bytes);
251
+ return lanereport(rammime, { mount: "tmpfs", filecount: tree.size, totalbytes, files: [...tree.keys()] }, { mount: "tmpfs", files });
252
+ }
253
+ /** ram-mmap: the zero-copy byte window lane. The code field is the
254
+ * window manifest {"window":[offset,len],"bytes":"<hex>"}: the lane
255
+ * materializes one array buffer over the bytes (the whole mapping),
256
+ * answers the zero-copy subarray window view inside it and reports the
257
+ * window bounds — the window bytes ride the artifact. */
258
+ async function rammmaplane(code, inputs, _deadline) {
259
+ const manifest = parsemanifest("ram-mmap", code);
260
+ const buffer = fromhex("ram-mmap", manifest.bytes, "bytes");
261
+ const window = manifestwindow("ram-mmap", manifest.window, "window");
262
+ assertramquota("ram-mmap", buffer.byteLength, inputs);
263
+ const [offset, length] = window;
264
+ if (length > buffer.byteLength - offset) {
265
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-mmap window [${offset}, ${length}] escapes the ${buffer.byteLength} byte mapping`);
266
+ }
267
+ const view = buffer.subarray(offset, offset + length);
268
+ return lanereport(rammime, { bufferbytes: buffer.byteLength, window: [offset, offset + length], viewbytes: view.byteLength }, { window: [offset, length], bytes: tohex(view) });
269
+ }
270
+ /** ram-overlayfs: the layer union lane. The code field is the overlay
271
+ * manifest {"lower":{...},"upper":{...}}: the lane merges the two layers
272
+ * (the upper layer wins every shared name) and answers the union — the
273
+ * declared bytes are the merged tree only, never the double count. */
274
+ async function ramoverlayfslane(code, inputs, _deadline) {
275
+ const manifest = parsemanifest("ram-overlayfs", code);
276
+ const lower = manifestfiles("ram-overlayfs", manifest.lower, "lower");
277
+ const upper = manifestfiles("ram-overlayfs", manifest.upper, "upper");
278
+ const merged = new Map(lower);
279
+ for (const [name, bytes] of upper)
280
+ merged.set(name, bytes);
281
+ let totalbytes = 0;
282
+ const files = {};
283
+ for (const [name, bytes] of merged) {
284
+ totalbytes += bytes.byteLength;
285
+ files[name] = tohex(bytes);
286
+ }
287
+ assertramquota("ram-overlayfs", totalbytes, inputs);
288
+ return lanereport(rammime, { filecount: merged.size, totalbytes, lower: lower.length, upper: upper.length, merged: [...merged.keys()] }, { files });
289
+ }
290
+ /** reads the sector writes [sectorindex, hex] of the loop ram disk: the
291
+ * sector must sit inside the disk and the payload must fit one sector. */
292
+ function manifestwrites(lane, value, sectorsize, sectors) {
293
+ if (!Array.isArray(value)) {
294
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires a writes array in the manifest`);
295
+ }
296
+ const writes = [];
297
+ for (const entry of value) {
298
+ if (!Array.isArray(entry) || entry.length !== 2) {
299
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} requires [sector, hex] write pairs`);
300
+ }
301
+ const sector = manifestuint(lane, entry[0], "writes sector");
302
+ if (sector >= sectors) {
303
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} write names the sector ${sector} outside the ${sectors} sector disk`);
304
+ }
305
+ const bytes = fromhex(lane, entry[1], "writes bytes");
306
+ if (bytes.byteLength > sectorsize) {
307
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the lane ${lane} write carries ${bytes.byteLength} bytes over the ${sectorsize} byte sector`);
308
+ }
309
+ writes.push([sector, bytes]);
310
+ }
311
+ return writes;
312
+ }
313
+ /** ram-loopram: the loop ram disk lane. The code field is the disk
314
+ * manifest {"sectorsize":n,"sectors":m,"writes":[[sector,"<hex>"],...]}:
315
+ * the lane materializes one sector-addressed zero-filled disk — the
316
+ * declared capacity (sectorsize * sectors) is what the oom guard reads
317
+ * from the manifest numbers before any allocation rides — applies the
318
+ * sector writes and answers the sector map with the disk bytes as the
319
+ * artifact. */
320
+ async function ramloopramlane(code, inputs, _deadline) {
321
+ const manifest = parsemanifest("ram-loopram", code);
322
+ const sectorsize = manifestuint("ram-loopram", manifest.sectorsize, "sectorsize");
323
+ const sectors = manifestuint("ram-loopram", manifest.sectors, "sectors");
324
+ if (sectorsize < 1) {
325
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-loopram lane requires a positive sectorsize");
326
+ }
327
+ const capacity = sectorsize * sectors;
328
+ if (!Number.isSafeInteger(capacity)) {
329
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-loopram disk exceeds the representable byte range");
330
+ }
331
+ assertramquota("ram-loopram", capacity, inputs);
332
+ const writes = manifestwrites("ram-loopram", manifest.writes ?? [], sectorsize, sectors);
333
+ const disk = new Uint8Array(capacity);
334
+ for (const [sector, bytes] of writes)
335
+ disk.set(bytes, sector * sectorsize);
336
+ const written = [...new Set(writes.map((write) => write[0]))].sort((left, right) => left - right);
337
+ return lanereport(rammime, { sectorsize, sectors, capacity, written }, { sectorsize, sectors, capacity, written, disk: tohex(disk) });
338
+ }
339
+ /** ram-gitram: the git object cache lane. The code field is the object
340
+ * manifest {"objects":[{"oid":"...","data":"<hex>"},...],"read":"oid"}:
341
+ * the lane loads the objects into one hash table keyed by oid (a
342
+ * repeated oid answers the last write) and answers the read object —
343
+ * the object bytes ride the artifact. */
344
+ async function ramgitramlane(code, inputs, _deadline) {
345
+ const manifest = parsemanifest("ram-gitram", code);
346
+ if (!Array.isArray(manifest.objects)) {
347
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-gitram lane requires an objects array in the manifest");
348
+ }
349
+ const objects = new Map();
350
+ for (const entry of manifest.objects) {
351
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
352
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-gitram lane requires {oid, data} object entries");
353
+ }
354
+ const record = entry;
355
+ const oid = manifesttext("ram-gitram", record.oid, "objects oid");
356
+ objects.set(oid, fromhex("ram-gitram", record.data, `objects ${oid} data`));
357
+ }
358
+ let totalbytes = 0;
359
+ for (const bytes of objects.values())
360
+ totalbytes += bytes.byteLength;
361
+ assertramquota("ram-gitram", totalbytes, inputs);
362
+ const read = manifesttext("ram-gitram", manifest.read, "read");
363
+ const object = objects.get(read);
364
+ if (object === undefined) {
365
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-gitram read names the unknown oid ${read}`);
366
+ }
367
+ return lanereport(rammime, { objects: objects.size, totalbytes, read, size: object.byteLength }, { oid: read, size: object.byteLength, bytes: tohex(object) });
368
+ }
369
+ /** ram-zram: the compressed page store lane. The code field is the page
370
+ * manifest {"pagesize":n,"pages":["<hex>",...]}: the lane compresses
371
+ * every page with the real stored-block zlib wrapper and answers the
372
+ * per page compression ratios — the compressed streams ride the artifact. */
373
+ async function ramzramlane(code, inputs, _deadline) {
374
+ const manifest = parsemanifest("ram-zram", code);
375
+ const pagesize = manifestuint("ram-zram", manifest.pagesize, "pagesize");
376
+ if (pagesize < 1) {
377
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-zram lane requires a positive pagesize");
378
+ }
379
+ if (!Array.isArray(manifest.pages)) {
380
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-zram lane requires a pages array in the manifest");
381
+ }
382
+ const pages = manifest.pages.map((page, index) => {
383
+ const bytes = fromhex("ram-zram", page, `pages ${index}`);
384
+ if (bytes.byteLength > pagesize) {
385
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-zram page ${index} carries ${bytes.byteLength} bytes over the ${pagesize} byte page`);
386
+ }
387
+ return bytes;
388
+ });
389
+ const rawbytes = pages.reduce((sum, page) => sum + page.byteLength, 0);
390
+ assertramquota("ram-zram", rawbytes, inputs);
391
+ const streams = pages.map((page) => storedzlib(page));
392
+ const compressedbytes = streams.reduce((sum, stream) => sum + stream.byteLength, 0);
393
+ const ratios = streams.map((stream, index) => pages[index].byteLength === 0 ? 0 : Math.round((stream.byteLength / pages[index].byteLength) * 1000) / 1000);
394
+ return lanereport(rammime, { pagesize, pages: pages.length, rawbytes, compressedbytes, ratios }, { pagesize, pages: pages.length, streams: streams.map((stream) => tohex(stream)) });
395
+ }
396
+ /** ram-zswap: the swap front pool lane. The code field is the pool
397
+ * manifest {"poolsize":n,"pages":["<hex>",...]}: the lane compresses
398
+ * every page with the same stored-block zlib wrapper and admits them
399
+ * into the LRU pool (arrival order, the oldest page evicted beyond
400
+ * poolsize) — the pool snapshot rides the artifact. */
401
+ async function ramzswaplane(code, inputs, _deadline) {
402
+ const manifest = parsemanifest("ram-zswap", code);
403
+ const poolsize = manifestuint("ram-zswap", manifest.poolsize, "poolsize");
404
+ if (!Array.isArray(manifest.pages)) {
405
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-zswap lane requires a pages array in the manifest");
406
+ }
407
+ const pages = manifest.pages.map((page, index) => fromhex("ram-zswap", page, `pages ${index}`));
408
+ const rawbytes = pages.reduce((sum, page) => sum + page.byteLength, 0);
409
+ assertramquota("ram-zswap", rawbytes, inputs);
410
+ const pool = new Map();
411
+ let evicted = 0;
412
+ pages.forEach((page, index) => {
413
+ pool.set(index, storedzlib(page));
414
+ while (pool.size > poolsize) {
415
+ const oldest = pool.keys().next();
416
+ if (oldest.done === true)
417
+ break;
418
+ pool.delete(oldest.value);
419
+ evicted += 1;
420
+ }
421
+ });
422
+ let compressedbytes = 0;
423
+ const snapshot = [];
424
+ for (const [index, stream] of pool) {
425
+ compressedbytes += stream.byteLength;
426
+ snapshot.push({ page: index, raw: pages[index].byteLength, compressed: tohex(stream) });
427
+ }
428
+ return lanereport(rammime, { poolsize, pages: pages.length, admitted: pool.size, evicted, compressedbytes }, { poolsize, pool: snapshot });
429
+ }
430
+ /** ram-swapfile: the swap extent file lane. The code field is the extent
431
+ * manifest {"extents":[[start,len,"<hex>"],...],"read":[start,len]}: the
432
+ * lane materializes the extent-addressed file (the extent table covers
433
+ * the sparse holes with zero bytes) and answers the read window — the
434
+ * extent table and the read bytes ride the artifact. */
435
+ async function ramswapfilelane(code, inputs, _deadline) {
436
+ const manifest = parsemanifest("ram-swapfile", code);
437
+ if (!Array.isArray(manifest.extents)) {
438
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-swapfile lane requires an extents array in the manifest");
439
+ }
440
+ const extents = [];
441
+ let filebytes = 0;
442
+ for (const entry of manifest.extents) {
443
+ if (!Array.isArray(entry) || entry.length !== 3) {
444
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the ram-swapfile lane requires [start, length, hex] extent triples");
445
+ }
446
+ const start = manifestuint("ram-swapfile", entry[0], "extents start");
447
+ const length = manifestuint("ram-swapfile", entry[1], "extents length");
448
+ if (!Number.isSafeInteger(start + length)) {
449
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-swapfile extent at ${start} exceeds the representable byte range`);
450
+ }
451
+ const bytes = fromhex("ram-swapfile", entry[2], "extents bytes");
452
+ if (bytes.byteLength !== length) {
453
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-swapfile extent at ${start} declares ${length} bytes but carries ${bytes.byteLength}`);
454
+ }
455
+ extents.push({ start, length, bytes });
456
+ if (start + length > filebytes)
457
+ filebytes = start + length;
458
+ }
459
+ assertramquota("ram-swapfile", filebytes, inputs);
460
+ const [readstart, readlength] = manifestwindow("ram-swapfile", manifest.read, "read");
461
+ if (readlength > filebytes - readstart) {
462
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", `the ram-swapfile read [${readstart}, ${readlength}] escapes the ${filebytes} byte file`);
463
+ }
464
+ const window = new Uint8Array(readlength);
465
+ const coveredmask = new Uint8Array(readlength);
466
+ let covered = 0;
467
+ for (const extent of extents) {
468
+ const from = Math.max(extent.start, readstart);
469
+ const to = Math.min(extent.start + extent.length, readstart + readlength);
470
+ for (let position = from; position < to; position += 1) {
471
+ if (coveredmask[position - readstart] === 0) {
472
+ coveredmask[position - readstart] = 1;
473
+ covered += 1;
474
+ }
475
+ window[position - readstart] = extent.bytes[position - extent.start];
476
+ }
477
+ }
478
+ return lanereport(rammime, {
479
+ extents: extents.length,
480
+ filebytes,
481
+ read: [readstart, readstart + readlength],
482
+ covered,
483
+ holes: readlength - covered,
484
+ }, {
485
+ read: [readstart, readlength],
486
+ bytes: tohex(window),
487
+ extents: extents.map((extent) => [extent.start, extent.length]),
488
+ });
489
+ }
490
+ /* ════════════════════════════════════════════════════════════════════ */
491
+ /* Section 4: the delivery family — the wire frame builders. */
492
+ /* ════════════════════════════════════════════════════════════════════ */
493
+ /** the deterministic rfc6455 client mask of the wss lane. */
494
+ const wssmask = Uint8Array.of(0x01, 0x02, 0x03, 0x04);
495
+ /** builds one rfc6455 client text frame around the payload: fin and the
496
+ * text opcode 1, the mask bit, the deterministic four byte mask, the
497
+ * 7/16/64 bit payload length encoding and the masked payload bytes. */
498
+ function wssframe(payload) {
499
+ const length = payload.byteLength;
500
+ const headerbytes = length < 126 ? 2 : length < 65536 ? 4 : 10;
501
+ const frame = new Uint8Array(headerbytes + 4 + length);
502
+ frame[0] = 0x81;
503
+ if (length < 126) {
504
+ frame[1] = 0x80 | length;
505
+ }
506
+ else if (length < 65536) {
507
+ frame[1] = 0x80 | 126;
508
+ frame[2] = length >> 8;
509
+ frame[3] = length & 0xff;
510
+ }
511
+ else {
512
+ frame[1] = 0x80 | 127;
513
+ new DataView(frame.buffer).setBigUint64(2, BigInt(length));
514
+ }
515
+ frame.set(wssmask, headerbytes);
516
+ const body = headerbytes + 4;
517
+ for (let index = 0; index < length; index += 1)
518
+ frame[body + index] = payload[index] ^ wssmask[index % 4];
519
+ return frame;
520
+ }
521
+ /** encodes one number as a quic variable length integer (rfc 9000
522
+ * section 16): the two bit length prefix selects the 1, 2, 4 or 8 byte
523
+ * form of the datagram framing. */
524
+ function quicvarint(value) {
525
+ if (value < 64)
526
+ return [value];
527
+ if (value < 16384)
528
+ return [0x40 | (value >> 8), value & 0xff];
529
+ if (value < 1073741824) {
530
+ return [0x80 | ((value >> 24) & 0xff), (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff];
531
+ }
532
+ const big = BigInt(value);
533
+ const bytes = [0xc0];
534
+ for (let shift = 56n; shift >= 0n; shift -= 8n)
535
+ bytes.push(Number((big >> shift) & 0xffn));
536
+ return bytes;
537
+ }
538
+ /** builds one grpc length-prefixed message: the one byte compressed flag
539
+ * 0 and the four byte big-endian payload length — exactly the bytes an
540
+ * http/2 DATA frame would carry. */
541
+ function grpcframe(payload) {
542
+ const frame = new Uint8Array(5 + payload.byteLength);
543
+ frame[0] = 0x00;
544
+ new DataView(frame.buffer).setUint32(1, payload.byteLength);
545
+ frame.set(payload, 5);
546
+ return frame;
547
+ }
548
+ /** builds the minimal one segment capnproto message around the payload:
549
+ * the little-endian 32-bit header pair (the segment count 0, then the
550
+ * segment word count) and the payload zero-padded to the 8 byte word
551
+ * boundary — the message length always answers a whole word count. */
552
+ function capnpmessage(payload) {
553
+ const words = Math.ceil(payload.byteLength / 8);
554
+ const message = new Uint8Array(8 + words * 8);
555
+ const view = new DataView(message.buffer);
556
+ view.setUint32(0, 0, true);
557
+ view.setUint32(4, words, true);
558
+ message.set(payload, 8);
559
+ return message;
560
+ }
561
+ /** delivery-cdn: the mirror manifest lane. The code field is the mirror
562
+ * manifest {"origin":"https://...","assets":["a.js",...]}: the lane is
563
+ * the mirror PLANNER — it answers the content addressed key of every
564
+ * asset (the fnv-1a 32 hash of the asset name, deterministic) and never
565
+ * fetches anything (the fetch rides the vfs seat inside the sandbox).
566
+ * The origin-pin law: a manifest without an origin answers
567
+ * INVALID_LANE_PAYLOAD. */
568
+ async function deliverycdnlane(code, _inputs, _deadline) {
569
+ const manifest = parsemanifest("delivery-cdn", code);
570
+ const origin = manifesttext("delivery-cdn", manifest.origin, "origin");
571
+ if (!Array.isArray(manifest.assets)) {
572
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the delivery-cdn lane requires an assets array in the manifest");
573
+ }
574
+ const assets = manifest.assets.map((name) => manifesttext("delivery-cdn", name, "assets entry"));
575
+ const entries = assets.map((name) => ({ name, key: `assets/${fnv1a(name)}` }));
576
+ return lanereport(cdnmime, { origin, assets: entries.length, keys: entries.map((entry) => entry.key) }, { origin, assets: entries });
577
+ }
578
+ /** delivery-wss: the websocket frame writer lane. The code field is the
579
+ * text payload: the lane builds the real rfc6455 client frame — fin and
580
+ * the text opcode, the mask bit with the deterministic mask 0x01020304,
581
+ * the 7/16/64 bit length encoding and the masked payload — and answers
582
+ * the frame bytes (the first 64 ride stdout as hex, the full frame
583
+ * rides the artifact manifest). */
584
+ async function deliverywsslane(code, _inputs, _deadline) {
585
+ const payload = utf8.encode(code);
586
+ const frame = wssframe(payload);
587
+ const hex = tohex(frame.subarray(0, Math.min(64, frame.byteLength)));
588
+ return lanereport(cdnmime, {
589
+ opcode: 1,
590
+ fin: true,
591
+ masked: true,
592
+ mask: "01020304",
593
+ length: payload.byteLength,
594
+ framebytes: frame.byteLength,
595
+ hex,
596
+ }, { opcode: 1, fin: true, masked: true, mask: "01020304", length: payload.byteLength, framehex: tohex(frame) });
597
+ }
598
+ /** delivery-webtransport: the http3 datagram lane. The code field is the
599
+ * payload: the lane frames it as one quic-style DATAGRAM frame — the
600
+ * deterministic stream id 1 as a quic varint, the datagram frame type
601
+ * 0x40 and the varint payload length — the framed bytes ride the
602
+ * artifact manifest. */
603
+ async function deliverywebtransportlane(code, _inputs, _deadline) {
604
+ const payload = utf8.encode(code);
605
+ const streamvarint = quicvarint(1);
606
+ const lengthvarint = quicvarint(payload.byteLength);
607
+ const frame = new Uint8Array(streamvarint.length + 1 + lengthvarint.length + payload.byteLength);
608
+ frame.set(streamvarint, 0);
609
+ frame[streamvarint.length] = 0x40;
610
+ frame.set(lengthvarint, streamvarint.length + 1);
611
+ frame.set(payload, streamvarint.length + 1 + lengthvarint.length);
612
+ return lanereport(cdnmime, { type: "datagram", streamid: 1, length: payload.byteLength, framebytes: frame.byteLength }, { streamid: 1, type: 64, length: payload.byteLength, framehex: tohex(frame) });
613
+ }
614
+ /** delivery-grpc: the grpc frame lane. The code field is the text
615
+ * payload: the lane frames it as one grpc length-prefixed message — the
616
+ * one byte compressed flag 0 and the four byte big-endian length. */
617
+ async function deliverygrpclane(code, _inputs, _deadline) {
618
+ const payload = utf8.encode(code);
619
+ if (payload.byteLength > 0xffffffff) {
620
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the delivery-grpc frame exceeds the four byte length ceiling");
621
+ }
622
+ const frame = grpcframe(payload);
623
+ return lanereport(cdnmime, { compressed: false, length: payload.byteLength, framebytes: frame.byteLength }, { compressedflag: 0, length: payload.byteLength, framehex: tohex(frame) });
624
+ }
625
+ /** delivery-capnproto: the capnproto segment lane. The code field is the
626
+ * payload: the lane builds the minimal one segment capnproto message —
627
+ * the little-endian 32-bit header pair (segment count 0, segment word
628
+ * count) and the payload zero-padded to the word boundary. */
629
+ async function deliverycapnprotolane(code, _inputs, _deadline) {
630
+ const payload = utf8.encode(code);
631
+ const message = capnpmessage(payload);
632
+ const words = (message.byteLength - 8) / 8;
633
+ return lanereport(cdnmime, { segments: 1, words, bytes: message.byteLength }, { segments: 1, words, messagehex: tohex(message) });
634
+ }
635
+ /* ════════════════════════════════════════════════════════════════════ */
636
+ /* Section 5: the storage wire family — the handshake speakers and the signer. */
637
+ /* ════════════════════════════════════════════════════════════════════ */
638
+ /** the mysql client capability set the lane speaks: long password, found
639
+ * rows, long flag, connect with db, protocol 41, transactions, secure
640
+ * connection and plugin auth — a fixed modern client set, deterministic. */
641
+ const mysqlclientflags = 0x0008a20f;
642
+ /** builds the mysql client handshake payload: the client flags and max
643
+ * packet (little-endian), the charset 33, the 23 byte zero filler, the
644
+ * null-terminated username, the sixteen byte auth response under its
645
+ * length byte and the null-terminated database "vault". */
646
+ function mysqlhandshakepayload(username, authresponse) {
647
+ const database = utf8.encode("vault");
648
+ const payload = new Uint8Array(32 + username.byteLength + 1 + 1 + 16 + database.byteLength + 1);
649
+ const view = new DataView(payload.buffer);
650
+ view.setUint32(0, mysqlclientflags, true);
651
+ view.setUint32(4, 0x01000000, true);
652
+ payload[8] = 33;
653
+ let offset = 32;
654
+ payload.set(username, offset);
655
+ offset += username.byteLength;
656
+ payload[offset] = 0;
657
+ offset += 1;
658
+ payload[offset] = 16;
659
+ offset += 1;
660
+ payload.set(authresponse, offset);
661
+ offset += 16;
662
+ payload.set(database, offset);
663
+ offset += database.byteLength;
664
+ payload[offset] = 0;
665
+ return payload;
666
+ }
667
+ /** the sixteen byte mysql auth response: the token's char codes (mod
668
+ * 256) truncated or zero-padded to the fixed sixteen byte slot — the
669
+ * auth-token law of the mysql lane. */
670
+ function mysqlauthresponse(token) {
671
+ const response = new Uint8Array(16);
672
+ if (typeof token === "string") {
673
+ for (let index = 0; index < Math.min(16, token.length); index += 1)
674
+ response[index] = token.charCodeAt(index) & 0xff;
675
+ }
676
+ return response;
677
+ }
678
+ /** builds the postgres startup message: the four byte big-endian length,
679
+ * the protocol 3.0 code 196608 and the null-terminated parameter list
680
+ * "user <name> database vault" closed by the empty parameter byte. */
681
+ function postgresstartup(username) {
682
+ const body = utf8.encode(`user\0${username}\0database\0vault\0\0`);
683
+ const message = new Uint8Array(8 + body.byteLength);
684
+ const view = new DataView(message.buffer);
685
+ view.setUint32(0, 8 + body.byteLength);
686
+ view.setUint32(4, 196608);
687
+ message.set(body, 8);
688
+ return message;
689
+ }
690
+ /** storage-libsql: the libsql seat lane. The code field is the query
691
+ * manifest {"sql":"select ..."}: the lane is the wire PLANNER — it
692
+ * composes the query envelope with the deterministic statement id (the
693
+ * fnv-1a 32 hash of the sql text); the daemon connection rides the host
694
+ * lane, this lane never opens a socket. */
695
+ async function storagelibsqllane(code, _inputs, _deadline) {
696
+ const manifest = parsemanifest("storage-libsql", code);
697
+ const sql = manifesttext("storage-libsql", manifest.sql, "sql");
698
+ const statementid = fnv1a(sql);
699
+ const envelope = { dialect: "libsql", sql, statementid };
700
+ return lanereport(storagemime, {
701
+ statementid,
702
+ sqlbytes: utf8.encode(sql).byteLength,
703
+ envelopebytes: utf8.encode(JSON.stringify(envelope)).byteLength,
704
+ }, envelope);
705
+ }
706
+ /** storage-mysql: the mysql wire handshake lane. The code field is the
707
+ * username (the default "saddle" when the field is empty): the lane
708
+ * composes the real mysql client handshake packet — the three byte
709
+ * little-endian payload length, the sequence byte 0 and the handshake
710
+ * payload. The auth-token law: inputs.token replaces the zero auth
711
+ * response with the token's char codes. */
712
+ async function storagemysqllane(code, inputs, _deadline) {
713
+ const username = code.length > 0 ? code : "saddle";
714
+ if (username.includes("\0")) {
715
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the storage-mysql username must not carry a nul byte");
716
+ }
717
+ const token = typeof inputs === "object" && inputs !== null ? inputs.token : undefined;
718
+ const payload = mysqlhandshakepayload(utf8.encode(username), mysqlauthresponse(token));
719
+ if (payload.byteLength > 0xffffff) {
720
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the storage-mysql handshake exceeds the three byte mysql length ceiling");
721
+ }
722
+ const packet = new Uint8Array(4 + payload.byteLength);
723
+ packet[0] = payload.byteLength & 0xff;
724
+ packet[1] = (payload.byteLength >> 8) & 0xff;
725
+ packet[2] = (payload.byteLength >> 16) & 0xff;
726
+ packet[3] = 0;
727
+ packet.set(payload, 4);
728
+ return lanereport(storagemime, { payloadbytes: payload.byteLength, packetbytes: packet.byteLength, sequence: 0, username }, { username, database: "vault", charset: 33, sequence: 0, length: payload.byteLength, packethex: tohex(packet) });
729
+ }
730
+ /** storage-postgres: the postgres wire startup lane. The code field is
731
+ * the username (the default "saddle"): the lane composes the real pg
732
+ * startup message — the big-endian length, the protocol 3.0 code and
733
+ * the null-terminated parameter list. */
734
+ async function storagepostgreslane(code, _inputs, _deadline) {
735
+ const username = code.length > 0 ? code : "saddle";
736
+ if (username.includes("\0")) {
737
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the storage-postgres username must not carry a nul byte");
738
+ }
739
+ const message = postgresstartup(username);
740
+ return lanereport(storagemime, { length: message.byteLength, protocol: 196608, username, database: "vault" }, { length: message.byteLength, protocol: 196608, username, database: "vault", messagehex: tohex(message) });
741
+ }
742
+ /** storage-s3: the s3 request signer lane. The code field is the request
743
+ * manifest {"method":"GET","bucket":"name","key":"path","payload":"text"}:
744
+ * the lane composes the canonical request string (the method line, the
745
+ * /bucket/key path, the empty query line and the host header) and signs
746
+ * it with the lane's deterministic keyed fnv-1a signer — documented as
747
+ * the lane's own signer, never a claim of aws sigv4. The auth-token law:
748
+ * inputs.secretkey mixes the signer. */
749
+ async function storages3lane(code, inputs, _deadline) {
750
+ const manifest = parsemanifest("storage-s3", code);
751
+ const method = manifesttext("storage-s3", manifest.method, "method");
752
+ const bucket = manifesttext("storage-s3", manifest.bucket, "bucket");
753
+ if (bucket.includes("/")) {
754
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the storage-s3 bucket must not carry a path separator");
755
+ }
756
+ const key = manifesttext("storage-s3", manifest.key, "key");
757
+ if (key.startsWith("/")) {
758
+ throw edgelaneerror("INVALID_LANE_PAYLOAD", "the storage-s3 key must be a relative path");
759
+ }
760
+ const payload = typeof manifest.payload === "string" ? manifest.payload : "";
761
+ const host = `${bucket}.s3.amazonaws.com`;
762
+ const path = `/${bucket}/${key}`;
763
+ const canonical = [method, path, "", "", `host:${host}`].join("\n");
764
+ const secret = typeof inputs === "object" && inputs !== null ? inputs.secretkey : undefined;
765
+ const signature = keyedfnv1a(typeof secret === "string" ? secret : "", `${canonical}\n${payload}`);
766
+ return lanereport(storagemime, { method, path, signature }, { method, bucket, key, host, canonical, signature, signer: "fnv1a-keyed" });
767
+ }
768
+ /* ════════════════════════════════════════════════════════════════════ */
769
+ /* Section 6: the browser and local family — the webcontainer seat and the consent gate. */
770
+ /* ════════════════════════════════════════════════════════════════════ */
771
+ /** rewrites the export declarations of one module into the wrapper's
772
+ * exports surface: export const/let/var/function/class NAME become the
773
+ * plain binding plus one trailing exports.NAME = NAME assignment, and
774
+ * export default EXPR becomes exports.default = EXPR. The pass is
775
+ * deliberately tiny and deterministic — anything beyond it reaches
776
+ * node:vm as written and the engine answers the honest syntax failure. */
777
+ function rewriteexports(code) {
778
+ const names = [];
779
+ const lines = code.split("\n").map((line) => {
780
+ const binding = /^(\s*)export\s+(const|let|var)\s+([A-Za-z_$][A-Za-z0-9_$]*)\b/.exec(line);
781
+ if (binding !== null) {
782
+ names.push(binding[3]);
783
+ return `${binding[1]}${binding[2]} ${binding[3]}${line.slice(binding[0].length)}`;
784
+ }
785
+ const callable = /^(\s*)export\s+(function\*?)\s+([A-Za-z_$][A-Za-z0-9_$]*)\b/.exec(line);
786
+ if (callable !== null) {
787
+ names.push(callable[3]);
788
+ return `${callable[1]}${callable[2]} ${callable[3]}${line.slice(callable[0].length)}`;
789
+ }
790
+ const klass = /^(\s*)export\s+class\s+([A-Za-z_$][A-Za-z0-9_$]*)\b/.exec(line);
791
+ if (klass !== null) {
792
+ names.push(klass[2]);
793
+ return `${klass[1]}class ${klass[2]}${line.slice(klass[0].length)}`;
794
+ }
795
+ const fallback = /^(\s*)export\s+default\s+(.+)$/.exec(line);
796
+ if (fallback !== null)
797
+ return `${fallback[1]}exports.default = ${fallback[2]}`;
798
+ return line;
799
+ });
800
+ const assignments = names.map((name) => `exports.${name} = ${name};`);
801
+ return [...lines, ...assignments].join("\n");
802
+ }
803
+ /** encodes one module export value for the exports report: the value
804
+ * rides its json form when json can carry it, the encodeline string form
805
+ * otherwise (a function answers its source text, an undefined answers
806
+ * "undefined" — the encodeline pattern, json when possible). */
807
+ function exportencoding(value) {
808
+ try {
809
+ if (JSON.stringify(value) !== undefined)
810
+ return value;
811
+ }
812
+ catch {
813
+ // the value is not json representable (a bigint, a circular
814
+ // reference): the encodeline string form answers below
815
+ }
816
+ return encodeline(value);
817
+ }
818
+ /** browser-webcontainer: the in-process webcontainer seat. The code field
819
+ * is a javascript module (like "export const answer = 42"): the lane
820
+ * rewrites the export declarations into the wrapper's exports surface
821
+ * and runs the module inside a fresh node:vm context that carries only
822
+ * the frozen console and inputs surfaces (no require, no process, no
823
+ * host globals — the server-side webcontainer law), then answers the
824
+ * exports report. A module that throws answers VM_MODULE_FAILED
825
+ * honestly — the vm error surfaces as the lane failure. */
826
+ async function browserwebcontainerlane(code, inputs, deadline) {
827
+ if (typeof vm.runInNewContext !== "function") {
828
+ throw edgelaneerror("HOST_RUNTIME_ABSENT", "the node:vm surface is absent from this engine host (the webcontainer seat never fakes a module run)");
829
+ }
830
+ const stdoutlines = [];
831
+ const stderrlines = [];
832
+ const push = (target) => (...values) => {
833
+ target.push(values.map((value) => (typeof value === "string" ? value : encodeline(value))).join(" "));
834
+ };
835
+ const consolesurface = Object.freeze({
836
+ log: push(stdoutlines),
837
+ info: push(stdoutlines),
838
+ debug: push(stdoutlines),
839
+ warn: push(stderrlines),
840
+ error: push(stderrlines),
841
+ });
842
+ const sandbox = { console: consolesurface, inputs: inputs === undefined ? null : Object.freeze(inputs) };
843
+ const script = [
844
+ '"use strict";',
845
+ "const module = Object.freeze({ exports: {} });",
846
+ "(function (module, exports) {",
847
+ rewriteexports(code),
848
+ "})(module, module.exports);",
849
+ "module.exports;",
850
+ ].join("\n");
851
+ let exportsobject;
852
+ try {
853
+ exportsobject = vm.runInNewContext(script, sandbox, { timeout: deadline, displayErrors: true });
854
+ }
855
+ catch (error) {
856
+ throw edgelaneerror("VM_MODULE_FAILED", `the webcontainer module failed to run: ${errormessage(error)}`, {
857
+ stderr: stderrlines.join("\n"),
858
+ });
859
+ }
860
+ const exportsrecord = {};
861
+ if (typeof exportsobject === "object" && exportsobject !== null) {
862
+ for (const [name, value] of Object.entries(exportsobject))
863
+ exportsrecord[name] = exportencoding(value);
864
+ }
865
+ const report = { exports: exportsrecord };
866
+ const output = {
867
+ stdout: [...stdoutlines, encodeline(report)].join("\n"),
868
+ artifact: { mime: browsermime, bytes: utf8.encode(JSON.stringify(report)) },
869
+ };
870
+ if (stderrlines.length > 0)
871
+ output.stderr = stderrlines.join("\n");
872
+ return output;
873
+ }
874
+ /** local-optin: the consent gate lane — the only lane of the plane that
875
+ * may even name the visitor machine, and only under declared consent.
876
+ * The lane refuses every run whose inputs do not declare consent exactly
877
+ * true (LOCAL_CONSENT_REQUIRED), and even under consent the lane stays
878
+ * in-process: it answers the consent manifest, the visitor machine is
879
+ * never touched. */
880
+ async function localoptinlane(_code, inputs, _deadline) {
881
+ const consent = typeof inputs === "object" && inputs !== null && inputs.consent === true;
882
+ if (!consent) {
883
+ throw edgelaneerror("LOCAL_CONSENT_REQUIRED", "the local opt-in lane refuses to run without the declared consent (inputs.consent true)");
884
+ }
885
+ const manifest = { consent: true, scope: "declared", law: "the visitor machine stays untouched" };
886
+ return lanereport(localmime, manifest, manifest);
887
+ }
888
+ /* ════════════════════════════════════════════════════════════════════ */
889
+ /* Section 7: the lane tables — the specs, the executors and the ids. */
890
+ /* ════════════════════════════════════════════════════════════════════ */
891
+ /** the in-process lane specs: one row per wired modality, the source of
892
+ * truth of the lane order — every lane executes (live), the pure recipe
893
+ * and wire lanes ride the pure typescript engine surface and the
894
+ * webcontainer seat rides node:vm. */
895
+ export const inproclanespecs = Object.freeze([
896
+ // the ram family: the memory ladder recipes
897
+ { modality: "ram-tmpfs", kind: "live", runtime: "pure-ts", present: () => true },
898
+ { modality: "ram-mmap", kind: "live", runtime: "pure-ts", present: () => true },
899
+ { modality: "ram-overlayfs", kind: "live", runtime: "pure-ts", present: () => true },
900
+ { modality: "ram-loopram", kind: "live", runtime: "pure-ts", present: () => true },
901
+ { modality: "ram-gitram", kind: "live", runtime: "pure-ts", present: () => true },
902
+ { modality: "ram-zram", kind: "live", runtime: "pure-ts", present: () => true },
903
+ { modality: "ram-zswap", kind: "live", runtime: "pure-ts", present: () => true },
904
+ { modality: "ram-swapfile", kind: "live", runtime: "pure-ts", present: () => true },
905
+ // the delivery family: the wire frame builders
906
+ { modality: "delivery-cdn", kind: "live", runtime: "pure-ts", present: () => true },
907
+ { modality: "delivery-wss", kind: "live", runtime: "pure-ts", present: () => true },
908
+ { modality: "delivery-webtransport", kind: "live", runtime: "pure-ts", present: () => true },
909
+ { modality: "delivery-grpc", kind: "live", runtime: "pure-ts", present: () => true },
910
+ { modality: "delivery-capnproto", kind: "live", runtime: "pure-ts", present: () => true },
911
+ // the storage wire family: the handshake speakers and the signer
912
+ { modality: "storage-libsql", kind: "live", runtime: "pure-ts", present: () => true },
913
+ { modality: "storage-mysql", kind: "live", runtime: "pure-ts", present: () => true },
914
+ { modality: "storage-postgres", kind: "live", runtime: "pure-ts", present: () => true },
915
+ { modality: "storage-s3", kind: "live", runtime: "pure-ts", present: () => true },
916
+ // the browser family: the server-side webcontainer seat (never the visitor's)
917
+ {
918
+ modality: "browser-webcontainer",
919
+ kind: "live",
920
+ runtime: "node:vm",
921
+ present: () => typeof vm.runInNewContext === "function",
922
+ },
923
+ // the local family: the explicit consent gate
924
+ { modality: "local-optin", kind: "live", runtime: "pure-ts", present: () => true },
925
+ ]);
926
+ /** the in-process executor table: every lane of the group b contract,
927
+ * keyed by modality id — the dispatcher refuses to boot over a lane it
928
+ * cannot wire. */
929
+ export const edgelaneexecutorsinproc = Object.freeze({
930
+ "ram-tmpfs": ramtmpfslane,
931
+ "ram-mmap": rammmaplane,
932
+ "ram-overlayfs": ramoverlayfslane,
933
+ "ram-loopram": ramloopramlane,
934
+ "ram-gitram": ramgitramlane,
935
+ "ram-zram": ramzramlane,
936
+ "ram-zswap": ramzswaplane,
937
+ "ram-swapfile": ramswapfilelane,
938
+ "delivery-cdn": deliverycdnlane,
939
+ "delivery-wss": deliverywsslane,
940
+ "delivery-webtransport": deliverywebtransportlane,
941
+ "delivery-grpc": deliverygrpclane,
942
+ "delivery-capnproto": deliverycapnprotolane,
943
+ "storage-libsql": storagelibsqllane,
944
+ "storage-mysql": storagemysqllane,
945
+ "storage-postgres": storagepostgreslane,
946
+ "storage-s3": storages3lane,
947
+ "browser-webcontainer": browserwebcontainerlane,
948
+ "local-optin": localoptinlane,
949
+ });
950
+ /** the wired lane ids in spec order — the pinned contract the parallel
951
+ * waves and the api routes read exactly. */
952
+ export const inproclaneids = Object.freeze(inproclanespecs.map((spec) => spec.modality));