space-data-module-sdk 0.8.15 → 0.8.16

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 (116) hide show
  1. package/docs/_shell/consumer-assets.html +5 -0
  2. package/docs/browser-wasmedge-isomorphic.html +261 -0
  3. package/docs/byo-wasm-quickstart.html +226 -0
  4. package/docs/byo-wasm-quickstart.md +204 -0
  5. package/docs/conformance.html +156 -0
  6. package/docs/emception-shared-memory-verdict.md +209 -0
  7. package/docs/events-abi.html +313 -0
  8. package/docs/events-abi.md +530 -0
  9. package/docs/families/analytics.html +178 -0
  10. package/docs/families/analytics.md +104 -0
  11. package/docs/families/attitude.html +157 -0
  12. package/docs/families/attitude.md +36 -0
  13. package/docs/families/behavior.html +157 -0
  14. package/docs/families/behavior.md +36 -0
  15. package/docs/families/breakup.html +157 -0
  16. package/docs/families/breakup.md +36 -0
  17. package/docs/families/conjunction.html +186 -0
  18. package/docs/families/conjunction.md +121 -0
  19. package/docs/families/data-source.html +318 -0
  20. package/docs/families/effects.html +157 -0
  21. package/docs/families/effects.md +36 -0
  22. package/docs/families/environment.html +170 -0
  23. package/docs/families/environment.md +73 -0
  24. package/docs/families/estimation.html +190 -0
  25. package/docs/families/estimation.md +128 -0
  26. package/docs/families/gnc.html +157 -0
  27. package/docs/families/gnc.md +36 -0
  28. package/docs/families/maneuver.html +209 -0
  29. package/docs/families/maneuver.md +206 -0
  30. package/docs/families/obstruction.html +191 -0
  31. package/docs/families/obstruction.md +96 -0
  32. package/docs/families/propagator.html +333 -0
  33. package/docs/families/propulsion.html +157 -0
  34. package/docs/families/propulsion.md +36 -0
  35. package/docs/families/reentry.html +157 -0
  36. package/docs/families/reentry.md +36 -0
  37. package/docs/families/rf.html +193 -0
  38. package/docs/families/rf.md +136 -0
  39. package/docs/families/scheduler.html +157 -0
  40. package/docs/families/scheduler.md +36 -0
  41. package/docs/families/sensor.html +157 -0
  42. package/docs/families/sensor.md +36 -0
  43. package/docs/families/signature.html +157 -0
  44. package/docs/families/signature.md +36 -0
  45. package/docs/flatsql-host-contract.html +176 -0
  46. package/docs/flatsql-streaming-standard.html +375 -0
  47. package/docs/gpu-module-abi.html +233 -0
  48. package/docs/harness-family-matrix.md +135 -0
  49. package/docs/index.html +216 -85
  50. package/docs/isomorphic-pthreads.html +228 -0
  51. package/docs/isomorphic-pthreads.md +84 -0
  52. package/docs/isomorphic-sdn-runtime-plan.html +274 -0
  53. package/docs/language-runtime-matrix.html +182 -0
  54. package/docs/llms.txt +86 -0
  55. package/docs/module-bundle-runtime-plan.html +146 -0
  56. package/docs/module-publication-standard.html +503 -0
  57. package/docs/node-red-default-node-parity.html +201 -0
  58. package/docs/propagator-abi.md +45 -12
  59. package/docs/protect-and-sign.html +181 -0
  60. package/docs/protect-and-sign.md +120 -0
  61. package/docs/protocol-installation.html +296 -0
  62. package/docs/publication-submission.html +158 -0
  63. package/docs/publication-submission.md +78 -0
  64. package/docs/secrets-capability.html +206 -0
  65. package/docs/styles.css +860 -167
  66. package/docs/testing-harness.html +408 -0
  67. package/docs/tri-runtime-parity-gate.html +182 -0
  68. package/docs/tri-runtime-parity.html +203 -0
  69. package/include/orbpro/orbpro_event_runner.h +951 -0
  70. package/include/orbpro/orbpro_events_abi.h +565 -0
  71. package/include/orbpro/orbpro_propagator_abi.h +17 -0
  72. package/package.json +11 -4
  73. package/schemas/orbpro/Events.fbs +501 -0
  74. package/schemas/orbpro/Propagator.fbs +72 -9
  75. package/schemas/orbpro/reference-frame-crosswalk.json +108 -0
  76. package/schemas/orbpro/reference-frame.lock.json +98 -0
  77. package/src/browser.js +13 -0
  78. package/src/generated/orbpro/events-abi.js +206 -0
  79. package/src/generated/orbpro/events-abi.ts +319 -0
  80. package/src/generated/orbpro/propagator/reference-frame.js +17 -0
  81. package/src/generated/orbpro/propagator/reference-frame.ts +91 -1
  82. package/src/generated/orbpro/propagator-abi.js +17 -0
  83. package/src/generated/orbpro/propagator-abi.ts +17 -0
  84. package/src/generated/spacedatastandards/plg/CCT.d.ts +94 -0
  85. package/src/generated/spacedatastandards/plg/CCT.d.ts.map +1 -0
  86. package/src/generated/spacedatastandards/plg/CCT.js +208 -0
  87. package/src/generated/spacedatastandards/plg/CCT.ts +281 -0
  88. package/src/generated/spacedatastandards/plg/CCTCategory.d.ts +98 -0
  89. package/src/generated/spacedatastandards/plg/CCTCategory.d.ts.map +1 -0
  90. package/src/generated/spacedatastandards/plg/CCTCategory.js +177 -0
  91. package/src/generated/spacedatastandards/plg/CCTCategory.ts +269 -0
  92. package/src/generated/spacedatastandards/plg/CCTCategoryRollup.d.ts +54 -0
  93. package/src/generated/spacedatastandards/plg/CCTCategoryRollup.d.ts.map +1 -0
  94. package/src/generated/spacedatastandards/plg/CCTCategoryRollup.js +106 -0
  95. package/src/generated/spacedatastandards/plg/CCTCategoryRollup.ts +144 -0
  96. package/src/generated/spacedatastandards/plg/PLG.d.ts +46 -2
  97. package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -1
  98. package/src/generated/spacedatastandards/plg/PLG.js +78 -5
  99. package/src/generated/spacedatastandards/plg/PLG.ts +90 -5
  100. package/src/generated/spacedatastandards/plg/capabilityClass.d.ts +181 -0
  101. package/src/generated/spacedatastandards/plg/capabilityClass.d.ts.map +1 -0
  102. package/src/generated/spacedatastandards/plg/capabilityClass.js +183 -0
  103. package/src/generated/spacedatastandards/plg/capabilityClass.ts +208 -0
  104. package/src/generated/spacedatastandards/plg/main.d.ts +4 -0
  105. package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -1
  106. package/src/generated/spacedatastandards/plg/main.js +4 -0
  107. package/src/generated/spacedatastandards/plg/main.ts +4 -0
  108. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +40 -2
  109. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -1
  110. package/src/generated/spacedatastandards/plg/pluginCategory.js +40 -2
  111. package/src/generated/spacedatastandards/plg/pluginCategory.ts +40 -2
  112. package/src/host/browserModuleHarness.js +8 -0
  113. package/src/host/wasiThreadHost.js +189 -14
  114. package/src/index.d.ts +18 -1
  115. package/src/transport/index.js +16 -0
  116. package/src/transport/records.js +1015 -3
