space-data-module-sdk 0.8.14 → 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.
- package/bin/space-data-module.js +91 -0
- package/docs/_shell/consumer-assets.html +5 -0
- package/docs/browser-wasmedge-isomorphic.html +261 -0
- package/docs/byo-wasm-quickstart.html +226 -0
- package/docs/byo-wasm-quickstart.md +204 -0
- package/docs/conformance.html +156 -0
- package/docs/conformance.md +92 -0
- package/docs/emception-shared-memory-verdict.md +209 -0
- package/docs/events-abi.html +313 -0
- package/docs/events-abi.md +530 -0
- package/docs/families/analytics.html +178 -0
- package/docs/families/analytics.md +104 -0
- package/docs/families/attitude.html +157 -0
- package/docs/families/attitude.md +36 -0
- package/docs/families/behavior.html +157 -0
- package/docs/families/behavior.md +36 -0
- package/docs/families/breakup.html +157 -0
- package/docs/families/breakup.md +36 -0
- package/docs/families/conjunction.html +186 -0
- package/docs/families/conjunction.md +121 -0
- package/docs/families/data-source.html +318 -0
- package/docs/families/effects.html +157 -0
- package/docs/families/effects.md +36 -0
- package/docs/families/environment.html +170 -0
- package/docs/families/environment.md +73 -0
- package/docs/families/estimation.html +190 -0
- package/docs/families/estimation.md +128 -0
- package/docs/families/gnc.html +157 -0
- package/docs/families/gnc.md +36 -0
- package/docs/families/maneuver.html +209 -0
- package/docs/families/maneuver.md +206 -0
- package/docs/families/obstruction.html +191 -0
- package/docs/families/obstruction.md +96 -0
- package/docs/families/propagator.html +333 -0
- package/docs/families/propulsion.html +157 -0
- package/docs/families/propulsion.md +36 -0
- package/docs/families/reentry.html +157 -0
- package/docs/families/reentry.md +36 -0
- package/docs/families/rf.html +193 -0
- package/docs/families/rf.md +136 -0
- package/docs/families/scheduler.html +157 -0
- package/docs/families/scheduler.md +36 -0
- package/docs/families/sensor.html +157 -0
- package/docs/families/sensor.md +36 -0
- package/docs/families/signature.html +157 -0
- package/docs/families/signature.md +36 -0
- package/docs/flatsql-host-contract.html +176 -0
- package/docs/flatsql-streaming-standard.html +375 -0
- package/docs/gpu-module-abi.html +233 -0
- package/docs/harness-family-matrix.md +135 -0
- package/docs/index.html +216 -85
- package/docs/isomorphic-pthreads.html +228 -0
- package/docs/isomorphic-pthreads.md +84 -0
- package/docs/isomorphic-sdn-runtime-plan.html +274 -0
- package/docs/language-runtime-matrix.html +182 -0
- package/docs/llms.txt +86 -0
- package/docs/module-bundle-runtime-plan.html +146 -0
- package/docs/module-publication-standard.html +503 -0
- package/docs/node-red-default-node-parity.html +201 -0
- package/docs/propagator-abi.md +73 -21
- package/docs/protect-and-sign.html +181 -0
- package/docs/protect-and-sign.md +120 -0
- package/docs/protocol-installation.html +296 -0
- package/docs/publication-submission.html +158 -0
- package/docs/publication-submission.md +78 -0
- package/docs/secrets-capability.html +206 -0
- package/docs/styles.css +860 -167
- package/docs/testing-harness.html +408 -0
- package/docs/tri-runtime-parity-gate.html +182 -0
- package/docs/tri-runtime-parity.html +203 -0
- package/include/orbpro/orbpro_event_runner.h +951 -0
- package/include/orbpro/orbpro_events_abi.h +565 -0
- package/include/orbpro/orbpro_propagator_abi.h +17 -0
- package/package.json +15 -5
- package/schemas/orbpro/Events.fbs +501 -0
- package/schemas/orbpro/Propagator.fbs +72 -9
- package/schemas/orbpro/reference-frame-crosswalk.json +108 -0
- package/schemas/orbpro/reference-frame.lock.json +98 -0
- package/src/browser.js +13 -0
- package/src/conformance/abiDriver.js +225 -0
- package/src/conformance/index.js +151 -0
- package/src/conformance/propagatorSuite.js +526 -0
- package/src/conformance/selfTest.js +275 -0
- package/src/conformance/selfTestCorpus.js +68 -0
- package/src/conformance/twoBodyReference.js +132 -0
- package/src/generated/orbpro/events-abi.js +206 -0
- package/src/generated/orbpro/events-abi.ts +319 -0
- package/src/generated/orbpro/propagator/reference-frame.js +17 -0
- package/src/generated/orbpro/propagator/reference-frame.ts +91 -1
- package/src/generated/orbpro/propagator-abi.js +17 -0
- package/src/generated/orbpro/propagator-abi.ts +17 -0
- package/src/generated/spacedatastandards/plg/CCT.d.ts +94 -0
- package/src/generated/spacedatastandards/plg/CCT.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/CCT.js +208 -0
- package/src/generated/spacedatastandards/plg/CCT.ts +281 -0
- package/src/generated/spacedatastandards/plg/CCTCategory.d.ts +98 -0
- package/src/generated/spacedatastandards/plg/CCTCategory.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/CCTCategory.js +177 -0
- package/src/generated/spacedatastandards/plg/CCTCategory.ts +269 -0
- package/src/generated/spacedatastandards/plg/CCTCategoryRollup.d.ts +54 -0
- package/src/generated/spacedatastandards/plg/CCTCategoryRollup.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/CCTCategoryRollup.js +106 -0
- package/src/generated/spacedatastandards/plg/CCTCategoryRollup.ts +144 -0
- package/src/generated/spacedatastandards/plg/PLG.d.ts +46 -2
- package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -1
- package/src/generated/spacedatastandards/plg/PLG.js +78 -5
- package/src/generated/spacedatastandards/plg/PLG.ts +90 -5
- package/src/generated/spacedatastandards/plg/capabilityClass.d.ts +181 -0
- package/src/generated/spacedatastandards/plg/capabilityClass.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/capabilityClass.js +183 -0
- package/src/generated/spacedatastandards/plg/capabilityClass.ts +208 -0
- package/src/generated/spacedatastandards/plg/main.d.ts +4 -0
- package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -1
- package/src/generated/spacedatastandards/plg/main.js +4 -0
- package/src/generated/spacedatastandards/plg/main.ts +4 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +40 -2
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -1
- package/src/generated/spacedatastandards/plg/pluginCategory.js +40 -2
- package/src/generated/spacedatastandards/plg/pluginCategory.ts +40 -2
- package/src/host/browserModuleHarness.js +8 -0
- package/src/host/wasiThreadHost.js +189 -14
- package/src/index.d.ts +18 -1
- package/src/testing/isomorphicHarness.js +233 -0
- package/src/transport/index.js +16 -0
- package/src/transport/records.js +1015 -3
|
@@ -0,0 +1,333 @@
|
|
|
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 — owner ruling 2026-08-10 ," />
|
|
7
|
+
<title>Propagator — 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"><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="./propagator.html" aria-current="page"><span>Propagator</span><span class="tag tag-shipped">shipped</span></a></li>
|
|
38
|
+
<li><a href="./maneuver.html"><span>Maneuver</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
39
|
+
<li><a href="./propulsion.html"><span>Propulsion</span><span class="tag tag-planned">planned</span></a></li>
|
|
40
|
+
<li><a href="./attitude.html"><span>Attitude</span><span class="tag tag-planned">planned</span></a></li>
|
|
41
|
+
<li><a href="./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="./rf.html"><span>RF</span><span class="tag tag-designed">designed</span></a></li>
|
|
45
|
+
<li><a href="./sensor.html"><span>Sensor</span><span class="tag tag-planned">planned</span></a></li>
|
|
46
|
+
<li><a href="./signature.html"><span>Signature</span><span class="tag tag-planned">planned</span></a></li>
|
|
47
|
+
<li><a href="./environment.html"><span>Environment</span><span class="tag tag-planned">planned</span></a></li>
|
|
48
|
+
<li><a href="./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="./breakup.html"><span>Breakup</span><span class="tag tag-planned">planned</span></a></li>
|
|
52
|
+
<li><a href="./reentry.html"><span>Reentry</span><span class="tag tag-planned">planned</span></a></li>
|
|
53
|
+
<li><a href="./conjunction.html"><span>Conjunction</span><span class="tag tag-designed">designed</span></a></li>
|
|
54
|
+
<li><a href="./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="./estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
58
|
+
<li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
|
|
59
|
+
<li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
60
|
+
<li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
|
|
61
|
+
<li><a href="./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
|
+
<p class="breadcrumb"><a href="../index.html">Harness families</a> / Dynamics</p>
|
|
86
|
+
<h1>Propagator</h1>
|
|
87
|
+
<p class="doc-meta"><span class="pill pill-shipped">shipped</span><span>Shipped contract. Generated from a ratified .fbs single source, covered by a conformance kit and a reference module.</span></p>
|
|
88
|
+
<p><strong>Status:</strong> v1 — owner ruling 2026-08-10 ("No JS propagator!!!! WASM ONLY"), graph task <code>harness-w1-propagator-abi-and-reference</code>, ratified by <code>graph/findings/official-harness-shapes.md</code> §7 SHIP-1.</p>
|
|
89
|
+
<p>This is <strong>the</strong> official third-party propagator harness. A propagator that touches OrbPro primitives ships as a signed WASM module implementing the exports below. The JavaScript <code>Propagators</code> registry is INTERNAL engine plumbing — how the engine dispatches to compiled modules — and is never offered as a public extension point.</p>
|
|
90
|
+
<p>Nothing in this ABI names Cesium, OrbPro, or a vendor. The same exports serve the browser frame-worker pool, a WasmEdge flow runtime, and a deterministic test fixture.</p>
|
|
91
|
+
<h2 id="doctrine"><a class="anchor" href="#doctrine" aria-hidden="true">#</a>Doctrine</h2>
|
|
92
|
+
<p>Five rules govern every line below.</p>
|
|
93
|
+
<ol>
|
|
94
|
+
<li><strong>One source, generated everywhere.</strong> The structs, enums, size locks and offset locks in this ABI are GENERATED from <code>schemas/orbpro/Propagator.fbs</code>. No hand-written mirror is legitimate anywhere in the stack. Before W1.1 there were five, they disagreed, and the disagreement was a units contradiction inside a single file — kilometres in the field comments, METERS in the layout block three lines below.</li>
|
|
95
|
+
<li><strong>The wire is bytes at offsets, and the offsets are locked.</strong> Every ABI struct carries <code>_Static_assert</code> on its size AND on every field offset. This is not decoration: JavaScript reads these structs out of linear memory at byte offsets, and no runtime check can catch a shifted field — <code>6778</code> and <code>6778000</code> are both finite doubles.</li>
|
|
96
|
+
<li><strong>Refuse rather than approximate.</strong> A propagator that cannot answer returns a documented negative code. It never returns a plausible number it does not stand behind, and it never traps on input it was given the chance to validate. A <code>converged</code> flag is never trusted by a consumer; it is adjudicated by verify-by-propagation.</li>
|
|
97
|
+
<li><strong>Declare what you are.</strong> Frame, validity flags and reserved bytes are WRITTEN, every call. A state vector that leaves <code>reference_frame</code> at its default is unreadable by a host that honours the field, and one that leaves the padding bytes alone is handing back the previous call's data.</li>
|
|
98
|
+
<li><strong>The engine owns the schedule; the module owns one row.</strong> Sharding a batch across workers is the host's decision. A module writes only the rows it was given and holds no cross-row state, which is what makes it safe under any sharding the host chooses.</li>
|
|
99
|
+
</ol>
|
|
100
|
+
<h2 id="capability"><a class="anchor" href="#capability" aria-hidden="true">#</a>Capability</h2>
|
|
101
|
+
<p>A propagator module declares family <code>propagator</code> in its <code>plugin-manifest.json</code>. The family vocabulary is authoritative and fail-closed: <code>normalizePluginFamily</code> throws <code>UnknownPluginFamilyError</code> naming the value and the vocabulary (W0.3). There is no silent <code>ANALYSIS</code> fallback — that fallback silently mislabelled 22 modules.</p>
|
|
102
|
+
<p><strong>The namespace rule.</strong> A <code>$</code>-prefixed four-byte file identifier is ratified SDS. A bare four-byte identifier is a vendor invention, and <strong>a harness MUST refuse it</strong>. A port declaring <code>acceptsAnyFlatbuffer</code> is unconformable and is not admissible on a harnessed family: a wildcard cannot be conformance-tested, and six first-party manifests currently declare one on both faces.</p>
|
|
103
|
+
<p>The reference module's ingest port is the worked example: it declares exactly <code>$OMM</code>, in both its canonical FlatBuffer form and its aligned-binary peer, and nothing else.</p>
|
|
104
|
+
<h2 id="the-export-set"><a class="anchor" href="#the-export-set" aria-hidden="true">#</a>The export set</h2>
|
|
105
|
+
<p>Exports are announced with <code>__attribute__((export_name(...)))</code>. The SDK compiler exports the invoke-surface symbols and every declared <code>methodId</code>; the propagator ABI entry points are not <code>methodId</code>s, so they announce themselves.</p>
|
|
106
|
+
<h3 id="required"><a class="anchor" href="#required" aria-hidden="true">#</a>Required</h3>
|
|
107
|
+
<div class="table-wrap"><table><thead><tr><th>Export</th><th>Signature</th><th>Returns</th></tr></thead><tbody><tr><td><code>plugin_init</code></td><td><code>int32_t(const uint8_t* data, size_t len)</code></td><td>entities initialized (>0), or a negative <a href="#error-codes">error code</a></td></tr><tr><td><code>plugin_propagate</code></td><td><code>int32_t(double julian_date, uint32_t entity_index, OrbProStateVector* out)</code></td><td><code>0</code>, or a negative error code</td></tr><tr><td><code>plugin_destroy</code></td><td><code>void(void)</code></td><td>—</td></tr></tbody></table></div>
|
|
108
|
+
<p>At least one of <code>plugin_propagate</code> or <code>plugin_propagate_batch</code> must exist; shipping both is expected, and they must agree exactly (see <a href="#parity-envelope">parity envelope</a>).</p>
|
|
109
|
+
<h3 id="typed-ingest"><a class="anchor" href="#typed-ingest" aria-hidden="true">#</a>Typed ingest</h3>
|
|
110
|
+
<div class="table-wrap"><table><thead><tr><th>Export</th><th>Signature</th><th>Returns</th></tr></thead><tbody><tr><td><code>plugin_init_omm</code></td><td><code>int32_t(const OrbProOMMRecord* records, uint32_t count)</code></td><td>entities now held, or negative</td></tr><tr><td><code>plugin_ingest_omm_one</code></td><td><code>int32_t(const OrbProOMMRecord* record)</code></td><td><strong>the handle it assigned</strong>, or negative</td></tr><tr><td><code>plugin_init_elements</code></td><td><code>int32_t(const OrbProOrbitalElements* elements, uint32_t count)</code></td><td>entities initialized, or negative</td></tr></tbody></table></div>
|
|
111
|
+
<p><code>plugin_init_omm</code> REPLACES the element set. <code>plugin_ingest_omm_one</code> APPENDS and returns its handle — see <a href="#identity">identity</a>.</p>
|
|
112
|
+
<h3 id="batch-and-introspection"><a class="anchor" href="#batch-and-introspection" aria-hidden="true">#</a>Batch and introspection</h3>
|
|
113
|
+
<div class="table-wrap"><table><thead><tr><th>Export</th><th>Signature</th><th>Returns</th></tr></thead><tbody><tr><td><code>plugin_propagate_batch</code></td><td><code>int32_t(double julian_date, OrbProStateVector* out, uint32_t count)</code></td><td><code>0</code>, or negative</td></tr><tr><td><code>plugin_entity_count</code></td><td><code>int32_t(void)</code></td><td>entities currently held</td></tr></tbody></table></div>
|
|
114
|
+
<p><code>plugin_init</code> must accept a packed array of <code>OrbProOMMRecord</code> and MUST refuse a length that is not a whole multiple of <code>sizeof(OrbProOMMRecord)</code>. A partial trailing record means the caller and the module disagree about the struct size, and the size lock cannot see across the boundary.</p>
|
|
115
|
+
<h2 id="wire-layout"><a class="anchor" href="#wire-layout" aria-hidden="true">#</a>Wire layout</h2>
|
|
116
|
+
<p>Generated header: <code>include/orbpro/orbpro_propagator_abi.h</code>. Generated TS byte offsets: <code>space-data-module-sdk/generated/propagator-abi</code>. <strong>Read offsets from the generated bindings. Never write a literal <code>8</code>.</strong></p>
|
|
117
|
+
<h3 id="orbprostatevector-64-bytes-8-byte-aligned"><a class="anchor" href="#orbprostatevector-64-bytes-8-byte-aligned" aria-hidden="true">#</a><code>OrbProStateVector</code> — 64 bytes, 8-byte aligned</h3>
|
|
118
|
+
<div class="table-wrap"><table><thead><tr><th>Offset</th><th>Size</th><th>Type</th><th>Field</th></tr></thead><tbody><tr><td>0</td><td>8</td><td>float64</td><td><code>epoch</code> — Julian date</td></tr><tr><td>8</td><td>24</td><td>float64×3</td><td><code>position</code> — <strong>METERS</strong></td></tr><tr><td>32</td><td>24</td><td>float64×3</td><td><code>velocity</code> — <strong>METERS/SECOND</strong></td></tr><tr><td>56</td><td>1</td><td>uint8</td><td><code>reference_frame</code></td></tr><tr><td>57</td><td>3</td><td>uint8×3</td><td>padding — <strong>MUST be written as zero</strong></td></tr><tr><td>60</td><td>4</td><td>uint32</td><td><code>flags</code></td></tr></tbody></table></div>
|
|
119
|
+
<p>The one-byte frame plus three reserved bytes is a DECLARED layout, not an accident. The C header formerly declared a <code>uint32_t</code> at offset 56, which is wire-identical only by little-endian accident (W0.2).</p>
|
|
120
|
+
<h3 id="orbproommrecord-88-bytes-8-byte-aligned"><a class="anchor" href="#orbproommrecord-88-bytes-8-byte-aligned" aria-hidden="true">#</a><code>OrbProOMMRecord</code> — 88 bytes, 8-byte aligned</h3>
|
|
121
|
+
<div class="table-wrap"><table><thead><tr><th>Offset</th><th>Size</th><th>Field</th><th>Units</th></tr></thead><tbody><tr><td>0</td><td>8</td><td><code>epoch_jd</code></td><td>Julian date</td></tr><tr><td>8</td><td>8</td><td><code>mean_motion</code></td><td>REV/DAY</td></tr><tr><td>16</td><td>8</td><td><code>eccentricity</code></td><td>—</td></tr><tr><td>24</td><td>8</td><td><code>inclination</code></td><td>DEGREES</td></tr><tr><td>32</td><td>8</td><td><code>ra_of_asc_node</code></td><td>DEGREES</td></tr><tr><td>40</td><td>8</td><td><code>arg_of_pericenter</code></td><td>DEGREES</td></tr><tr><td>48</td><td>8</td><td><code>mean_anomaly</code></td><td>DEGREES</td></tr><tr><td>56</td><td>8</td><td><code>bstar</code></td><td>1/earth-radii</td></tr><tr><td>64</td><td>8</td><td><code>mean_motion_dot</code></td><td>REV/DAY²</td></tr><tr><td>72</td><td>8</td><td><code>mean_motion_ddot</code></td><td>REV/DAY³</td></tr><tr><td>80</td><td>4</td><td><code>norad_cat_id</code></td><td>uint32</td></tr><tr><td>84</td><td>4</td><td>padding</td><td>MUST be zero</td></tr></tbody></table></div>
|
|
122
|
+
<p><strong>This struct is also an on-disk format.</strong> The first-party SGP4 module persists it verbatim as a SQLite BLOB (<code>sqlite3_bind_blob(..., &omm, sizeof(OrbProOMMRecord), ...)</code>). Until W1.1 it carried no size or offset lock anywhere in the stack, so the layout every stored blob depends on was held only by the field order of one hand-written C struct in one module.</p>
|
|
123
|
+
<p>The layout above is that layout, exactly as it has already been written to disk, trailing padding included. Locking it revealed <strong>no ambiguity</strong>: the IDL-derived layout reproduces the hand-written struct byte for byte, so the lock pins the existing wire rather than changing it. Migration is out of scope and would invalidate every stored blob.</p>
|
|
124
|
+
<h3 id="orbproorbitalelements-64-bytes-8-byte-aligned"><a class="anchor" href="#orbproorbitalelements-64-bytes-8-byte-aligned" aria-hidden="true">#</a><code>OrbProOrbitalElements</code> — 64 bytes, 8-byte aligned</h3>
|
|
125
|
+
<p>Eight float64 in declaration order: <code>semi_major_axis</code> (<strong>KILOMETRES</strong>), <code>eccentricity</code>, <code>inclination</code>, <code>raan</code>, <code>arg_periapsis</code>, <code>true_anomaly</code> (all RADIANS), <code>epoch</code> (Julian date), <code>reserved</code> (MUST be 0).</p>
|
|
126
|
+
<h2 id="units"><a class="anchor" href="#units" aria-hidden="true">#</a>Units</h2>
|
|
127
|
+
<blockquote><p><code>OrbProStateVector.position</code> IS IN METERS. <code>OrbProStateVector.velocity</code> IS IN METERS PER SECOND.</p></blockquote>
|
|
128
|
+
<p>There is no km variant, no per-plugin unit flag, and no negotiation. A plugin that writes kilometres here is off by 1000× and its satellites render inside the Earth.</p>
|
|
129
|
+
<p>The ONE place kilometres survive is <code>OrbProOrbitalElements.semi_major_axis</code>, an INPUT struct that is not the state vector. It is kilometres there and stays kilometres. Do not "unify" them.</p>
|
|
130
|
+
<p>Ruling: finding §4.1 / §8.1; landed as W0.1.</p>
|
|
131
|
+
<h2 id="frames"><a class="anchor" href="#frames" aria-hidden="true">#</a>Frames</h2>
|
|
132
|
+
<p><code>reference_frame</code> is <code>OrbProReferenceFrame</code>. Values <strong>0-5 are frozen and are never renumbered</strong>; the GMAT axis roster is appended at 6+:</p>
|
|
133
|
+
<p><code>TEME=0 J2000=1 ICRF=2 ECEF=3 MCI=4 MCMF=5 MJ2000EC=6 MOD=7 TOD=8 MOE=9 TOE=10 BODY_FIXED=11 BODY_INERTIAL=12 OBJECT_REFERENCED=13 LOCAL_ALIGNED_CONSTRAINED=14 EQUATOR=15 GSE=16 GSM=17 TOPOCENTRIC=18 BODY_SPIN_SUN=19 SPICE_DEFINED=20 MOD_FK5=21 TOD_FK5=22</code></p>
|
|
134
|
+
<p><code>ECEF</code>, <code>MCI</code> and <code>MCMF</code> are body-bound legacy instances of the generic pair at 11/12 — ECEF is <code>BODY_FIXED</code> about the Earth, MCI is <code>BODY_INERTIAL</code> about Mars, MCMF is <code>BODY_FIXED</code> about Mars. They are retained; the generic members are not a second spelling of them.</p>
|
|
135
|
+
<p><code>MOD_FK5</code> and <code>TOD_FK5</code> are the IAU-76/FK5 route, retained under a NAME rather than left as an undocumented second answer. They differ from <code>MOD</code>/<code>TOD</code> at the milliarcsecond level and are not interchangeable with them.</p>
|
|
136
|
+
<p><strong>Plugins output ECEF.</strong> The frame transform happens INSIDE the module. A plugin that emits an inertial frame and expects the host to rotate it is relying on a host path that is still unimplemented — <code>PropagatorPlugin.toICRF</code> carries a live TEME≈ICRF approximation, and an ECEF input there is wrong by up to a full Earth rotation (<code>orbpro-toicrf-frame-transform-unimplemented</code>).</p>
|
|
137
|
+
<p><strong>Never let a raw integer frame value cross a boundary unqualified.</strong> Five incompatible <code>ReferenceFrame</code> vocabularies are live on this seam, plus an axis-type roster that is not a <code>ReferenceFrame</code> at all:</p>
|
|
138
|
+
<div class="table-wrap"><table><thead><tr><th>Vocabulary</th><th>Values</th></tr></thead><tbody><tr><td><code>orbpro.propagator</code> (<strong>this ABI</strong>)</td><td>TEME=0 J2000=1 ICRF=2 ECEF=3 MCI=4 MCMF=5, then the roster at 6+</td></tr><tr><td><code>orbpro.plugins</code> (<code>PropagatorState.fbs</code>)</td><td>ECI=0 ECEF=1 TEME=2 ICRF=3</td></tr><tr><td>OrbPro engine <code>ReferenceFrame.js</code></td><td>FIXED=0 INERTIAL=1 TEME=2 VVLH=3 ENU=4 NED=5 NEU=6 RIC=7 LVLH=8</td></tr><tr><td><code>ConjunctionCommon.fbs</code></td><td>ECI=1</td></tr><tr><td><code>foundation/frames</code> <code>AxisType</code></td><td>an ORIENTATION rule, no origin — never numerically equated with a frame</td></tr></tbody></table></div>
|
|
139
|
+
<p>The engine row is the one this document got wrong for a long time: it said "<code>Cesium.ReferenceFrame</code> FIXED=0 INERTIAL=1", and it was stale in the direction that mattered — it hid seven live members. Verified against OrbPro <code>417320c5c5</code> on 2026-08-30.</p>
|
|
140
|
+
<p><code>ECI==0</code>, <code>TEME==0</code> and <code>FIXED==0</code> all collide, and ECEF is 1 in <code>orbpro.plugins</code> but 3 here. Those values are frozen by compiled WASM artifacts already in the field, so collapsing them is a wire break, tracked as <code>sdk-reference-frame-enum-unification</code> — which also owns the ABI-vs-engine inversion at 0/1. Until it lands, <strong>translate by named token at every seam</strong>.</p>
|
|
141
|
+
<p>The crosswalk between all of them is DATA, in <code>schemas/orbpro/reference-frame-crosswalk.json</code>, and <code>npm run check:reference-frame</code> (wired into <code>npm test</code> as <code>test/reference-frame-uniqueness.test.js</code>) holds four things at once: exactly one definition crosses the ABI; its numbering is append-only against <code>schemas/orbpro/reference-frame.lock.json</code>; every foreign vocabulary maps onto it by NAMED TOKEN and totally, re-read from source when that repo is on disk and skipped-with-a-note when it is not; and the three live RTN triads (RIC, RSW, RTN, plus the LVLH/VVLH relabellings) collapse to the single <code>OBJECT_REFERENCED</code> member with an axes spec rather than becoming members of their own.</p>
|
|
142
|
+
<p>Use the generated setter <code>orbpro_state_set_reference_frame()</code>, never a bare assignment: it clears the three padding bytes a consumer reading offset 56 as a 32-bit word would otherwise see as garbage.</p>
|
|
143
|
+
<h2 id="identity"><a class="anchor" href="#identity" aria-hidden="true">#</a>Identity</h2>
|
|
144
|
+
<p><strong><code>NORAD_CAT_ID</code> is the identity authority.</strong> It is carried through, never invented, never synthesized to make a lookup succeed.</p>
|
|
145
|
+
<p><strong>The entity index is a local handle</strong> into one module instance's own array. It is meaningless outside that instance and must never be persisted as an identity.</p>
|
|
146
|
+
<h3 id="creating-engine-state-returns-its-handle"><a class="anchor" href="#creating-engine-state-returns-its-handle" aria-hidden="true">#</a>Creating engine state RETURNS its handle</h3>
|
|
147
|
+
<p>This is the single highest-value primitive the harness adds.</p>
|
|
148
|
+
<div class="codeblock"><div class="codeblock-head">c</div><pre><code>int32_t handle = plugin_ingest_omm_one(&record); /* -> the handle assigned */</code></pre></div>
|
|
149
|
+
<p>A caller must never derive "the entity I just created" as <code>count − 1</code>. Three families in this stack independently reinvented that derivation; all three are race-unsafe, undeclared and untested, and it is the root of defect B3 (the maneuver marker renders from a buffer the seam never writes).</p>
|
|
150
|
+
<p>The engine-side implementation of this primitive for the FIRST-PARTY propagators is <strong>W1.5</strong> (<code>graph/tasks/official-harness-shapes-program.md</code>). This document states the contract now; third-party modules are expected to honour it from day one, and the reference module does.</p>
|
|
151
|
+
<h2 id="threading"><a class="anchor" href="#threading" aria-hidden="true">#</a>Threading</h2>
|
|
152
|
+
<p>Modules compile to <code>wasm32-wasip1-threads</code> (clang), per the isomorphic-pthreads law. <strong>Never <code>emcc -pthread</code></strong> — that emits the browser-only Web Worker + postMessage thread model and has no wasi thread-spawn contract, so it cannot thread under WasmEdge.</p>
|
|
153
|
+
<p>Two thread models are legitimate, and both use that same toolchain:</p>
|
|
154
|
+
<ul>
|
|
155
|
+
<li><strong><code>emscripten-pthreads</code></strong> — despite the name, the real wasi-threads contract: the guest imports <code>wasi.thread-spawn</code> and exports <code>wasi_thread_start</code> over an imported shared memory. The post-link artifact guard fails the build if the emitted wasm does not actually carry shared memory and atomics.</li>
|
|
156
|
+
<li><strong><code>wasi-sequential</code></strong> — the module provably never spawns a thread. Requires <code>manifest.sequentialJustification</code> with a <code>kind</code> and a substantive <code>detail</code>; a mirror guard fails the build if the artifact is not what was claimed.</li>
|
|
157
|
+
</ul>
|
|
158
|
+
<p><strong>A propagator is normally <code>wasi-sequential</code>, and that is the strong default.</strong> Propagation is embarrassingly parallel ACROSS entities and strictly sequential WITHIN one, and the sharding belongs to the host. A module that spawns its own pool contends with the pool already scheduling it.</p>
|
|
159
|
+
<blockquote><p><strong>Known defect:</strong> <code>resolveThreadModel</code> reads the compile OPTION, not <code>manifest.threadModel</code>, and otherwise infers the model from <code>runtimeTargets</code> — where <code>"wasmedge"</code> infers pthreads. Pass <code>threadModel: manifest.threadModel</code> explicitly until <code>sdk-manifest-threadmodel-silently-ignored</code> lands, and assert the compiler agreed.</p></blockquote>
|
|
160
|
+
<h3 id="shard-write-discipline"><a class="anchor" href="#shard-write-discipline" aria-hidden="true">#</a>Shard write discipline</h3>
|
|
161
|
+
<p>When the host runs <code>plugin_propagate_batch</code> across a worker pool it hands each worker the SAME output base pointer and a DISJOINT index range.</p>
|
|
162
|
+
<ul>
|
|
163
|
+
<li>Write <strong>only</strong> rows in your own range. Never write outside your stride.</li>
|
|
164
|
+
<li>Never READ a neighbour's row. Your output must not depend on rows you were not given.</li>
|
|
165
|
+
<li>Hold no cross-row state between rows of one batch.</li>
|
|
166
|
+
<li>On failure, zero the offending row before returning, so a host that ignores the return value still reads a state marked not-valid rather than stale bytes. A partially written batch with no signal is the silent-wrong-numbers failure this ABI exists to prevent.</li>
|
|
167
|
+
</ul>
|
|
168
|
+
<p>A module that satisfies these is safe under any sharding the host chooses, which is the property the ABI actually requires — not a particular thread count.</p>
|
|
169
|
+
<h2 id="error-codes"><a class="anchor" href="#error-codes" aria-hidden="true">#</a>Error codes</h2>
|
|
170
|
+
<p>Every failure returns its OWN documented negative code. A propagator that returns <code>-1</code> for everything is unconformable: the host cannot tell a bad entity index from an uninitialized module, so it cannot place the failure on the degradation ladder (transient → skip; fatal → respawn; exhausted → latch).</p>
|
|
171
|
+
<div class="table-wrap"><table><thead><tr><th>Code</th><th>Name</th><th>Meaning</th></tr></thead><tbody><tr><td><code>0</code></td><td>OK</td><td>success</td></tr><tr><td><code>-1</code></td><td>NOT_INITIALIZED</td><td>no elements ingested yet</td></tr><tr><td><code>-2</code></td><td>BAD_ENTITY_INDEX</td><td>index ≥ entity count</td></tr><tr><td><code>-3</code></td><td>NULL_OUTPUT</td><td>caller passed a null output pointer</td></tr><tr><td><code>-4</code></td><td>BAD_INPUT</td><td>malformed or short input buffer</td></tr><tr><td><code>-5</code></td><td>NOT_CONVERGED</td><td>the solve failed to converge</td></tr><tr><td><code>-6</code></td><td>UNPHYSICAL</td><td>the elements describe no closed orbit</td></tr></tbody></table></div>
|
|
172
|
+
<p>Rules that are not negotiable:</p>
|
|
173
|
+
<ul>
|
|
174
|
+
<li><strong>Validated input can never trap.</strong> Malformed input is a code, not a crash.</li>
|
|
175
|
+
<li><strong>NaN is its own failure class.</strong> It is never "a number that happened".</li>
|
|
176
|
+
<li><strong>A physically impossible result is a refusal</strong>, not an output.</li>
|
|
177
|
+
<li><strong>Error classes are identical across runtimes.</strong> A code that differs between browser and WasmEdge is a P1 SDK defect.</li>
|
|
178
|
+
</ul>
|
|
179
|
+
<h2 id="lifetime"><a class="anchor" href="#lifetime" aria-hidden="true">#</a>Lifetime</h2>
|
|
180
|
+
<p><code>plugin_destroy</code> is <strong>required</strong>, and it must actually release.</p>
|
|
181
|
+
<p>The test is mechanical: N × ingest / propagate / destroy must reach a steady memory baseline. WebAssembly linear memory never shrinks, so "memory went back down" is not available and a test asserting it would assert something impossible. What a non-leaking module gives you is that growth STOPS: after a warm-up that pays for every allocation the cycle will ever need, further identical cycles add ZERO pages.</p>
|
|
182
|
+
<p><code>destroy</code> must also be idempotent, must leave <code>plugin_entity_count()</code> at zero, and must leave the module usable — a destroyed module refuses to propagate (<code>NOT_INITIALIZED</code>) rather than reading freed state, and comes back cleanly on the next ingest.</p>
|
|
183
|
+
<blockquote><p><strong>Historical defect, retired 2026-08-12.</strong> <code>destroySource()</code> was literally <code>{}</code> in BOTH shipped first-party propagators when this ABI was written (finding §4.5), and sgp4's <code>createSourceFromState</code> re-ingested the whole catalogue for a single burn. The maneuver program landed the fix on OrbPro <code>main</code> (<code>2db279766c</code> and <code>97cc38127e</code>): both propagators now recycle post-burn source SLOTS — the entity stays resident so no index above it moves, destroy marks the slot free, and creating a source re-points the recycled entity in place. The reference module remains the leak-test bar, now enforced mechanically by <code>space-data-module conformance propagator</code> (tier4/lifecycle-leak).</p></blockquote>
|
|
184
|
+
<h2 id="versioning"><a class="anchor" href="#versioning" aria-hidden="true">#</a>Versioning</h2>
|
|
185
|
+
<p><code>abi_version</code> gates at register/load. <code>ORBPRO_ABI_VERSION</code> is declared in <code>orbpro_plugin.h</code>; a module declares <code>abiVersion</code> in its manifest, and a mismatch is refused with <code>ORBPRO_ERROR_ABI_MISMATCH</code>, never coerced.</p>
|
|
186
|
+
<p>Shape versions are <code>SHAPE_MAJOR.SHAPE_MINOR</code>, independent of the SDS wave counter.</p>
|
|
187
|
+
<ul>
|
|
188
|
+
<li><strong>Additive-only within a MAJOR.</strong> Enforced by the drift gate, not by prose: <code>npm run check:propagator-abi</code> regenerates every artifact from the IDL and byte-diffs it against what is committed. Any difference fails.</li>
|
|
189
|
+
<li><strong>Consumers declare a FLOOR plus a MAJOR, never exact equality.</strong> Exact-equality resolution caused three build outages and a P1 in one week. Floors only advance.</li>
|
|
190
|
+
<li><strong>Stability promise:</strong> additive-only for two minors; a breaking change requires a one-minor deprecation notice.</li>
|
|
191
|
+
<li><strong>Deprecation, never deletion.</strong></li>
|
|
192
|
+
<li><strong>Refusals are legible.</strong> A mismatch names the shape, what was required and what was offered — never "not found".</li>
|
|
193
|
+
</ul>
|
|
194
|
+
<h2 id="parity-envelope"><a class="anchor" href="#parity-envelope" aria-hidden="true">#</a>Parity envelope</h2>
|
|
195
|
+
<p><strong>Inside the envelope</strong> — byte-identical across browser, native WasmEdge and Docker WasmEdge, at thread counts 1/2/4/8:</p>
|
|
196
|
+
<ul>
|
|
197
|
+
<li>every byte of every <code>OrbProStateVector</code> a module writes for given inputs</li>
|
|
198
|
+
<li><code>plugin_propagate</code> and <code>plugin_propagate_batch</code> for the same entity and epoch</li>
|
|
199
|
+
<li>every error code, for every malformed and unsatisfiable input</li>
|
|
200
|
+
<li>the handle <code>plugin_ingest_omm_one</code> assigns, for a given ingest order</li>
|
|
201
|
+
<li>the steady-state verdict of the lifecycle leak test</li>
|
|
202
|
+
</ul>
|
|
203
|
+
<p>Determinism is compared as <strong>bytes, not as numbers</strong>, and must survive a destroy / re-ingest cycle: output that changes after a lifecycle round trip is state leaking across it.</p>
|
|
204
|
+
<p><strong>Outside the envelope</strong>, stated so it is never mistaken for a defect: results from a propagator whose physics depends on live external data (space weather, EOP) at different acquisition instants. Their ABI BEHAVIOUR — codes, struct shapes, frame declaration, padding, copy accounting — is fully inside.</p>
|
|
205
|
+
<p><strong>Divergence in anything listed as inside the envelope is a P1 SDK defect.</strong> Not a platform quirk. File, block, fix.</p>
|
|
206
|
+
<p>Run it:</p>
|
|
207
|
+
<div class="codeblock"><pre><code>space-data-module parity-gate --artifact <id>=./dist/isomorphic/module.wasm:module</code></pre></div>
|
|
208
|
+
<h2 id="conformance"><a class="anchor" href="#conformance" aria-hidden="true">#</a>Conformance</h2>
|
|
209
|
+
<p>What "official" buys a third party: one command, family-dispatched, shipped with its own negative control (<a href="../conformance.html">docs/conformance.md</a>):</p>
|
|
210
|
+
<div class="codeblock"><pre><code>space-data-module conformance propagator --artifact ./dist/isomorphic/module.wasm
|
|
211
|
+
space-data-module conformance propagator --self-test # must exit 0 BY failing</code></pre></div>
|
|
212
|
+
<p>The runner adjudicates everything this document specifies that a single lane can observe — the export set, the corpus anchors, the invariants with no stored expectation, the error-code table, and the leak test — and reports the cross-runtime lane honestly as a gap that only the parity gate above closes. <code>PASS</code> / <code>PASS-WITH-GAPS</code> exit 0; <code>FAIL</code> exits 1 with the offending check named.</p>
|
|
213
|
+
<h2 id="consumer-seam"><a class="anchor" href="#consumer-seam" aria-hidden="true">#</a>Consumer seam</h2>
|
|
214
|
+
<p>Per the pluggable-propagation law (owner, 2026-07-29), <strong>every surface that consumes a propagator takes it as a parameter or port</strong> — never hardwired to SGP4 or any single provider. A Sandcastle demo resolves it once from <code>?propagator=NAME</code> and feeds that single value to every consumer downstream.</p>
|
|
215
|
+
<p>Engine-side, <code>PropagatedPositionProperty</code> accepts a propagator instance OR a registered name/id, and orbits are drawn by the regular path visualizer. Third-party modules reach it through the storefront ADD path — <code>Cesium.registerPlugin(name, source)</code> then <code>initPlugins({ plugins: [name] })</code>. Built-in bundle names are refused there (<code>E92</code>); a third-party module uses its own name.</p>
|
|
216
|
+
<h2 id="guest-usage"><a class="anchor" href="#guest-usage" aria-hidden="true">#</a>Guest usage</h2>
|
|
217
|
+
<p>The complete, buildable reference implementation lives at <code>space-data-network-modules/propagator/keplerian-reference/</code>. Every export in it is annotated with the section of this document it implements, and <code>space-data-module init --family propagator</code> scaffolds its skeleton.</p>
|
|
218
|
+
<div class="codeblock"><div class="codeblock-head">c</div><pre><code>#include "space_data_module_invoke.h"
|
|
219
|
+
#include "orbpro/orbpro_propagator_abi.h" /* the ONE generated ABI */
|
|
220
|
+
|
|
221
|
+
#define ORBPRO_ABI_EXPORT(name) __attribute__((export_name(name))) extern "C"
|
|
222
|
+
|
|
223
|
+
ORBPRO_ABI_EXPORT("plugin_propagate")
|
|
224
|
+
int32_t plugin_propagate(double julian_date, uint32_t entity_index,
|
|
225
|
+
OrbProStateVector* out) {
|
|
226
|
+
if (out == NULL) return -3; /* NULL_OUTPUT */
|
|
227
|
+
if (entity_count == 0) return -1; /* NOT_INITIALIZED */
|
|
228
|
+
if (entity_index >= entity_count) return -2; /* BAD_ENTITY_INDEX */
|
|
229
|
+
|
|
230
|
+
/* Start from the initializer: it zeroes the WHOLE struct, including the
|
|
231
|
+
* three reserved bytes the IDL requires to be zero. The host reuses one
|
|
232
|
+
* scratch buffer across every call, so a partial write hands back the
|
|
233
|
+
* previous call's bytes. */
|
|
234
|
+
orbpro_state_init(out);
|
|
235
|
+
out->epoch = julian_date;
|
|
236
|
+
out->position[0] = x_metres; /* METERS. Not kilometres. */
|
|
237
|
+
out->position[1] = y_metres;
|
|
238
|
+
out->position[2] = z_metres;
|
|
239
|
+
out->velocity[0] = vx_metres_per_second;
|
|
240
|
+
out->velocity[1] = vy_metres_per_second;
|
|
241
|
+
out->velocity[2] = vz_metres_per_second;
|
|
242
|
+
|
|
243
|
+
/* Use the generated setter — it clears the padding bytes. */
|
|
244
|
+
orbpro_state_set_reference_frame(out, ORBPRO_FRAME_ECEF);
|
|
245
|
+
out->flags |= (uint32_t)ORBPRO_STATE_VALID;
|
|
246
|
+
return 0;
|
|
247
|
+
}</code></pre></div>
|
|
248
|
+
<p>Reading a state vector from JavaScript, without a single literal offset:</p>
|
|
249
|
+
<div class="codeblock"><div class="codeblock-head">js</div><pre><code>import { ORBPRO_STATE_VECTOR } from "space-data-module-sdk/generated/propagator-abi";
|
|
250
|
+
|
|
251
|
+
const { offsets, size } = ORBPRO_STATE_VECTOR;
|
|
252
|
+
const view = new DataView(memory.buffer, pointer, size);
|
|
253
|
+
const epoch = view.getFloat64(offsets.epoch, true);
|
|
254
|
+
const x = view.getFloat64(offsets.position, true);
|
|
255
|
+
const frame = view.getUint8(offsets.reference_frame);</code></pre></div>
|
|
256
|
+
<h2 id="regenerating"><a class="anchor" href="#regenerating" aria-hidden="true">#</a>Regenerating</h2>
|
|
257
|
+
<div class="codeblock"><pre><code>node scripts/generate-propagator-abi.mjs # regenerate from the IDL
|
|
258
|
+
node scripts/check-propagator-abi.mjs # the drift gate (runs in npm test)</code></pre></div>
|
|
259
|
+
<p>The gate ships its own negative control: a test corrupts a copy of the generated tree and requires the gate to name the corruption. A gate never observed to fail is indistinguishable from one that cannot fail.</p>
|
|
260
|
+
<section class="playground" id="playground-slot" data-family="propagator" data-playground="pending" aria-labelledby="playground-title">
|
|
261
|
+
<h2 id="playground-title">Playground</h2>
|
|
262
|
+
<p>
|
|
263
|
+
An in-browser build-and-run playground for the <code>propagator</code> harness
|
|
264
|
+
mounts here. It is being built under the graph task
|
|
265
|
+
<code>sdk-playground-emception</code>; this slot is its reserved mount
|
|
266
|
+
point and is intentionally empty until that lands.
|
|
267
|
+
</p>
|
|
268
|
+
</section>
|
|
269
|
+
<p class="doc-footer">
|
|
270
|
+
Source of truth for this page:
|
|
271
|
+
<code>docs/propagator-abi.md</code>. Regenerate with
|
|
272
|
+
<code>npm run build:docs</code>.
|
|
273
|
+
</p>
|
|
274
|
+
</main>
|
|
275
|
+
<nav class="rail" aria-label="On this page"><h2>On this page</h2><ul><li><a class="depth-2" href="#doctrine">Doctrine</a></li>
|
|
276
|
+
<li><a class="depth-2" href="#capability">Capability</a></li>
|
|
277
|
+
<li><a class="depth-2" href="#the-export-set">The export set</a></li>
|
|
278
|
+
<li><a class="depth-3" href="#required">Required</a></li>
|
|
279
|
+
<li><a class="depth-3" href="#typed-ingest">Typed ingest</a></li>
|
|
280
|
+
<li><a class="depth-3" href="#batch-and-introspection">Batch and introspection</a></li>
|
|
281
|
+
<li><a class="depth-2" href="#wire-layout">Wire layout</a></li>
|
|
282
|
+
<li><a class="depth-3" href="#orbprostatevector-64-bytes-8-byte-aligned"><code>OrbProStateVector</code> — 64 bytes, 8-byte aligned</a></li>
|
|
283
|
+
<li><a class="depth-3" href="#orbproommrecord-88-bytes-8-byte-aligned"><code>OrbProOMMRecord</code> — 88 bytes, 8-byte aligned</a></li>
|
|
284
|
+
<li><a class="depth-3" href="#orbproorbitalelements-64-bytes-8-byte-aligned"><code>OrbProOrbitalElements</code> — 64 bytes, 8-byte aligned</a></li>
|
|
285
|
+
<li><a class="depth-2" href="#units">Units</a></li>
|
|
286
|
+
<li><a class="depth-2" href="#frames">Frames</a></li>
|
|
287
|
+
<li><a class="depth-2" href="#identity">Identity</a></li>
|
|
288
|
+
<li><a class="depth-3" href="#creating-engine-state-returns-its-handle">Creating engine state RETURNS its handle</a></li>
|
|
289
|
+
<li><a class="depth-2" href="#threading">Threading</a></li>
|
|
290
|
+
<li><a class="depth-3" href="#shard-write-discipline">Shard write discipline</a></li>
|
|
291
|
+
<li><a class="depth-2" href="#error-codes">Error codes</a></li>
|
|
292
|
+
<li><a class="depth-2" href="#lifetime">Lifetime</a></li>
|
|
293
|
+
<li><a class="depth-2" href="#versioning">Versioning</a></li>
|
|
294
|
+
<li><a class="depth-2" href="#parity-envelope">Parity envelope</a></li>
|
|
295
|
+
<li><a class="depth-2" href="#conformance">Conformance</a></li>
|
|
296
|
+
<li><a class="depth-2" href="#consumer-seam">Consumer seam</a></li>
|
|
297
|
+
<li><a class="depth-2" href="#guest-usage">Guest usage</a></li>
|
|
298
|
+
<li><a class="depth-2" href="#regenerating">Regenerating</a></li></ul></nav>
|
|
299
|
+
</div>
|
|
300
|
+
<section id="stack" class="section" aria-labelledby="stack-title">
|
|
301
|
+
<div class="section-head">
|
|
302
|
+
<p class="eyebrow">SDN Stack</p>
|
|
303
|
+
<h2 id="stack-title">Connected sites</h2>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="link-list">
|
|
306
|
+
<a href="https://spacedatastandards.org/">
|
|
307
|
+
<span>Standards</span>
|
|
308
|
+
<small>Canonical schemas, record contracts, and generated bindings.</small>
|
|
309
|
+
</a>
|
|
310
|
+
<a href="https://digitalarsenal.github.io/flatbuffers/">
|
|
311
|
+
<span>FlatBuffers</span>
|
|
312
|
+
<small>Binary encoding, schema tooling, and runtime documentation.</small>
|
|
313
|
+
</a>
|
|
314
|
+
<a href="https://digitalarsenal.github.io/flatsql/">
|
|
315
|
+
<span>FlatSQL</span>
|
|
316
|
+
<small>SQL-style queries over FlatBuffer-backed datasets and streams.</small>
|
|
317
|
+
</a>
|
|
318
|
+
<a href="https://spacedatanetwork.org/">
|
|
319
|
+
<span>SDN</span>
|
|
320
|
+
<small>Distributed publication, discovery, delivery, and marketplace infrastructure.</small>
|
|
321
|
+
</a>
|
|
322
|
+
<a href="https://digitalarsenal.github.io/space-data-module-sdk/" class="active">
|
|
323
|
+
<span>Module SDK</span>
|
|
324
|
+
<small>WASM module packaging, validation, and host compatibility tooling.</small>
|
|
325
|
+
</a>
|
|
326
|
+
</div>
|
|
327
|
+
</section>
|
|
328
|
+
<footer class="site-footer">
|
|
329
|
+
Space Data Module SDK — Apache-2.0. Every ABI page renders a Markdown
|
|
330
|
+
source in <code>docs/</code>; edit the Markdown, never the HTML.
|
|
331
|
+
</footer>
|
|
332
|
+
</body>
|
|
333
|
+
</html>
|
|
@@ -0,0 +1,157 @@
|
|
|
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: PLANNED. This family is a ratified entry in the harness-family" />
|
|
7
|
+
<title>Propulsion — 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"><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="./propagator.html"><span>Propagator</span><span class="tag tag-shipped">shipped</span></a></li>
|
|
38
|
+
<li><a href="./maneuver.html"><span>Maneuver</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
39
|
+
<li><a href="./propulsion.html" aria-current="page"><span>Propulsion</span><span class="tag tag-planned">planned</span></a></li>
|
|
40
|
+
<li><a href="./attitude.html"><span>Attitude</span><span class="tag tag-planned">planned</span></a></li>
|
|
41
|
+
<li><a href="./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="./rf.html"><span>RF</span><span class="tag tag-designed">designed</span></a></li>
|
|
45
|
+
<li><a href="./sensor.html"><span>Sensor</span><span class="tag tag-planned">planned</span></a></li>
|
|
46
|
+
<li><a href="./signature.html"><span>Signature</span><span class="tag tag-planned">planned</span></a></li>
|
|
47
|
+
<li><a href="./environment.html"><span>Environment</span><span class="tag tag-planned">planned</span></a></li>
|
|
48
|
+
<li><a href="./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="./breakup.html"><span>Breakup</span><span class="tag tag-planned">planned</span></a></li>
|
|
52
|
+
<li><a href="./reentry.html"><span>Reentry</span><span class="tag tag-planned">planned</span></a></li>
|
|
53
|
+
<li><a href="./conjunction.html"><span>Conjunction</span><span class="tag tag-designed">designed</span></a></li>
|
|
54
|
+
<li><a href="./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="./estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
58
|
+
<li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
|
|
59
|
+
<li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
|
|
60
|
+
<li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
|
|
61
|
+
<li><a href="./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
|
+
<p class="breadcrumb"><a href="../index.html">Harness families</a> / Dynamics</p>
|
|
86
|
+
<h1>Propulsion</h1>
|
|
87
|
+
<p class="doc-meta"><span class="pill pill-planned">planned</span><span>Planned. This family is a ratified entry in the harness-family taxonomy; its individual shape has not been ratified and nothing is implemented.</span></p>
|
|
88
|
+
<p><strong>Status: PLANNED.</strong> This family is a ratified entry in the harness-family taxonomy. Its individual shape has not been ratified, and nothing is implemented. This page states scope and status; it is not a contract, and it does not imply parity with the Designed tier.</p>
|
|
89
|
+
<h2 id="scope"><a class="anchor" href="#scope" aria-hidden="true">#</a>Scope</h2>
|
|
90
|
+
<p>Model thrust production and propellant consumption: thruster performance, specific impulse, throttle and duty-cycle behavior, tank state and mass depletion over a burn. It supplies the maneuver family rather than replacing it — maneuver decides the burn, propulsion decides what the vehicle can actually deliver and what it costs in mass.</p>
|
|
91
|
+
<h2 id="what-exists-today"><a class="anchor" href="#what-exists-today" aria-hidden="true">#</a>What exists today</h2>
|
|
92
|
+
<p>Nothing. No schema, no header, no module, no open design task.</p>
|
|
93
|
+
<p>Note that a propulsion contract is inseparable from a mass-properties contract: a thrust model that cannot report the mass it consumed is not usable by a propagator that integrates the resulting acceleration. Expect these to be ratified together.</p>
|
|
94
|
+
<h2 id="what-ratification-requires"><a class="anchor" href="#what-ratification-requires" aria-hidden="true">#</a>What ratification requires</h2>
|
|
95
|
+
<p>A family reaches Designed when an ABI has been drafted against a real consumer, and Shipped only when all of the following exist:</p>
|
|
96
|
+
<ul>
|
|
97
|
+
<li>A single <code>.fbs</code> schema as the source of the wire layout.</li>
|
|
98
|
+
<li>A generated ABI header with size and offset locks, plus a drift gate that fails when the schema and the committed header disagree.</li>
|
|
99
|
+
<li>Declared units and frames per field, named sentinels, and named negative error codes.</li>
|
|
100
|
+
<li>A conformance kit carrying its own negative control, and a reference module.</li>
|
|
101
|
+
<li>A stated tri-runtime parity envelope.</li>
|
|
102
|
+
<li>Exactly one generic consumer port.</li>
|
|
103
|
+
</ul>
|
|
104
|
+
<p>Until then, do not build against this family. If your work falls in this scope and cannot wait, build a records-in, records-out module through the <a href="../byo-wasm-quickstart.html">BYO-wasm quickstart</a> — that path needs no harness and is available now — and expect to migrate to the family ABI when it is ratified.</p>
|
|
105
|
+
<section class="playground" id="playground-slot" data-family="propulsion" data-playground="pending" aria-labelledby="playground-title">
|
|
106
|
+
<h2 id="playground-title">Playground</h2>
|
|
107
|
+
<p>
|
|
108
|
+
An in-browser build-and-run playground for the <code>propulsion</code> harness
|
|
109
|
+
mounts here. It is being built under the graph task
|
|
110
|
+
<code>sdk-playground-emception</code>; this slot is its reserved mount
|
|
111
|
+
point and is intentionally empty until that lands.
|
|
112
|
+
</p>
|
|
113
|
+
</section>
|
|
114
|
+
<p class="doc-footer">
|
|
115
|
+
Source of truth for this page:
|
|
116
|
+
<code>docs/families/propulsion.md</code>. Regenerate with
|
|
117
|
+
<code>npm run build:docs</code>.
|
|
118
|
+
</p>
|
|
119
|
+
</main>
|
|
120
|
+
<nav class="rail" aria-label="On this page"><h2>On this page</h2><ul><li><a class="depth-2" href="#scope">Scope</a></li>
|
|
121
|
+
<li><a class="depth-2" href="#what-exists-today">What exists today</a></li>
|
|
122
|
+
<li><a class="depth-2" href="#what-ratification-requires">What ratification requires</a></li></ul></nav>
|
|
123
|
+
</div>
|
|
124
|
+
<section id="stack" class="section" aria-labelledby="stack-title">
|
|
125
|
+
<div class="section-head">
|
|
126
|
+
<p class="eyebrow">SDN Stack</p>
|
|
127
|
+
<h2 id="stack-title">Connected sites</h2>
|
|
128
|
+
</div>
|
|
129
|
+
<div class="link-list">
|
|
130
|
+
<a href="https://spacedatastandards.org/">
|
|
131
|
+
<span>Standards</span>
|
|
132
|
+
<small>Canonical schemas, record contracts, and generated bindings.</small>
|
|
133
|
+
</a>
|
|
134
|
+
<a href="https://digitalarsenal.github.io/flatbuffers/">
|
|
135
|
+
<span>FlatBuffers</span>
|
|
136
|
+
<small>Binary encoding, schema tooling, and runtime documentation.</small>
|
|
137
|
+
</a>
|
|
138
|
+
<a href="https://digitalarsenal.github.io/flatsql/">
|
|
139
|
+
<span>FlatSQL</span>
|
|
140
|
+
<small>SQL-style queries over FlatBuffer-backed datasets and streams.</small>
|
|
141
|
+
</a>
|
|
142
|
+
<a href="https://spacedatanetwork.org/">
|
|
143
|
+
<span>SDN</span>
|
|
144
|
+
<small>Distributed publication, discovery, delivery, and marketplace infrastructure.</small>
|
|
145
|
+
</a>
|
|
146
|
+
<a href="https://digitalarsenal.github.io/space-data-module-sdk/" class="active">
|
|
147
|
+
<span>Module SDK</span>
|
|
148
|
+
<small>WASM module packaging, validation, and host compatibility tooling.</small>
|
|
149
|
+
</a>
|
|
150
|
+
</div>
|
|
151
|
+
</section>
|
|
152
|
+
<footer class="site-footer">
|
|
153
|
+
Space Data Module SDK — Apache-2.0. Every ABI page renders a Markdown
|
|
154
|
+
source in <code>docs/</code>; edit the Markdown, never the HTML.
|
|
155
|
+
</footer>
|
|
156
|
+
</body>
|
|
157
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Propulsion
|
|
2
|
+
|
|
3
|
+
**Status: PLANNED.** This family is a ratified entry in the harness-family
|
|
4
|
+
taxonomy. Its individual shape has not been ratified, and nothing is
|
|
5
|
+
implemented. This page states scope and status; it is not a contract, and it
|
|
6
|
+
does not imply parity with the Designed tier.
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
Model thrust production and propellant consumption: thruster performance, specific impulse, throttle and duty-cycle behavior, tank state and mass depletion over a burn. It supplies the maneuver family rather than replacing it — maneuver decides the burn, propulsion decides what the vehicle can actually deliver and what it costs in mass.
|
|
11
|
+
|
|
12
|
+
## What exists today
|
|
13
|
+
|
|
14
|
+
Nothing. No schema, no header, no module, no open design task.
|
|
15
|
+
|
|
16
|
+
Note that a propulsion contract is inseparable from a mass-properties contract: a thrust model that cannot report the mass it consumed is not usable by a propagator that integrates the resulting acceleration. Expect these to be ratified together.
|
|
17
|
+
|
|
18
|
+
## What ratification requires
|
|
19
|
+
|
|
20
|
+
A family reaches Designed when an ABI has been drafted against a real consumer,
|
|
21
|
+
and Shipped only when all of the following exist:
|
|
22
|
+
|
|
23
|
+
- A single `.fbs` schema as the source of the wire layout.
|
|
24
|
+
- A generated ABI header with size and offset locks, plus a drift gate that
|
|
25
|
+
fails when the schema and the committed header disagree.
|
|
26
|
+
- Declared units and frames per field, named sentinels, and named negative error
|
|
27
|
+
codes.
|
|
28
|
+
- A conformance kit carrying its own negative control, and a reference module.
|
|
29
|
+
- A stated tri-runtime parity envelope.
|
|
30
|
+
- Exactly one generic consumer port.
|
|
31
|
+
|
|
32
|
+
Until then, do not build against this family. If your work falls in this scope
|
|
33
|
+
and cannot wait, build a records-in, records-out module through the
|
|
34
|
+
[BYO-wasm quickstart](../byo-wasm-quickstart.html) — that path needs no harness
|
|
35
|
+
and is available now — and expect to migrate to the family ABI when it is
|
|
36
|
+
ratified.
|