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,209 @@
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: EXPERIMENTAL. A real maneuver module ships and a consumer-side seam" />
7
+ <title>Maneuver — 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" aria-current="page"><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>Maneuver</h1>
87
+ <p class="doc-meta"><span class="pill pill-experimental">experimental</span><span>Experimental. The shape exists in wave-2 form and is expected to change. Do not ship a commercial module against it yet.</span></p>
88
+ <p><strong>Status: EXPERIMENTAL.</strong> A real maneuver module ships and a consumer-side seam is frozen, but the WASM invoke surface itself is not frozen and carries known defects. Do not ship a commercial module against this family yet. Everything below describes what exists, and names precisely what does not.</p>
89
+ <h2 id="doctrine"><a class="anchor" href="#doctrine" aria-hidden="true">#</a>Doctrine</h2>
90
+ <p>A maneuver module answers one question: given a chaser state, an optional target state, and a maneuver intent, what burns achieve it and what does the resulting trajectory look like? It computes; it does not render, and it does not decide when a burn happens — that belongs to the scheduler and behavior families.</p>
91
+ <p>The family's defining discipline is that a computed maneuver is answered by the module or not at all. The consuming seam never falls back to arithmetic in JavaScript when the module declines; it returns an empty plan and a diagnostic. This is what makes a third-party maneuver module a real substitution rather than a decoration on a built-in solver.</p>
92
+ <h2 id="capability"><a class="anchor" href="#capability" aria-hidden="true">#</a>Capability</h2>
93
+ <p>A maneuver module may read the states it is given, compute impulsive or finite burns, and return a plan. It may not mutate scene state, may not fetch data, and may not schedule itself.</p>
94
+ <p>The conformance model pinned by the shipped seam is deliberately narrow: two-body point-mass Earth with impulsive burns, <code>mu = 3.986004418e14 m^3 s^-2</code> and <code>Re = 6378137 m</code>. A module offering higher fidelity is welcome, but it must answer these vectors within the seam's tolerance to be a drop-in.</p>
95
+ <h2 id="import-and-export-set"><a class="anchor" href="#import-and-export-set" aria-hidden="true">#</a>Import and export set</h2>
96
+ <p><strong>Not frozen.</strong> The shipped module uses the SDK's generic command invoke surface rather than a family-specific export set. A module declares <code>invoke surface: command</code> in its manifest and receives a JSON command envelope:</p>
97
+ <div class="codeblock"><div class="codeblock-head">json</div><pre><code>{ &quot;operation&quot;: &quot;&lt;name&gt;&quot;, &quot;params&quot;: { } }</code></pre></div>
98
+ <p>Structured JSON comes back, with an <code>errorCode</code> on every failure path. The manifest of the shipped module declares <code>acceptsAnyFlatbuffer: true</code>, justified as a foreign-wire-format wildcard port — that wildcard is exactly the thing a frozen ABI is supposed to remove.</p>
99
+ <p>There is no <code>orbpro_maneuver_abi.h</code>. There is no maneuver <code>.fbs</code> message ABI. The freeze of this surface is open work under the graph task <code>harness-w2-maneuver-invoke-freeze</code>.</p>
100
+ <h2 id="wire-layout"><a class="anchor" href="#wire-layout" aria-hidden="true">#</a>Wire layout</h2>
101
+ <p><strong>Not specified.</strong> The command envelope is JSON, not a byte-exact struct. The typed FlatBuffer runtime wire — delta-v nodes with a mandatory frame and named basis, signed doubles in metres per second, epoch-or-anchor timing — is designed but unminted; the SDS <code>$MVW</code> maneuver-plan record does not exist. Tracked by <code>harness-w3-maneuver-plan-record-mvw</code>.</p>
102
+ <p>Until that lands, treat the JSON envelope as an implementation detail that will be replaced, not as a contract.</p>
103
+ <h2 id="units-and-frames"><a class="anchor" href="#units-and-frames" aria-hidden="true">#</a>Units and frames</h2>
104
+ <p>SI end-to-end at the frozen consumer seam: metres, metres per second, seconds, radians. Frames must be named explicitly on every delta-v, and the reference module now does so unconditionally: every response carrying a delta-v emits a <code>frame</code> key, and there is no default to fall back on.</p>
105
+ <h3 id="the-canonical-ric-triad"><a class="anchor" href="#the-canonical-ric-triad" aria-hidden="true">#</a>The canonical RIC triad</h3>
106
+ <p>R = unit(r) C = unit(r x v) I = C x R</p>
107
+ <p>Built from the <strong>inertial</strong> state — never an Earth-fixed one — with components ordered <code>[radial, in-track, cross-track]</code>, SI metres per second, signed.</p>
108
+ <p>This is the ONE convention the family names. It is what <code>space-data-network-modules/analysis/maneuver/src/cpp/src/rendezvous.cpp</code> implements (<code>lvlhBasis()</code>) and what the engine's <code>OrbPro/packages/engine/Source/DataSources/ManeuverFrames.js</code> calls <code>ManeuverFrame.RIC</code>; those two already agreed, and this page is where the agreement is written down. A consuming seam MUST NOT infer the triad from a key spelling, and a producing module MUST NOT rely on a consumer's alias tolerance: alias key sets that exist on the consumer side are legacy tolerance, never a producer contract.</p>
109
+ <p>Lambert-family operations are the one place a different frame is correct: their velocities are stated in the same inertial frame as the <code>r1</code> / <code>r2</code> they were given, so they declare <code>frame: &quot;ECI&quot;</code> rather than <code>RIC</code>. Declared, not assumed — that distinction is the whole point.</p>
110
+ <p>The reference module also exposes the rotation itself, so a consumer never has to re-derive a triad: <code>transformDeltaV</code> takes <code>{position, velocity, deltaV, from: &quot;RIC&quot; | &quot;ECI&quot;}</code> and returns the rotated vector, the resulting frame name, and the basis. An unrecognised <code>from</code> is an <code>invalid-parameter</code> refusal; a purely radial state, which has no orbit normal and therefore no RIC frame, is <code>singular-configuration</code>.</p>
111
+ <p>Historically this was the family's worst defect: no frame was declared and none was applied — r/t/n components were written onto x/y/z raw while three distinct RTN triads were live across the stack (D1 in <code>graph/findings/official-harness-shapes.md</code>).</p>
112
+ <h2 id="sentinels"><a class="anchor" href="#sentinels" aria-hidden="true">#</a>Sentinels</h2>
113
+ <p>An unanswerable card returns an empty plan plus a diagnostic — never a zero burn, and never a silently substituted approximation. A zero-length plan is a refusal, not a no-op maneuver.</p>
114
+ <h2 id="identity"><a class="anchor" href="#identity" aria-hidden="true">#</a>Identity</h2>
115
+ <p>States are passed by value into the call. There is no persistent entity handle in this family today; a plan is addressed by the card kind and the seed it was produced from.</p>
116
+ <h2 id="threading"><a class="anchor" href="#threading" aria-hidden="true">#</a>Threading</h2>
117
+ <p><code>wasm32-wasip1-threads</code>, as for every family. The shipped module declares runtime targets browser, wasi and wasmedge. No batch or shard-write discipline is defined for this family yet, because no batch call exists.</p>
118
+ <h2 id="error-codes"><a class="anchor" href="#error-codes" aria-hidden="true">#</a>Error codes</h2>
119
+ <p><strong>Not frozen.</strong> The envelope returns an <code>errorCode</code> on failure paths, but the named code set is not ratified, and an audit found a dead error path in the shipped implementation. Do not depend on specific numeric values.</p>
120
+ <h2 id="lifetime"><a class="anchor" href="#lifetime" aria-hidden="true">#</a>Lifetime</h2>
121
+ <p>Command-surface modules are instantiated, invoked, and torn down by the host. Nothing in this family holds cross-call state today.</p>
122
+ <h2 id="parity-envelope"><a class="anchor" href="#parity-envelope" aria-hidden="true">#</a>Parity envelope</h2>
123
+ <p>The module builds for browser, wasi and wasmedge targets and is exercised by the project's own tests, but this family has no ratified parity envelope statement of its own. Run the generic <a href="../tri-runtime-parity-gate.html">tri-runtime parity gate</a> against any candidate.</p>
124
+ <h2 id="consumer-seam"><a class="anchor" href="#consumer-seam" aria-hidden="true">#</a>Consumer seam</h2>
125
+ <p>The consumer-side seam <strong>is</strong> frozen, and it is the most useful part of this family today. A solver is a pluggable port with two methods:</p>
126
+ <div class="codeblock"><div class="codeblock-head">ts</div><pre><code>plan(cardKind, seed, chaserState, targetState?): Node[]
127
+ reconcile(plan, simT): { liveElements, firedJobs }</code></pre></div>
128
+ <p>Card kinds: <code>pro</code>, <code>radial</code>, <code>normal</code>, <code>cislunar</code>, <code>custom</code>, <code>hohmann</code>, <code>hohplane</code>, <code>biel</code>, <code>lambert</code>, <code>phasing</code>, <code>rendezvous</code>.</p>
129
+ <p>The computed cards — <code>hohmann</code>, <code>hohplane</code>, <code>biel</code>, <code>phasing</code>, <code>lambert</code> — are answered by the module or not at all. The node-seed cards — <code>pro</code>, <code>radial</code>, <code>normal</code>, <code>custom</code> — have no module operation and are seeded directly.</p>
130
+ <h2 id="guest-c-example"><a class="anchor" href="#guest-c-example" aria-hidden="true">#</a>Guest C++ example</h2>
131
+ <p>There is no reference maneuver module in this SDK to derive a canonical example from, and publishing an invented one against an unfrozen surface would be worse than publishing none. Build against the <a href="./propagator.html">propagator guest example</a> for the module skeleton, threading model and teardown discipline, and treat the maneuver computation itself as command-envelope handling until the invoke freeze lands.</p>
132
+ <h2 id="known-defects-stated-plainly"><a class="anchor" href="#known-defects-stated-plainly" aria-hidden="true">#</a>Known defects, stated plainly</h2>
133
+ <p>The three defects that held this surface unfrozen are <strong>closed</strong> as of <code>maneuver-planner</code> 0.5.0 (<code>gmat-01-defect-burn-down</code>). Each is recorded here with what closed it and what proves it, because &quot;we fixed it&quot; without an assertion is how they came back the first time:</p>
134
+ <ul>
135
+ <li>~~A dead error path that cannot be reached.~~ <strong>Closed.</strong> Every refusal is a structured result carrying an <code>errorCode</code> and a message; <code>tests/error_path.test.mjs</code> drives malformed, hostile and impossible inputs and distinguishes &quot;returned a refusal&quot; from &quot;trapped&quot; — a helper that throws on a non-zero status cannot tell those apart, which is why that file invokes raw bytes.</li>
136
+ <li>~~Delta-v scalars that lose their sign.~~ <strong>Closed.</strong> Single-axis scalars are signed and equal the in-track component of their RIC array. <code>totalDeltaV</code> stays a magnitude because it is the propellant budget, and <code>combinedManeuver</code>'s <code>dv2</code> stays a magnitude because it is the norm of a two-component burn. The negative control is a GEO-to-LEO descent whose burns both brake; under 0.4.0 it was numerically indistinguishable from the ascent.</li>
137
+ <li>~~Lambert solutions that report a converged flag which is not true.~~ <strong>Closed.</strong> <code>converged</code> is a measured residual against a stated budget, not a literal; the root is bracketed and found by Newton safeguarded with bisection, so &quot;no solution&quot; is a reportable answer. A 72-geometry LEO sweep re-propagates every claimed departure velocity and measures the arrival miss, on browser and WasmEdge alike.</li>
138
+ </ul>
139
+ <p>Two gaps remain open and are NOT closed by the above:</p>
140
+ <ul>
141
+ <li><strong>No independent-solver cross-check runs yet.</strong> The intended reference, <code>space-data-network-modules/analysis/lambert-izzo</code> (Izzo's revisited algorithm, Householder), exits with WASI code 1 on every <code>solve_lambert</code> invoke — that package ships manifest tests only and has never had a functional invoke test. The cross-check is written and armed in <code>analysis/maneuver/tests/lambert_izzo_crosscheck.test.mjs</code>; it SKIPS with that diagnosis rather than voting, and turns on by itself once the reference artifact answers.</li>
142
+ <li><strong>The <code>$MVW</code> record is not minted</strong>, so delta-v still travels as the reviewed JSON envelope rather than a typed wire.</li>
143
+ </ul>
144
+ <p>The seam contract publication, the invoke freeze, and the <code>$MVW</code> record mint remain the three gates between this page and a Shipped status (<code>harness-w2-maneuver-invoke-freeze</code>).</p>
145
+ <section class="playground" id="playground-slot" data-family="maneuver" data-playground="pending" aria-labelledby="playground-title">
146
+ <h2 id="playground-title">Playground</h2>
147
+ <p>
148
+ An in-browser build-and-run playground for the <code>maneuver</code> harness
149
+ mounts here. It is being built under the graph task
150
+ <code>sdk-playground-emception</code>; this slot is its reserved mount
151
+ point and is intentionally empty until that lands.
152
+ </p>
153
+ </section>
154
+ <p class="doc-footer">
155
+ Source of truth for this page:
156
+ <code>docs/families/maneuver.md</code>. Regenerate with
157
+ <code>npm run build:docs</code>.
158
+ </p>
159
+ </main>
160
+ <nav class="rail" aria-label="On this page"><h2>On this page</h2><ul><li><a class="depth-2" href="#doctrine">Doctrine</a></li>
161
+ <li><a class="depth-2" href="#capability">Capability</a></li>
162
+ <li><a class="depth-2" href="#import-and-export-set">Import and export set</a></li>
163
+ <li><a class="depth-2" href="#wire-layout">Wire layout</a></li>
164
+ <li><a class="depth-2" href="#units-and-frames">Units and frames</a></li>
165
+ <li><a class="depth-3" href="#the-canonical-ric-triad">The canonical RIC triad</a></li>
166
+ <li><a class="depth-2" href="#sentinels">Sentinels</a></li>
167
+ <li><a class="depth-2" href="#identity">Identity</a></li>
168
+ <li><a class="depth-2" href="#threading">Threading</a></li>
169
+ <li><a class="depth-2" href="#error-codes">Error codes</a></li>
170
+ <li><a class="depth-2" href="#lifetime">Lifetime</a></li>
171
+ <li><a class="depth-2" href="#parity-envelope">Parity envelope</a></li>
172
+ <li><a class="depth-2" href="#consumer-seam">Consumer seam</a></li>
173
+ <li><a class="depth-2" href="#guest-c-example">Guest C++ example</a></li>
174
+ <li><a class="depth-2" href="#known-defects-stated-plainly">Known defects, stated plainly</a></li></ul></nav>
175
+ </div>
176
+ <section id="stack" class="section" aria-labelledby="stack-title">
177
+ <div class="section-head">
178
+ <p class="eyebrow">SDN Stack</p>
179
+ <h2 id="stack-title">Connected sites</h2>
180
+ </div>
181
+ <div class="link-list">
182
+ <a href="https://spacedatastandards.org/">
183
+ <span>Standards</span>
184
+ <small>Canonical schemas, record contracts, and generated bindings.</small>
185
+ </a>
186
+ <a href="https://digitalarsenal.github.io/flatbuffers/">
187
+ <span>FlatBuffers</span>
188
+ <small>Binary encoding, schema tooling, and runtime documentation.</small>
189
+ </a>
190
+ <a href="https://digitalarsenal.github.io/flatsql/">
191
+ <span>FlatSQL</span>
192
+ <small>SQL-style queries over FlatBuffer-backed datasets and streams.</small>
193
+ </a>
194
+ <a href="https://spacedatanetwork.org/">
195
+ <span>SDN</span>
196
+ <small>Distributed publication, discovery, delivery, and marketplace infrastructure.</small>
197
+ </a>
198
+ <a href="https://digitalarsenal.github.io/space-data-module-sdk/" class="active">
199
+ <span>Module SDK</span>
200
+ <small>WASM module packaging, validation, and host compatibility tooling.</small>
201
+ </a>
202
+ </div>
203
+ </section>
204
+ <footer class="site-footer">
205
+ Space Data Module SDK — Apache-2.0. Every ABI page renders a Markdown
206
+ source in <code>docs/</code>; edit the Markdown, never the HTML.
207
+ </footer>
208
+ </body>
209
+ </html>
@@ -0,0 +1,206 @@
1
+ # Maneuver
2
+
3
+ **Status: EXPERIMENTAL.** A real maneuver module ships and a consumer-side seam
4
+ is frozen, but the WASM invoke surface itself is not frozen and carries known
5
+ defects. Do not ship a commercial module against this family yet. Everything
6
+ below describes what exists, and names precisely what does not.
7
+
8
+ ## Doctrine
9
+
10
+ A maneuver module answers one question: given a chaser state, an optional target
11
+ state, and a maneuver intent, what burns achieve it and what does the resulting
12
+ trajectory look like? It computes; it does not render, and it does not decide
13
+ when a burn happens — that belongs to the scheduler and behavior families.
14
+
15
+ The family's defining discipline is that a computed maneuver is answered by the
16
+ module or not at all. The consuming seam never falls back to arithmetic in
17
+ JavaScript when the module declines; it returns an empty plan and a diagnostic.
18
+ This is what makes a third-party maneuver module a real substitution rather than
19
+ a decoration on a built-in solver.
20
+
21
+ ## Capability
22
+
23
+ A maneuver module may read the states it is given, compute impulsive or finite
24
+ burns, and return a plan. It may not mutate scene state, may not fetch data, and
25
+ may not schedule itself.
26
+
27
+ The conformance model pinned by the shipped seam is deliberately narrow:
28
+ two-body point-mass Earth with impulsive burns, `mu = 3.986004418e14 m^3 s^-2`
29
+ and `Re = 6378137 m`. A module offering higher fidelity is welcome, but it must
30
+ answer these vectors within the seam's tolerance to be a drop-in.
31
+
32
+ ## Import and export set
33
+
34
+ **Not frozen.** The shipped module uses the SDK's generic command invoke
35
+ surface rather than a family-specific export set. A module declares
36
+ `invoke surface: command` in its manifest and receives a JSON command envelope:
37
+
38
+ ```json
39
+ { "operation": "<name>", "params": { } }
40
+ ```
41
+
42
+ Structured JSON comes back, with an `errorCode` on every failure path. The
43
+ manifest of the shipped module declares `acceptsAnyFlatbuffer: true`, justified
44
+ as a foreign-wire-format wildcard port — that wildcard is exactly the thing a
45
+ frozen ABI is supposed to remove.
46
+
47
+ There is no `orbpro_maneuver_abi.h`. There is no maneuver `.fbs` message ABI.
48
+ The freeze of this surface is open work under the graph task
49
+ `harness-w2-maneuver-invoke-freeze`.
50
+
51
+ ## Wire layout
52
+
53
+ **Not specified.** The command envelope is JSON, not a byte-exact struct. The
54
+ typed FlatBuffer runtime wire — delta-v nodes with a mandatory frame and named
55
+ basis, signed doubles in metres per second, epoch-or-anchor timing — is designed
56
+ but unminted; the SDS `$MVW` maneuver-plan record does not exist. Tracked by
57
+ `harness-w3-maneuver-plan-record-mvw`.
58
+
59
+ Until that lands, treat the JSON envelope as an implementation detail that will
60
+ be replaced, not as a contract.
61
+
62
+ ## Units and frames
63
+
64
+ SI end-to-end at the frozen consumer seam: metres, metres per second, seconds,
65
+ radians. Frames must be named explicitly on every delta-v, and the reference
66
+ module now does so unconditionally: every response carrying a delta-v emits a
67
+ `frame` key, and there is no default to fall back on.
68
+
69
+ ### The canonical RIC triad
70
+
71
+ R = unit(r) C = unit(r x v) I = C x R
72
+
73
+ Built from the **inertial** state — never an Earth-fixed one — with components
74
+ ordered `[radial, in-track, cross-track]`, SI metres per second, signed.
75
+
76
+ This is the ONE convention the family names. It is what
77
+ `space-data-network-modules/analysis/maneuver/src/cpp/src/rendezvous.cpp`
78
+ implements (`lvlhBasis()`) and what the engine's
79
+ `OrbPro/packages/engine/Source/DataSources/ManeuverFrames.js` calls
80
+ `ManeuverFrame.RIC`; those two already agreed, and this page is where the
81
+ agreement is written down. A consuming seam MUST NOT infer the triad from a
82
+ key spelling, and a producing module MUST NOT rely on a consumer's alias
83
+ tolerance: alias key sets that exist on the consumer side are legacy
84
+ tolerance, never a producer contract.
85
+
86
+ Lambert-family operations are the one place a different frame is correct: their
87
+ velocities are stated in the same inertial frame as the `r1` / `r2` they were
88
+ given, so they declare `frame: "ECI"` rather than `RIC`. Declared, not assumed
89
+ — that distinction is the whole point.
90
+
91
+ The reference module also exposes the rotation itself, so a consumer never has
92
+ to re-derive a triad: `transformDeltaV` takes
93
+ `{position, velocity, deltaV, from: "RIC" | "ECI"}` and returns the rotated
94
+ vector, the resulting frame name, and the basis. An unrecognised `from` is an
95
+ `invalid-parameter` refusal; a purely radial state, which has no orbit normal
96
+ and therefore no RIC frame, is `singular-configuration`.
97
+
98
+ Historically this was the family's worst defect: no frame was declared and none
99
+ was applied — r/t/n components were written onto x/y/z raw while three distinct
100
+ RTN triads were live across the stack (D1 in
101
+ `graph/findings/official-harness-shapes.md`).
102
+
103
+ ## Sentinels
104
+
105
+ An unanswerable card returns an empty plan plus a diagnostic — never a zero
106
+ burn, and never a silently substituted approximation. A zero-length plan is a
107
+ refusal, not a no-op maneuver.
108
+
109
+ ## Identity
110
+
111
+ States are passed by value into the call. There is no persistent entity handle
112
+ in this family today; a plan is addressed by the card kind and the seed it was
113
+ produced from.
114
+
115
+ ## Threading
116
+
117
+ `wasm32-wasip1-threads`, as for every family. The shipped module declares
118
+ runtime targets browser, wasi and wasmedge. No batch or shard-write discipline
119
+ is defined for this family yet, because no batch call exists.
120
+
121
+ ## Error codes
122
+
123
+ **Not frozen.** The envelope returns an `errorCode` on failure paths, but the
124
+ named code set is not ratified, and an audit found a dead error path in the
125
+ shipped implementation. Do not depend on specific numeric values.
126
+
127
+ ## Lifetime
128
+
129
+ Command-surface modules are instantiated, invoked, and torn down by the host.
130
+ Nothing in this family holds cross-call state today.
131
+
132
+ ## Parity envelope
133
+
134
+ The module builds for browser, wasi and wasmedge targets and is exercised by the
135
+ project's own tests, but this family has no ratified parity envelope statement
136
+ of its own. Run the generic
137
+ [tri-runtime parity gate](../tri-runtime-parity-gate.html) against any candidate.
138
+
139
+ ## Consumer seam
140
+
141
+ The consumer-side seam **is** frozen, and it is the most useful part of this
142
+ family today. A solver is a pluggable port with two methods:
143
+
144
+ ```ts
145
+ plan(cardKind, seed, chaserState, targetState?): Node[]
146
+ reconcile(plan, simT): { liveElements, firedJobs }
147
+ ```
148
+
149
+ Card kinds: `pro`, `radial`, `normal`, `cislunar`, `custom`, `hohmann`,
150
+ `hohplane`, `biel`, `lambert`, `phasing`, `rendezvous`.
151
+
152
+ The computed cards — `hohmann`, `hohplane`, `biel`, `phasing`, `lambert` — are
153
+ answered by the module or not at all. The node-seed cards — `pro`, `radial`,
154
+ `normal`, `custom` — have no module operation and are seeded directly.
155
+
156
+ ## Guest C++ example
157
+
158
+ There is no reference maneuver module in this SDK to derive a canonical example
159
+ from, and publishing an invented one against an unfrozen surface would be worse
160
+ than publishing none. Build against the
161
+ [propagator guest example](propagator.html) for the module skeleton, threading
162
+ model and teardown discipline, and treat the maneuver computation itself as
163
+ command-envelope handling until the invoke freeze lands.
164
+
165
+ ## Known defects, stated plainly
166
+
167
+ The three defects that held this surface unfrozen are **closed** as of
168
+ `maneuver-planner` 0.5.0 (`gmat-01-defect-burn-down`). Each is recorded here
169
+ with what closed it and what proves it, because "we fixed it" without an
170
+ assertion is how they came back the first time:
171
+
172
+ - ~~A dead error path that cannot be reached.~~ **Closed.** Every refusal is a
173
+ structured result carrying an `errorCode` and a message; `tests/error_path.test.mjs`
174
+ drives malformed, hostile and impossible inputs and distinguishes "returned a
175
+ refusal" from "trapped" — a helper that throws on a non-zero status cannot
176
+ tell those apart, which is why that file invokes raw bytes.
177
+ - ~~Delta-v scalars that lose their sign.~~ **Closed.** Single-axis scalars are
178
+ signed and equal the in-track component of their RIC array. `totalDeltaV`
179
+ stays a magnitude because it is the propellant budget, and
180
+ `combinedManeuver`'s `dv2` stays a magnitude because it is the norm of a
181
+ two-component burn. The negative control is a GEO-to-LEO descent whose burns
182
+ both brake; under 0.4.0 it was numerically indistinguishable from the
183
+ ascent.
184
+ - ~~Lambert solutions that report a converged flag which is not true.~~
185
+ **Closed.** `converged` is a measured residual against a stated budget, not a
186
+ literal; the root is bracketed and found by Newton safeguarded with
187
+ bisection, so "no solution" is a reportable answer. A 72-geometry LEO sweep
188
+ re-propagates every claimed departure velocity and measures the arrival miss,
189
+ on browser and WasmEdge alike.
190
+
191
+ Two gaps remain open and are NOT closed by the above:
192
+
193
+ - **No independent-solver cross-check runs yet.** The intended reference,
194
+ `space-data-network-modules/analysis/lambert-izzo` (Izzo's revisited
195
+ algorithm, Householder), exits with WASI code 1 on every `solve_lambert`
196
+ invoke — that package ships manifest tests only and has never had a
197
+ functional invoke test. The cross-check is written and armed in
198
+ `analysis/maneuver/tests/lambert_izzo_crosscheck.test.mjs`; it SKIPS with
199
+ that diagnosis rather than voting, and turns on by itself once the reference
200
+ artifact answers.
201
+ - **The `$MVW` record is not minted**, so delta-v still travels as the reviewed
202
+ JSON envelope rather than a typed wire.
203
+
204
+ The seam contract publication, the invoke freeze, and the `$MVW` record mint
205
+ remain the three gates between this page and a Shipped status
206
+ (`harness-w2-maneuver-invoke-freeze`).