@@ -0,0 +1,204 @@
1
+ # BYO-wasm quickstart
2
+
3
+ Bring your own WebAssembly. This is the vendor path: you compile your existing
4
+ C or C++ with your own build system, against the pinned toolchain and the
5
+ family ABI header, and hand the SDK a finished `module.wasm`. You do not need
6
+ access to any private repository, and you do not have to route your source
7
+ through the SDK's own compiler.
8
+
9
+ If you would rather have the SDK drive the compiler for you, the
10
+ `space-data-module compile` command exists and applies the same toolchain
11
+ resolution described below. The BYO lane is the supported path for a vendor
12
+ with an established build.
13
+
14
+ ## 1. The toolchain pin
15
+
16
+ This is the only sanctioned toolchain for a guest module, and it is not
17
+ negotiable:
18
+
19
+ > Compile guest modules with `clang --target=wasm32-wasip1-threads` (WASI SDK,
20
+ > pinned by the repository's CI workflows). This is the ONLY sanctioned
21
+ > toolchain for `module.wasm`. `emcc -pthread` is FORBIDDEN for module
22
+ > compilation: Emscripten's pthread model is browser-only and cannot thread
23
+ > under WasmEdge, which breaks tri-runtime isomorphism (see
24
+ > [Isomorphic pthreads](isomorphic-pthreads.html)). Modules must be EH-free.
25
+ > `flowcc` composes a runtime from prebuilt objects; it is not a WASI rebuild
26
+ > step.
27
+
28
+ The template headers carry the same one-line doctrine:
29
+ `Build: clang --target=wasm32-wasip1-threads (never emcc -pthread)`.
30
+
31
+ ### Toolchain triples
32
+
33
+ | Purpose | Value |
34
+ | --- | --- |
35
+ | Compile target | `wasm32-wasip1-threads` |
36
+ | Sysroot triple (threads libc / libc++) | `wasm32-wasip1-threads` |
37
+ | Resource-dir triple (compiler-rt builtins) | `wasm32-unknown-wasip1-threads` |
38
+ | Default drivers on `PATH` | `wasm32-wasi-clang`, `wasm32-wasi-clang++` |
39
+
40
+ The SDK resolves the sysroot by looking for `lib/wasm32-wasip1-threads/libc.a`
41
+ under, in order, `/opt/homebrew/share/wasi-sysroot`,
42
+ `/usr/local/share/wasi-sysroot`, `/opt/wasi-sdk/share/wasi-sysroot`, and
43
+ versioned Homebrew cellar paths. It resolves the resource directory by looking
44
+ for `lib/wasm32-unknown-wasip1-threads/libclang_rt.builtins.a` under
45
+ `/opt/homebrew/share/wasi-runtimes`, `/usr/local/share/wasi-runtimes`, and the
46
+ versioned cellar equivalents.
47
+
48
+ If nothing is found the SDK tells you exactly this:
49
+
50
+ > Install a wasi-sdk / wasi-libc+wasi-runtimes toolchain with the
51
+ > wasm32-wasip1-threads target (e.g. `brew install wasi-libc wasi-runtimes` or a
52
+ > wasi-sdk release), or set the `SDN_WASI_*` env overrides.
53
+
54
+ ### Environment overrides
55
+
56
+ Set these when your toolchain lives somewhere else — for example inside your own
57
+ container image:
58
+
59
+ | Variable | Overrides |
60
+ | --- | --- |
61
+ | `SDN_WASI_CLANG` | C driver binary |
62
+ | `SDN_WASI_CLANGXX` | C++ driver binary |
63
+ | `SDN_WASI_TARGET` | Compile target triple |
64
+ | `SDN_WASI_SYSROOT` | Sysroot path |
65
+ | `SDN_WASI_RESOURCE_DIR` | compiler-rt resource directory |
66
+
67
+ ## 2. The flag set
68
+
69
+ Object files are compiled with atomics, no exceptions, and threads:
70
+
71
+ ```sh
72
+ wasm32-wasi-clang++ \
73
+ --target=wasm32-wasip1-threads \
74
+ --sysroot="$WASI_SYSROOT" \
75
+ -resource-dir="$WASI_RESOURCE_DIR" \
76
+ -matomics -fno-exceptions -pthread \
77
+ -O2 -c src/my_module.cpp -o build/my_module.o
78
+ ```
79
+
80
+ The link step adds the shared-memory and imported-memory contract:
81
+
82
+ ```sh
83
+ wasm32-wasi-clang++ \
84
+ --target=wasm32-wasip1-threads \
85
+ --sysroot="$WASI_SYSROOT" \
86
+ -resource-dir="$WASI_RESOURCE_DIR" \
87
+ -pthread -matomics -mbulk-memory \
88
+ -Wl,--import-memory -Wl,--shared-memory -Wl,--max-memory=2147483648 \
89
+ -O2 build/*.o -o dist/isomorphic/module.wasm
90
+ ```
91
+
92
+ `-pthread -matomics -mbulk-memory -Wl,--import-memory -Wl,--shared-memory
93
+ -Wl,--max-memory=2147483648` is the enforced flag set. A module linked without
94
+ it will not satisfy the parity gate.
95
+
96
+ ### Multi-translation-unit builds
97
+
98
+ Nothing about the contract is single-file. Compile every translation unit with
99
+ the object-file flags above and link them in one step. A minimal `Makefile`:
100
+
101
+ ```make
102
+ WASI_SYSROOT ?= /opt/homebrew/share/wasi-sysroot
103
+ WASI_RESOURCE_DIR ?= /opt/homebrew/share/wasi-runtimes
104
+ CXX := wasm32-wasi-clang++
105
+
106
+ TARGET_FLAGS := --target=wasm32-wasip1-threads \
107
+ --sysroot=$(WASI_SYSROOT) \
108
+ -resource-dir=$(WASI_RESOURCE_DIR)
109
+ CXXFLAGS := $(TARGET_FLAGS) -matomics -fno-exceptions -pthread -O2 -Iinclude
110
+ LDFLAGS := $(TARGET_FLAGS) -pthread -matomics -mbulk-memory \
111
+ -Wl,--import-memory -Wl,--shared-memory \
112
+ -Wl,--max-memory=2147483648 -O2
113
+
114
+ SRCS := $(wildcard src/*.cpp)
115
+ OBJS := $(SRCS:src/%.cpp=build/%.o)
116
+
117
+ dist/isomorphic/module.wasm: $(OBJS)
118
+ @mkdir -p $(dir $@)
119
+ $(CXX) $(LDFLAGS) $(OBJS) -o $@
120
+
121
+ build/%.o: src/%.cpp
122
+ @mkdir -p build
123
+ $(CXX) $(CXXFLAGS) -c $< -o $@
124
+
125
+ clean:
126
+ rm -rf build dist
127
+ ```
128
+
129
+ Constraints that bite in practice:
130
+
131
+ - **EH-free.** Compile with `-fno-exceptions`. Do not throw across the ABI
132
+ boundary; return a named negative error code instead.
133
+ - **No `emcc`.** Not for one translation unit, not for a dependency, not
134
+ "temporarily for the browser build". One artifact serves every runtime.
135
+ - **No host-specific imports.** The parity gate classifies your import set
136
+ against the declared host contract and fails on a forbidden import class.
137
+
138
+ ## 3. Implement the family ABI
139
+
140
+ Pick your family from the [harness family matrix](index.html) and implement
141
+ exactly the export set that family's page names. Include the family's generated
142
+ ABI header from the SDK — do not hand-write the struct layouts, because the
143
+ headers carry `_Static_assert` size and offset locks that are the whole point of
144
+ the generated wire contract.
145
+
146
+ ```cpp
147
+ #include <orbpro/orbpro_propagator_abi.h>
148
+ ```
149
+
150
+ The SDK ships the headers under `include/` and exports them through the package
151
+ (`space-data-module-sdk/include/*`), so a vendor consuming the SDK from npm gets
152
+ the same bytes the generator produced.
153
+
154
+ ## 4. Declare the manifest
155
+
156
+ A module carries an embedded manifest declaring its plugin id, family, invoke
157
+ surface, runtime targets, methods, ports, and the standards record types it
158
+ consumes and emits. See the
159
+ [module publication standard](module-publication-standard.html) for the record
160
+ layout and [conformance](conformance.html) for what is checked.
161
+
162
+ > **Status: still being built.** There is no tool today that stamps a manifest
163
+ > onto a binary produced by a foreign toolchain. Manifest normalization and
164
+ > codecs exist for modules authored inside the SDK's own build path, but a
165
+ > `manifest inject` verb for a BYO binary does not exist yet — it is Sprint 1 of
166
+ > the third-party integration program. Until it lands, a BYO vendor supplies the
167
+ > manifest JSON alongside the artifact and the manifest is attached for them.
168
+
169
+ ## 5. Prove it, then ship it
170
+
171
+ ```sh
172
+ # ABI conformance for your family
173
+ space-data-module conformance propagator --artifact ./dist/isomorphic/module.wasm
174
+
175
+ # tri-runtime parity: browser + WasmEdge + Docker WasmEdge, byte-identical
176
+ space-data-module parity \
177
+ --wasm ./dist/isomorphic/module.wasm \
178
+ --fixture ./fixtures/parity/basic.json \
179
+ --lanes browser,wasmedge,docker-wasmedge
180
+ ```
181
+
182
+ Then continue with [Conformance kit](conformance.html),
183
+ [Protect and sign](protect-and-sign.html), and
184
+ [Publication and listing](publication-submission.html).
185
+
186
+ ## Honest gaps in this lane
187
+
188
+ These are checked statements about the SDK today, not future tense for its own
189
+ sake:
190
+
191
+ - The toolchain flags and triples above are real and enforced, but they are
192
+ applied by the SDK's internal compiler resolver. The `Makefile` on this page
193
+ is a documented recipe assembled from those enforced values; the repository
194
+ does not yet ship a `Makefile`, `CMakeLists.txt` or `build.sh` template for a
195
+ hand-rolled multi-TU build.
196
+ - `conformance --self-test` currently accepts only the `propagator` family. Any
197
+ other family argument raises an unknown-family error.
198
+ - Manifest injection for foreign-compiled binaries does not exist yet.
199
+ - There is no self-serve listing submission command yet. See
200
+ [Publication and listing](publication-submission.html).
201
+
202
+ An escorted pilot is possible today: a vendor delivers a BYO artifact and the
203
+ gates are run and the module listed by hand. The program above is what makes
204
+ that self-serve.
@@ -0,0 +1,156 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="description" content="Status: v1 — W1.4 of graph/tasks/official-harness-shapes-program.md," />
7
+ <title>Conformance kit — Space Data Module SDK</title>
8
+ <link rel="stylesheet" href="./styles.css" />
9
+ <!-- SDN_CONSUMER_ASSETS_START -->
10
+ <link rel="stylesheet" href="https://static.spacedatanetwork.org/assets/hd-wallet-ui/2.0.28/sdn-wallet-public-client.c3f68d1cfd88478f10d836a5e829d1dfc6a10157972cf0f7d4d319d0636f2cc4.css" integrity="sha384-fICuhN4I9xqOK1F5vGGzl26opuO+xQIvTZXMSV76lWTBiQ6AfzztMGLLDw8yRT8i" crossorigin="anonymous">
11
+ <script defer src="https://static.spacedatanetwork.org/assets/hd-wallet-ui/2.0.28/sdn-wallet-public-client.f611e7e151a3b5c38384272f8894a4c6634f0a29bf925b0e02e0e27f8db0bfff.js" integrity="sha384-R+QqsKoWJIS7iWrtPmgJ49DVnb1hSGjZokupbLInJd1PLp8RwQhtF/hnaerc33ci" crossorigin="anonymous" data-sdn-wallet-public-client="v1"></script>
12
+ <script defer src="https://static.spacedatanetwork.org/assets/sdn-stack-nav/1.0.0/sdn-stack-nav.52fde607eee38ffa116188201f50258ed50bd18c9f06c1af9678f763147a8fe5.js" integrity="sha384-dgeojhJ8vTszHXIbv7O7nZcEzqD10oUYYJjBmPrV7+kLQEUlXLQD4ek5Q7HOFiO5" crossorigin="anonymous" data-nav-style-url="https://static.spacedatanetwork.org/assets/sdn-stack-nav/1.0.0/sdn-stack-nav.36a36359ce18322185e9ff179f88175bab67d5ad84a14d9c08a54f2ff27267e7.css" data-nav-style-integrity="sha384-c4M8Fg+kYaeOYYtJVr7jJsde24IhSWkWaRyAOHEZU9jozhRck089aw+mnHwxymds" data-wallet-client-url="https://static.spacedatanetwork.org/assets/hd-wallet-ui/2.0.28/sdn-wallet-public-client.f611e7e151a3b5c38384272f8894a4c6634f0a29bf925b0e02e0e27f8db0bfff.js" data-wallet-client-integrity="sha384-R+QqsKoWJIS7iWrtPmgJ49DVnb1hSGjZokupbLInJd1PLp8RwQhtF/hnaerc33ci" data-wallet-style-url="https://static.spacedatanetwork.org/assets/hd-wallet-ui/2.0.28/sdn-wallet-public-client.c3f68d1cfd88478f10d836a5e829d1dfc6a10157972cf0f7d4d319d0636f2cc4.css" data-wallet-style-integrity="sha384-fICuhN4I9xqOK1F5vGGzl26opuO+xQIvTZXMSV76lWTBiQ6AfzztMGLLDw8yRT8i" data-wallet-client-id="sdn-module-sdk-pages-v1" data-wallet-callback-uri="https://digitalarsenal.github.io/space-data-module-sdk/wallet-callback.html" data-wallet-registry-sha256="e1ce6fe903c9700484a8a87d96581c8cad97063dabf63030b4518a31a3bdaa93"></script>
13
+ <!-- SDN_CONSUMER_ASSETS_END -->
14
+ </head>
15
+ <body>
16
+ <a class="skip-link" href="#main">Skip to content</a>
17
+ <sdn-stack-nav active="module-sdk"></sdn-stack-nav>
18
+ <header class="site-header">
19
+ <a class="site-brand" href="./">Space Data Module SDK</a>
20
+ <nav class="header-links" aria-label="Site">
21
+ <a href="./byo-wasm-quickstart.html">Quickstart</a>
22
+ <a href="./conformance.html">Conformance</a>
23
+ <a href="https://github.com/DigitalArsenal/space-data-module-sdk">GitHub</a>
24
+ <a class="stack-button" href="#stack">Stack</a>
25
+ </nav>
26
+ </header>
27
+ <div class="shell">
28
+ <nav class="sidebar" id="sidebar" aria-label="Documentation">
29
+ <h2>Start here</h2><ul>
30
+ <li><a href="./index.html"><span>Harness family matrix</span></a></li>
31
+ <li><a href="./byo-wasm-quickstart.html"><span>BYO-wasm quickstart</span></a></li>
32
+ <li><a href="./conformance.html" aria-current="page"><span>Conformance kit</span></a></li>
33
+ <li><a href="./protect-and-sign.html"><span>Protect and sign</span></a></li>
34
+ <li><a href="./publication-submission.html"><span>Publication and listing</span></a></li>
35
+ </ul>
36
+ <h2>Dynamics</h2><ul>
37
+ <li><a href="./families/propagator.html"><span>Propagator</span><span class="tag tag-shipped">shipped</span></a></li>
38
+ <li><a href="./families/maneuver.html"><span>Maneuver</span><span class="tag tag-experimental">experimental</span></a></li>
39
+ <li><a href="./families/propulsion.html"><span>Propulsion</span><span class="tag tag-planned">planned</span></a></li>
40
+ <li><a href="./families/attitude.html"><span>Attitude</span><span class="tag tag-planned">planned</span></a></li>
41
+ <li><a href="./families/gnc.html"><span>GNC</span><span class="tag tag-planned">planned</span></a></li>
42
+ </ul>
43
+ <h2>Environment and interaction</h2><ul>
44
+ <li><a href="./families/rf.html"><span>RF</span><span class="tag tag-designed">designed</span></a></li>
45
+ <li><a href="./families/sensor.html"><span>Sensor</span><span class="tag tag-planned">planned</span></a></li>
46
+ <li><a href="./families/signature.html"><span>Signature</span><span class="tag tag-planned">planned</span></a></li>
47
+ <li><a href="./families/environment.html"><span>Environment</span><span class="tag tag-planned">planned</span></a></li>
48
+ <li><a href="./families/obstruction.html"><span>Obstruction</span><span class="tag tag-designed">designed</span></a></li>
49
+ </ul>
50
+ <h2>Event physics</h2><ul>
51
+ <li><a href="./families/breakup.html"><span>Breakup</span><span class="tag tag-planned">planned</span></a></li>
52
+ <li><a href="./families/reentry.html"><span>Reentry</span><span class="tag tag-planned">planned</span></a></li>
53
+ <li><a href="./families/conjunction.html"><span>Conjunction</span><span class="tag tag-designed">designed</span></a></li>
54
+ <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
+ </ul>
56
+ <h2>Estimation, data and logic</h2><ul>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
58
+ <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
+ <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
+ <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
61
+ <li><a href="./families/behavior.html"><span>Behavior</span><span class="tag tag-planned">planned</span></a></li>
62
+ </ul>
63
+ <h2>Runtime contract</h2><ul>
64
+ <li><a href="./events-abi.html"><span>Event locator ABI</span></a></li>
65
+ <li><a href="./module-publication-standard.html"><span>Module publication standard</span></a></li>
66
+ <li><a href="./browser-wasmedge-isomorphic.html"><span>Browser / WasmEdge isomorphism</span></a></li>
67
+ <li><a href="./isomorphic-pthreads.html"><span>Isomorphic pthreads</span></a></li>
68
+ <li><a href="./tri-runtime-parity.html"><span>Tri-runtime parity</span></a></li>
69
+ <li><a href="./tri-runtime-parity-gate.html"><span>Tri-runtime parity gate</span></a></li>
70
+ <li><a href="./testing-harness.html"><span>Testing harness</span></a></li>
71
+ <li><a href="./language-runtime-matrix.html"><span>Language and runtime matrix</span></a></li>
72
+ </ul>
73
+ <h2>Host surfaces</h2><ul>
74
+ <li><a href="./flatsql-host-contract.html"><span>FlatSQL host contract</span></a></li>
75
+ <li><a href="./flatsql-streaming-standard.html"><span>FlatSQL streaming standard</span></a></li>
76
+ <li><a href="./secrets-capability.html"><span>Credential lanes</span></a></li>
77
+ <li><a href="./protocol-installation.html"><span>Protocol installation</span></a></li>
78
+ <li><a href="./gpu-module-abi.html"><span>GPU module ABI</span></a></li>
79
+ <li><a href="./module-bundle-runtime-plan.html"><span>Module bundle runtime</span></a></li>
80
+ <li><a href="./isomorphic-sdn-runtime-plan.html"><span>Isomorphic SDN runtime</span></a></li>
81
+ <li><a href="./node-red-default-node-parity.html"><span>Node-RED node parity</span></a></li>
82
+ </ul>
83
+ </nav>
84
+ <main class="doc" id="main">
85
+ <h1>Conformance kit</h1>
86
+ <p><strong>Status:</strong> v1 — W1.4 of <code>graph/tasks/official-harness-shapes-program.md</code>, implementing <code>graph/findings/official-harness-shapes.md</code> §5. Family kits: <code>propagator</code> (SHIP 1). Maneuver is Wave 2 (EXPERIMENTAL, fix-then-freeze); OD is deferred by ruling. <strong>A family with no kit can never be <code>CORE</code>.</strong></p>
87
+ <p>WASM artifacts ONLY (owner ruling 2026-08-10: &quot;No JS propagator!!!! WASM ONLY&quot;). The runner instantiates a compiled <code>dist/isomorphic/module.wasm</code> and drives the family's ABI directly; there is no path that certifies a JavaScript object, because JS registries are internal engine plumbing, never a public contract.</p>
88
+ <h2 id="commands"><a class="anchor" href="#commands" aria-hidden="true">#</a>Commands</h2>
89
+ <div class="codeblock"><pre><code>space-data-module conformance propagator --artifact ./dist/isomorphic/module.wasm
90
+ space-data-module conformance propagator --artifact ./dist/isomorphic/module.wasm \
91
+ --vectors ./vectors/vectors.json --json
92
+ space-data-module conformance propagator --self-test # must exit 0 BY failing</code></pre></div>
93
+ <ul>
94
+ <li><code>--artifact</code> — the compiled module. Its sha256 goes in the report; a conformance claim binds to CONTENT, not to a name.</li>
95
+ <li><code>--vectors</code> — the module's corpus (<code>vectors.json</code> + <code>PROVENANCE.md</code>, the format proven by the reference module's <code>vectors/</code> suite). Default: the runner walks up from the artifact to the package root and takes <code>vectors/vectors.json</code>. <strong>The corpus is the module's own</strong>: Tier B anchors are model-specific, so a two-body corpus is never forced onto an SGP4 module, and a missing corpus is a NAMED GAP, never a silent pass.</li>
96
+ <li><code>--leak-warmup / --leak-cycles / --leak-entities</code> — lifecycle-leak window overrides (defaults 20 / 200 / 256, the reference module's proven numbers).</li>
97
+ <li>Exit codes: <code>PASS</code> and <code>PASS-WITH-GAPS</code> exit 0 (gaps are listed in the report); <code>FAIL</code> exits 1 with the offending check and case named.</li>
98
+ </ul>
99
+ <p>Library surface: <code>space-data-module-sdk/conformance</code> exports <code>runConformance</code>, <code>runPropagatorSuite</code>, <code>runPropagatorSelfTest</code>, <code>computeVerdict</code>, the ABI driver and the error-code table.</p>
100
+ <h2 id="what-is-checked"><a class="anchor" href="#what-is-checked" aria-hidden="true">#</a>What is checked</h2>
101
+ <div class="table-wrap"><table><thead><tr><th>Tier</th><th>Check</th><th>Source of authority</th></tr></thead><tbody><tr><td>0</td><td>real instantiation + required export set</td><td><a href="./families/propagator.html">propagator-abi.md</a> §The export set</td></tr><tr><td>0</td><td>cross-runtime byte-identity</td><td><strong>GAP here by design</strong> — the parity gate (<code>space-data-module parity-gate</code>) is the Tier 0 authority; this runner never re-certifies half of it</td></tr><tr><td>B</td><td>corpus anchors reproduced within band</td><td>the module's <code>vectors.json</code> (tolerance policy `abs + rel *</td><td>expected</td><td>`); NaN is its own failure class</td></tr><tr><td>C</td><td>vis-viva closure, period closure</td><td>corpus-declared invariants (<code>conformance.mu</code> from the corpus; ECEF un-rotation when the module declares frame 3) — run only where the corpus declares them applicable to the model</td></tr><tr><td>C</td><td>determinism as BYTES, surviving destroy/re-ingest</td><td>ABI §Parity envelope</td></tr><tr><td>C</td><td>frame/flags/reserved declared, corpus-consistent</td><td>ABI §Frames — a frame declaration that contradicts the module's own corpus is the silently-wrong-numbers defect</td></tr><tr><td>C</td><td>batch and single agree exactly</td><td>ABI §Threading — the batch path is the same physics</td></tr><tr><td>C</td><td>typed refusals (NOT_INITIALIZED / BAD_ENTITY_INDEX / unphysical ingest)</td><td>ABI §Error codes — the degradation ladder needs distinguishable codes</td></tr><tr><td>C</td><td>create RETURNS its handle</td><td>ABI §Identity — &quot;the entity I just created is count−1&quot; is the race the harness exists to kill (finding §4.4)</td></tr><tr><td>4</td><td>lifecycle leak: zero page growth after warm-up</td><td>ABI §Lifetime</td></tr><tr><td>4</td><td>destroy idempotent, refuses typed, comes back cleanly</td><td>ABI §Lifetime</td></tr><tr><td>4</td><td>leak-metric negative control</td><td>a gate never observed to fail is indistinguishable from one that cannot fail</td></tr></tbody></table></div>
102
+ <h2 id="the-self-test"><a class="anchor" href="#the-self-test" aria-hidden="true">#</a>The self-test</h2>
103
+ <p><code>--self-test</code> runs the SAME suite against mock propagators, each carrying ONE planted defect drawn from a real defect class the finding documented live:</p>
104
+ <div class="table-wrap"><table><thead><tr><th>Planted defect</th><th>Real-world citation</th><th>Must be caught by</th></tr></thead><tbody><tr><td><code>units-km</code> (1000× error)</td><td>the <code>orbpro_propagator.h</code> km/meters contradiction (finding §4.1)</td><td><code>tierB/anchors</code></td></tr><tr><td><code>leaky-destroy</code></td><td><code>destroySource(){}</code> in both shipped propagators (§4.5)</td><td><code>tier4/lifecycle-leak</code></td></tr><tr><td><code>confident-nonsense</code> (accepts e ≥ 1)</td><td>the underground phasing orbit (§5)</td><td><code>tierC/typed-refusals</code></td></tr><tr><td><code>count-fallback</code> (returns success, not the handle)</td><td>three families deriving count−1 (§4.4)</td><td><code>tierC/create-returns-handle</code></td></tr><tr><td><code>frame-lies</code> (declares TEME, writes ECEF)</td><td>the Δv frame never pinned (§4.3)</td><td><code>tierC/frame-flags-reserved-declared</code></td></tr><tr><td><code>batch-divergence</code></td><td>batch path not the same physics</td><td><code>tierC/batch-single-agreement</code></td></tr><tr><td><code>nondeterministic</code></td><td>byte-determinism is the parity envelope's floor</td><td><code>tierC/determinism-byte-identity</code></td></tr><tr><td><code>missing-exports</code></td><td>destroy was optional once; it is not now</td><td><code>tier0/instantiation-and-exports</code></td></tr></tbody></table></div>
105
+ <p>The self-test exits 0 only when the conformant baseline mock is clean AND every planted defect is caught by the check that owns it. It needs no toolchain, no artifact and no network — <code>npm run conformance:self-test</code>.</p>
106
+ <h2 id="receipt-trust-wave-4-not-yet-wired"><a class="anchor" href="#receipt-trust-wave-4-not-yet-wired" aria-hidden="true">#</a>Receipt &amp; trust (Wave 4, not yet wired)</h2>
107
+ <p>The conformance receipt travels as a bundle <code>ATTESTATION</code> entry (publisher-signed under bundle scope); the graduated listing requirement (receipt REQUIRED for <code>CORE</code>+<code>ANONYMOUS</code>, badge for <code>RECOMMENDED</code>) and the <code>SDN-CONFORMANCE-RECEIPT-V1</code> third-party attestor domain are W4.1/W4.2 of the program — see the finding §5 &quot;Receipt &amp; trust&quot;.</p>
108
+ <h2 id="reference-implementation"><a class="anchor" href="#reference-implementation" aria-hidden="true">#</a>Reference implementation</h2>
109
+ <p><code>space-data-network-modules propagator/keplerian-reference</code> is the exemplar the kit was generalized from: its <code>tests/</code> are the original expression of these checks, its <code>vectors/</code> suite is the corpus format, and <code>tests/sdk-conformance-runner.test.mjs</code> proves the runner reaches the same verdict on the same artifact — including the corrupted-corpus negative control.</p>
110
+
111
+ <p class="doc-footer">
112
+ Source of truth for this page:
113
+ <code>docs/conformance.md</code>. Regenerate with
114
+ <code>npm run build:docs</code>.
115
+ </p>
116
+ </main>
117
+ <nav class="rail" aria-label="On this page"><h2>On this page</h2><ul><li><a class="depth-2" href="#commands">Commands</a></li>
118
+ <li><a class="depth-2" href="#what-is-checked">What is checked</a></li>
119
+ <li><a class="depth-2" href="#the-self-test">The self-test</a></li>
120
+ <li><a class="depth-2" href="#receipt-trust-wave-4-not-yet-wired">Receipt &amp; trust (Wave 4, not yet wired)</a></li>
121
+ <li><a class="depth-2" href="#reference-implementation">Reference implementation</a></li></ul></nav>
122
+ </div>
123
+ <section id="stack" class="section" aria-labelledby="stack-title">
124
+ <div class="section-head">
125
+ <p class="eyebrow">SDN Stack</p>
126
+ <h2 id="stack-title">Connected sites</h2>
127
+ </div>
128
+ <div class="link-list">
129
+ <a href="https://spacedatastandards.org/">
130
+ <span>Standards</span>
131
+ <small>Canonical schemas, record contracts, and generated bindings.</small>
132
+ </a>
133
+ <a href="https://digitalarsenal.github.io/flatbuffers/">
134
+ <span>FlatBuffers</span>
135
+ <small>Binary encoding, schema tooling, and runtime documentation.</small>
136
+ </a>
137
+ <a href="https://digitalarsenal.github.io/flatsql/">
138
+ <span>FlatSQL</span>
139
+ <small>SQL-style queries over FlatBuffer-backed datasets and streams.</small>
140
+ </a>
141
+ <a href="https://spacedatanetwork.org/">
142
+ <span>SDN</span>
143
+ <small>Distributed publication, discovery, delivery, and marketplace infrastructure.</small>
144
+ </a>
145
+ <a href="https://digitalarsenal.github.io/space-data-module-sdk/" class="active">
146
+ <span>Module SDK</span>
147
+ <small>WASM module packaging, validation, and host compatibility tooling.</small>
148
+ </a>
149
+ </div>
150
+ </section>
151
+ <footer class="site-footer">
152
+ Space Data Module SDK — Apache-2.0. Every ABI page renders a Markdown
153
+ source in <code>docs/</code>; edit the Markdown, never the HTML.
154
+ </footer>
155
+ </body>
156
+ </html>
@@ -0,0 +1,209 @@
1
+ # Can emception build the shared-memory wasm-engine? — verdict
2
+
3
+ **Verdict: NO.** Recorded 2026-08-30 by `obc-05-emception-lane`
4
+ (`graph/tasks/obc-05-emception-lane.md`, OrbPro Build Cutter program). Measured
5
+ in headless Chromium against the real target's real flags. Three independent
6
+ blockers, any one of them fatal; the third is the one that settles it.
7
+
8
+ The user-module lane — Phase B — **works**, and ships. See §4.
9
+
10
+ Harness, fixtures and the raw record:
11
+ `OrbPro/packages/orbpro-integration/build-cutter/emception/`
12
+ (`spike/run.mjs` produces `results/emception-lane.json`).
13
+
14
+ ---
15
+
16
+ ## 1. The question
17
+
18
+ `packages/wasm-engine/build-sdn.sh` builds two Emscripten targets from
19
+ `packages/wasm-engine/src/cpp/CMakeLists.txt`. One of them,
20
+ **`wasm_engine_sdn_browser_shared`**, is the browser presentation artifact:
21
+ `-s IMPORTED_MEMORY=1 -s SHARED_MEMORY=1 -matomics -mbulk-memory` on top of
22
+ `-s STANDALONE_WASM=1`, with a 4 GiB ceiling.
23
+
24
+ Could the Build Cutter recompile *that* target in a browser tab, with the
25
+ runtime lock (`allowedDomains`, `compiledAtMs`, `ttlDays`) as compiled-in
26
+ constants, so a cut's domain lock lives inside the WASM instead of only in the
27
+ JS mirror?
28
+
29
+ ## 2. What was measured
30
+
31
+ | | |
32
+ | --- | --- |
33
+ | Target | `wasm_engine_sdn_browser_shared` |
34
+ | Compiler under test | `sdn-emception@1.0.0`, vendored same-origin |
35
+ | Its Emscripten | **3.1.24** (`/emscripten/emscripten-version.txt`, read at run time) |
36
+ | The engine's Emscripten | **6.0.1** (`build-sdn.sh`, `./emsdk install 6.0.1`) |
37
+ | Page | headless Chromium, own ephemeral port, `COOP: same-origin` + `COEP: require-corp`, `crossOriginIsolated === true` |
38
+ | Probe source | `fixtures/engine-lock-probe.cpp` — the lock's three fields as `constexpr`, the JS mirror's predicate, `std::atomic` and `std::thread` |
39
+ | Flags | transcribed from `src/cpp/CMakeLists.txt`, not invented — `compileArgs.mjs` |
40
+
41
+ ## 3. The three blockers, verbatim
42
+
43
+ ### 3.1 The target is a CMake target, and there is no CMake
44
+
45
+ `build-sdn.sh` runs `emcmake cmake -S src/cpp -B build-wasm` and then
46
+ `cmake --build --target wasm_engine_sdn_browser_shared`. Emception ships
47
+ `/emscripten/emcmake.py` but no `cmake`, no `make`, no `ninja` and no `git`
48
+ (measured; `git` matters because the target's `CMakeLists.txt` pulls GLM in
49
+ through `FetchContent_Declare(... GIT_REPOSITORY ...)`, and the tab has no
50
+ network beyond its own origin).
51
+
52
+ ```
53
+ $ emcmake cmake -S /working/build-cutter/src-cpp -B /working/build-cutter/build-wasm -DCMAKE_BUILD_TYPE=Release
54
+ configure: cmake -S /working/build-cutter/src-cpp -B /working/build-cutter/build-wasm -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node;--experimental-wasm-threads
55
+ Not found: cmake
56
+ emcmake: error: 'cmake -S /working/build-cutter/src-cpp -B /working/build-cutter/build-wasm -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node;--experimental-wasm-threads' failed (returned 1)
57
+ ```
58
+
59
+ ### 3.2 The engine's own flags do not exist in this Emscripten
60
+
61
+ Driving `em++` directly, bypassing CMake, with the target's exact flags:
62
+
63
+ ```
64
+ $ em++ -c engine_lock_probe.cpp -std=c++17 -O3 -flto -ffast-math -fno-finite-math-only \
65
+ -DNDEBUG -msimd128 -fwasm-exceptions -sWASM_LEGACY_EXCEPTIONS=0 -matomics -mbulk-memory -o engine_lock_probe.o
66
+ em++: error: Attempt to set a non-existent setting: 'WASM_LEGACY_EXCEPTIONS'
67
+ - did you mean one of ABORT_ON_WASM_EXCEPTIONS, LEGACY_SETTINGS?
68
+ - perhaps a typo in emcc's -sX=Y notation?
69
+ - (see src/settings.js for valid values)
70
+ ```
71
+
72
+ The link step fails identically. Removing `-fwasm-exceptions` and
73
+ `-sWASM_LEGACY_EXCEPTIONS=0` and asking again produces the next one:
74
+
75
+ ```
76
+ em++: error: Attempt to set a non-existent setting: 'STACK_SIZE'
77
+ - did you mean one of ASYNCIFY_STACK_SIZE?
78
+ ```
79
+
80
+ This is the 3.1.24-versus-6.0.1 gap, one setting at a time. The spike drops
81
+ each named setting and re-asks (`engine-shared-link-relaxed-<n>`, advisory
82
+ probes) rather than reporting only the first — the point is the size of the
83
+ gap, not its first symptom.
84
+
85
+ ### 3.3 This Emscripten refuses the combination outright
86
+
87
+ With every version-gated setting removed, the shared-memory link finally runs —
88
+ and this is the answer:
89
+
90
+ ```
91
+ $ em++ engine_lock_probe_relaxed.o -O3 -flto -s EXPORTED_FUNCTIONS=[...] -s MODULARIZE=1 \
92
+ -s EXPORT_NAME='WasmEngineSharedModule' -s EXPORT_ES6=1 -s STANDALONE_WASM=1 \
93
+ -s IMPORTED_MEMORY=1 -s SHARED_MEMORY=1 -matomics -mbulk-memory ... -o engine_shared_probe_relaxed.js
94
+
95
+ error: library_pthread_stub.js:11: #error "STANDALONE_WASM does not support shared memories yet"
96
+
97
+ warning: undefined symbol: main/__main_argc_argv (referenced by top-level compiled C/C++ code)
98
+ warning: To build in STANDALONE_WASM mode without a main(), use emcc --no-entry
99
+ ```
100
+
101
+ `STANDALONE_WASM=1` **and** `SHARED_MEMORY=1` is exactly what
102
+ `wasm_engine_sdn_browser_shared` is, and Emscripten 3.1.24 refuses that pair
103
+ from its own sources. Not a missing flag, not a missing tool — a refused
104
+ combination. (The object file compiles clean: `-matomics -mbulk-memory
105
+ -msimd128` produce a 12,196-byte object. Atomics are not the problem.)
106
+
107
+ ## 4. What this means, and what ships anyway
108
+
109
+ **The lock stays in the JS mirror.** `obc-01`'s
110
+ `isBundledWasmEngineKeyRuntimeAuthorized` (`packages/wasm-engine/index.mjs`)
111
+ remains the shipped enforcement, with its hard `E79` refusal. `obc-04`'s engine
112
+ slot takes the prebuilt engine blob, as it does today; the emception lane does
113
+ not fill it.
114
+
115
+ **Phase B ships.** A user's own C/C++ module compiles in the same worker, in
116
+ the single-thread Emscripten profile, and is labelled development-grade:
117
+
118
+ - fixture compiled and linked in **2.4–3.0 s**, producing a **597-byte** wasm;
119
+ - instantiated and called **on the page**: `build_cutter_probe(0)` returns
120
+ `307385611`, `build_cutter_tag_length()` returns `31`;
121
+ - stamped with `runtimeTargets: ["browser"]` in the `sds.manifest` `$PLG`
122
+ section, so `assertArtifactRuntimeTarget({leg: "wasmedge"})` throws
123
+ `RuntimeTargetError` — asserted against the real gate, and asserted again
124
+ against the UNSTAMPED artifact, which is admitted everywhere and proves the
125
+ stamp is the whole refusal;
126
+ - refused by `assertSequentialArtifact(..., {target: "wasm32-emscripten"})`:
127
+ *"the sequential model is a concurrency exemption, NOT a toolchain
128
+ exemption."*
129
+
130
+ This is the Janus boundary of 2026-08-14 holding: nothing a browser tab
131
+ produces enters the isomorphic lane, and the refusal is mechanical.
132
+
133
+ ## 5. A second finding: the shipped `.pack.br` files are not the packs
134
+
135
+ Not the question that was asked, but it blocks anyone who tries the obvious
136
+ thing. `sdn-emception@1.0.0` ships both uncompressed and brotli packs, and its
137
+ loader fetches the uncompressed ones — 143,151,779 B for the three it needs.
138
+ Pointing the fetch at the `.pack.br` siblings (21,901,402 B) produces a
139
+ compiler that cannot compile.
140
+
141
+ | pack | `.pack` | `.pack.br` decompresses to | first entry |
142
+ | --- | ---: | ---: | --- |
143
+ | `wasm` | 69,661,854 | 69,661,854 | `wasm/binaryen-box.wasm` |
144
+ | `cpython` | 9,129,156 | 9,129,487 | `usr/` |
145
+ | `emscripten` | 64,360,769 | 31,286,982 | `./` — **not** `emscripten/` |
146
+
147
+ The `.pack.br` files are a different build, not compressed copies:
148
+
149
+ 1. **The emscripten one is rooted at `.`**, so unpacking it where the prefixed
150
+ packs go scatters the emscripten tree across the filesystem root. Nothing
151
+ throws; the next thing to fail is `python: can't open file
152
+ '/emscripten/emcc.py': [Errno 44]`, stages later, with no hint of the cause.
153
+ 2. **It omits the prebuilt sysroot.** The real `emscripten.pack` carries 7,434
154
+ `emscripten/cache/sysroot/**` entries; the `.br` build carries none. Without
155
+ them the first link rebuilds libc (998 inputs), libc++, compiler_rt and the
156
+ rest inside the tab — **135 s, measured** — and then dies generating
157
+ `struct_info.json`, because that step compiles a probe and runs it under
158
+ emception's quicknode: `Error: not compiled for this environment`.
159
+
160
+ Proven not to be an artifact of the change: with the loader **unpatched** on
161
+ the 143 MB packs, the same fixture compiles in **3.9 s**
162
+ (`node vendor.mjs --uncompressed`, kept as the A/B control).
163
+
164
+ **What the lane does instead.** It compresses the *working* packs itself at
165
+ vendor time (brotli q11, lgwin 24) and serves those. Measured:
166
+
167
+ | | bytes |
168
+ | --- | ---: |
169
+ | Packs, upstream uncompressed lane | 143,151,779 |
170
+ | Packs, this lane | **25,851,077** |
171
+ | Cold page load + first compile, total served | **27,431,314** |
172
+ | Second page load + second compile, total served | **26,919** (0 pack bytes) |
173
+ | External-origin requests | **0** |
174
+
175
+ A 5.2× reduction on the wire, and the second compile costs nothing because the
176
+ service worker holds the packs. The task's ≤ 25 MB target is missed by 1.2 MB,
177
+ and the reason is item 2 above: the prebuilt sysroot is what makes the
178
+ difference between a 3 s compile and a 135 s failure, and it is 8.4 MB
179
+ compressed. Trading it away to hit the number would be trading the working
180
+ compiler for a byte count.
181
+
182
+ ### Escalation to `sdn-emception`
183
+
184
+ Two changes, both upstream, both retiring code this lane carries:
185
+
186
+ 1. **Publish `.pack.br` files that are the `.pack` files compressed** — same
187
+ roots, same contents, including `emscripten/cache/sysroot/**`. Today's
188
+ `emscripten.pack.br` cannot build anything.
189
+ 2. **Take a `packs: "br"` constructor option**, so `#fetchAndUnpack` can be
190
+ pointed at them without a vendor-time overlay.
191
+
192
+ Until then the overlay lives in
193
+ `OrbPro/packages/orbpro-integration/build-cutter/emception/vendor.mjs`: two
194
+ exact string rewrites, each required to match **exactly once**, so an
195
+ `sdn-emception` refresh fails the build loudly instead of silently reverting
196
+ the stack to a 143 MB download.
197
+
198
+ ## 6. Reproducing
199
+
200
+ ```sh
201
+ cd OrbPro/packages/orbpro-integration/build-cutter/emception
202
+ node vendor.mjs # copy the compiler same-origin, compress the packs
203
+ node spike/run.mjs # one headless run -> results/emception-lane.json
204
+ node --test test/emception-lane.test.mjs
205
+ node vendor.mjs --uncompressed # the A/B control: unpatched loader, 143 MB packs
206
+ ```
207
+
208
+ `node server.mjs` serves the lane at `http://127.0.0.1:8137/` for hand
209
+ inspection. It is a dev-server page; it is not published.