space-data-module-sdk 0.8.16 → 0.8.17

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 (63) hide show
  1. package/bin/space-data-module.js +24 -6
  2. package/docs/browser-wasmedge-isomorphic.html +1 -1
  3. package/docs/byo-wasm-quickstart.html +1 -1
  4. package/docs/conformance.html +10 -4
  5. package/docs/conformance.md +20 -4
  6. package/docs/events-abi.html +1 -1
  7. package/docs/families/analytics.html +1 -1
  8. package/docs/families/attitude.html +1 -1
  9. package/docs/families/behavior.html +1 -1
  10. package/docs/families/breakup.html +1 -1
  11. package/docs/families/conjunction.html +1 -1
  12. package/docs/families/data-source.html +7 -2
  13. package/docs/families/effects.html +1 -1
  14. package/docs/families/environment.html +1 -1
  15. package/docs/families/estimation.html +56 -54
  16. package/docs/families/estimation.md +155 -125
  17. package/docs/families/gnc.html +1 -1
  18. package/docs/families/maneuver.html +1 -1
  19. package/docs/families/obstruction.html +1 -1
  20. package/docs/families/propagator.html +16 -2
  21. package/docs/families/propulsion.html +1 -1
  22. package/docs/families/reentry.html +1 -1
  23. package/docs/families/rf.html +1 -1
  24. package/docs/families/scheduler.html +1 -1
  25. package/docs/families/sensor.html +1 -1
  26. package/docs/families/signature.html +1 -1
  27. package/docs/flatsql-host-contract.html +1 -1
  28. package/docs/flatsql-streaming-standard.html +1 -1
  29. package/docs/gpu-module-abi.html +1 -1
  30. package/docs/harness-family-matrix.md +7 -7
  31. package/docs/index.html +2 -2
  32. package/docs/isomorphic-pthreads.html +1 -1
  33. package/docs/isomorphic-sdn-runtime-plan.html +1 -1
  34. package/docs/language-runtime-matrix.html +1 -1
  35. package/docs/llms.txt +1 -1
  36. package/docs/module-bundle-runtime-plan.html +1 -1
  37. package/docs/module-publication-standard.html +1 -1
  38. package/docs/node-red-default-node-parity.html +1 -1
  39. package/docs/propagator-abi.md +52 -0
  40. package/docs/protect-and-sign.html +1 -1
  41. package/docs/protocol-installation.html +1 -1
  42. package/docs/provider-access-abi.md +25 -0
  43. package/docs/publication-submission.html +1 -1
  44. package/docs/secrets-capability.html +1 -1
  45. package/docs/testing-harness.html +1 -1
  46. package/docs/tri-runtime-parity-gate.html +1 -1
  47. package/docs/tri-runtime-parity.html +1 -1
  48. package/include/orbpro/orbpro_estimation_abi.h +883 -0
  49. package/include/orbpro/orbpro_propagator_abi.h +58 -0
  50. package/package.json +4 -2
  51. package/schemas/orbpro/Estimation.fbs +244 -0
  52. package/schemas/orbpro/Propagator.fbs +64 -0
  53. package/src/conformance/estimationReference.js +81 -0
  54. package/src/conformance/estimationSuite.js +134 -0
  55. package/src/conformance/index.js +39 -2
  56. package/src/generated/orbpro/propagator-abi.js +21 -0
  57. package/src/generated/orbpro/propagator-abi.ts +50 -0
  58. package/src/standards/sharedCatalog.js +7 -0
  59. package/templates/estimation-module/README.md +24 -0
  60. package/templates/estimation-module/build.mjs +32 -0
  61. package/templates/estimation-module/package.json +12 -0
  62. package/templates/estimation-module/plugin-manifest.json +34 -0
  63. package/templates/estimation-module/src/reference_estimation.cpp +53 -0
@@ -1,128 +1,158 @@
1
1
  # Estimation
2
2
 
3
- **Status: EXPERIMENTAL.** A production orbit-determination module is shipped and
4
- running, but it is not a ratified harness: it has no generated ABI header, no
5
- conformance kit, and no reference module in the harness sense. The broader
6
- estimation surface that its headers describe is largely not wired into the
7
- shipped path.
8
-
9
- ## Doctrine
10
-
11
- An estimation module turns observations into state. Observations and an initial
12
- guess go in; an estimated state, and where the family matures, a covariance,
13
- come out. It is the inverse of the propagator family, and it depends on that
14
- family: an estimator that cannot take its propagator as a pluggable port is
15
- hardwired to one force model and is not a member of this family.
16
-
17
- The pluggable-propagation law applies here with full force. Every
18
- propagator-consuming surface — an estimator emphatically included — takes the
19
- propagator as a parameter or port, never as a compiled-in choice.
20
-
21
- ## Capability
22
-
23
- Ingest observations, fit a state, emit results as standards records. The shipped
24
- path emits `$OMM`-class mean-element results and `$OBD` observation-derived
25
- records. Input ephemerides are transient by rule: they are fitted and discarded,
26
- and only the results are stored.
27
-
28
- ## Import and export set
29
-
30
- **Not specified as a harness ABI.** No `orbpro_od_abi.h` or equivalent
31
- generated header exists. The shipped module is invoked through the SDK's generic
32
- module surface, not through a family-specific export set.
33
-
34
- In the manifest vocabulary the family projects onto
35
- `PluginFamily.ORBIT_DETERMINATION`, which itself carries a known projection gap:
36
- Space Data Standards has no dedicated plugin-category member for it yet, so it
37
- projects onto the analysis category until one is minted.
38
-
39
- ## Wire layout
40
-
41
- **Not specified as a public wire.** The internal C++ types describe the intended
42
- shape and are useful as a design reference, but they are not a published ABI and
43
- their layout is not locked:
44
-
45
- | Type | Fields |
3
+ **Status: RATIFIED.** The estimation harness is the measurement-based orbit
4
+ determination contract. It covers simulation, batch weighted least squares,
5
+ sequential filtering, smoothing, process noise, media corrections, and initial
6
+ orbit determination without selecting a propagator implementation.
7
+
8
+ ## Result-model ruling
9
+
10
+ The result-model decision previously deferred by this family is final:
11
+
12
+ - `$ODR` is the canonical signed run report. It carries the solver
13
+ configuration, iteration and editing ledgers, estimated parameters, filter
14
+ history, residual statistics, and the estimated Cartesian state.
15
+ - `$OCM` is the canonical covariance product named by `ODR.OCM_CONTENT_ID`.
16
+ Its covariance values are the estimator's computed values; a diagonal
17
+ placeholder or an `N/A` solve-for is non-conforming.
18
+ - `Estimation.fbs` is the family request/result wire. It may embed the exact
19
+ `$ODR` and `$OCM` bytes for a one-frame invocation result, but it does not
20
+ replace either standards record.
21
+ - `$MEM`, `$TRH`, and `$TDM` are supporting input records: measurement error
22
+ and editing policy, tracking hardware, and observations respectively.
23
+
24
+ This split keeps algorithm telemetry out of a covariance interchange record
25
+ while still giving every reported covariance one immutable run provenance.
26
+
27
+ ## Propagator port
28
+
29
+ The caller supplies `propagator_port_id` and `propagator_capability`. The
30
+ estimator consumes `EstimationPropagatorSample` values whose states come from
31
+ `plugin_propagate` and whose state-transition matrices come from
32
+ `plugin_compute_stm`. The STM maps the a-priori epoch to the sample epoch.
33
+
34
+ Provider names, provider enums, and a default provider are absent from this
35
+ family. A host must reject a request whose named port does not provide both
36
+ capabilities. An estimator that imports or selects a concrete propagator is not
37
+ an estimation-family module.
38
+
39
+ ## Source of truth and generated header
40
+
41
+ `schemas/orbpro/Estimation.fbs` is the single layout source.
42
+ `include/orbpro/orbpro_estimation_abi.h` is generated from it by the SDK's
43
+ schema ABI renderer. Its compile-time size and offset assertions are part of
44
+ conformance; handwritten copies are not.
45
+
46
+ All state components use metres and metres per second. Covariance is row-major
47
+ 6 by 6 in matching SI units. Observation values use their native SI unit:
48
+ metres, metres per second, hertz, or radians. Epochs use the two-double Julian
49
+ day representation shared by the propagator family.
50
+
51
+ Angular and local-plane observations carry the station's inertial east,
52
+ north and up unit vectors alongside its inertial position and velocity. A
53
+ runtime uses that explicit topocentric basis when it is present; deriving
54
+ latitude and longitude from an inertial position rotates the local frame twice
55
+ and is non-conformant.
56
+
57
+ The fixed layouts are:
58
+
59
+ | Type | Bytes | Alignment |
60
+ | --- | ---: | ---: |
61
+ | `OrbProEstimationEpoch` | 16 | 8 |
62
+ | `OrbProEstimationObservation` | 376 | 8 |
63
+ | `OrbProEstimationErrorModel` | 72 | 8 |
64
+ | `OrbProEstimationConfig` | 448 | 8 |
65
+ | `OrbProEstimationState` | 384 | 8 |
66
+ | `OrbProFilterEpoch` | 696 | 8 |
67
+ | `OrbProEstimationPropagatorSample` | 352 | 8 |
68
+ | `OrbProInitialOrbitRequest` | 240 | 8 |
69
+ | `OrbProInitialOrbitResult` | 80 | 8 |
70
+
71
+ Call each generated `_init` helper before filling a struct. Padding is
72
+ contractual and must remain zero so browser, native, and WasmEdge runtimes hash
73
+ the same bytes.
74
+
75
+ ## Measurement and estimator roster
76
+
77
+ The measurement roster contains range, range rate and Doppler; azimuth and
78
+ elevation; XEast/YNorth and XSouth/YEast; right ascension and declination;
79
+ position vectors; sequential and pseudonoise range; time-correlated phase;
80
+ relay range, Doppler and differenced Doppler; bistatic, skin and crosslink
81
+ range/range rate; laser range; TDOA; and FDOA.
82
+
83
+ `EstimatorKind` distinguishes batch weighted least squares, a covariance-form
84
+ extended Kalman filter, a sigma-point unscented Kalman filter, and EKF with
85
+ Rauch–Tung–Striebel smoothing. Chaining one-observation batch solves is not an
86
+ EKF or UKF and fails conformance. SNC and DMC are explicit process-noise kinds.
87
+
88
+ The initial-orbit entry point exposes Gauss, Laplace, Gibbs, and
89
+ Herrick–Gibbs. It returns the middle-epoch Cartesian state and a typed status.
90
+
91
+ ## Result and error contract
92
+
93
+ Successful estimation produces a populated `OrbProEstimationState`. A batch
94
+ result includes convergence, iteration, accepted and rejected counts, RMS,
95
+ recovered noise sigma, and covariance. A sequential result includes every
96
+ filtered covariance and, for the smoother kind, every smoothed covariance.
97
+
98
+ Batch result wires also carry `iteration_covariances` as consecutive row-major
99
+ 6-by-6 blocks. Each block is the normal-matrix covariance from that exact
100
+ outer iteration, so a convergence visualization uses solver output rather
101
+ than an interpolated uncertainty.
102
+
103
+ The public status vocabulary is:
104
+
105
+ | Status | Meaning |
46
106
  | --- | --- |
47
- | `StateVector` | `epoch_jd`, `x`, `y`, `z`, `vx`, `vy`, `vz` |
48
- | `Observation` | `epoch_jd`, `type`, `value`, `sigma`, `station_id` |
49
- | `GroundStation` | `id`, `name`, `lat_deg`, `lon_deg`, `alt_km` |
50
- | `Covariance6x6` | 6×6 array of doubles |
51
-
52
- `ObservationType` covers right ascension, declination, azimuth, elevation,
53
- range, range rate, and position components.
54
-
55
- The SDS `$ODW` problem record and its runtime wire are unminted; `$OBD` remains
56
- the results record. By explicit ruling, the OD *result model* decision stays
57
- deferred — a future record mint covers the problem and wire side only and must
58
- not freeze the result model.
59
-
60
- ## Units and frames
61
-
62
- The internal types mix conventions and this is a real hazard: epochs are Julian
63
- dates, station geodetic position is in degrees with altitude in kilometres, and
64
- state components are in the propagator family's units. Any published estimation
65
- ABI must state the unit of every field at the field, exactly as the propagator
66
- ABI does. Until it does, read the module's own headers rather than assuming.
67
-
68
- ## Sentinels
69
-
70
- Not specified. The shipped path treats a failed fit as a refusal and does not
71
- emit a record; there is no ratified sentinel vocabulary for a partially
72
- converged solution.
73
-
74
- ## Identity
75
-
76
- Objects are addressed by their catalog identity in the shipped path — the same
77
- identity the propagator family uses for an entity.
78
-
79
- ## Threading
80
-
81
- `wasm32-wasip1-threads`. The shipped fit path is genuinely multi-threaded and
82
- runs a full catalog fit inside one composed WASM flow; that is the strongest
83
- evidence in this family that the threading model is sound. No harness-level
84
- shard-write discipline is specified because no batch ABI is published.
85
-
86
- ## Error codes
87
-
88
- Not specified as a named set.
89
-
90
- ## Lifetime
91
-
92
- The shipped module is instantiated once per flow run and torn down with it.
93
-
94
- ## Parity envelope
95
-
96
- Cross-runtime parity is exercised for the shipped flow, but the family has no
97
- parity envelope statement of its own. Use the generic
98
- [parity gate](../tri-runtime-parity-gate.html).
99
-
100
- ## Consumer seam
101
-
102
- The seam that matters is the propagator port. An estimation module accepts a
103
- propagator plugin and calls it; the consumer chooses which propagator is
104
- supplied. Any estimation module that internally hardwires a single propagator is
105
- non-conforming by the pluggable-propagation law, regardless of how good its
106
- filter is.
107
-
108
- ## Guest C++ example
109
-
110
- None published. Publishing a skeleton against an unratified ABI would invite
111
- exactly the drift this family needs to avoid. Start from the
112
- [propagator guest example](propagator.html) for module structure, and consume the
113
- propagator through its published ABI from inside your estimator.
114
-
115
- ## Known gaps, stated plainly
116
-
117
- - The shipped production path is SGP4 mean-element batch fitting. That is what
118
- runs.
119
- - The wider surface described in the module's own headers — Gauss, Laplace,
120
- double-r, Gibbs and Herrick-Gibbs initial orbit determination; sequential EKF
121
- and UKF; 6×6 covariance with consider parameters and state-transition-matrix
122
- propagation — is compiled but audited as dead code, reachable only from a test
123
- path and never called by the production entry points. Treat it as design
124
- intent, not as available capability.
125
- - The abstract propagator interface inside that module is part of the same dead
126
- path. The pluggable-propagation law is satisfied by design in the header and
127
- not yet exercised in the shipped flow.
128
- - No conformance kit, no generated header, no negative control.
107
+ | `ORBPRO_ESTIMATION_OK` | Result is complete. |
108
+ | `ORBPRO_ESTIMATION_NOT_CONFIGURED` | Required family or propagator configuration is absent. |
109
+ | `ORBPRO_ESTIMATION_NULL_OUTPUT` | Caller supplied no result destination. |
110
+ | `ORBPRO_ESTIMATION_BAD_INPUT` | Shape, unit, enum, sigma, or covariance validation failed. |
111
+ | `ORBPRO_ESTIMATION_NOT_CONVERGED` | A valid iteration history exists but the declared convergence criteria were not met. |
112
+ | `ORBPRO_ESTIMATION_BUFFER_TOO_SMALL` | Output storage cannot hold the declared result. |
113
+ | `ORBPRO_ESTIMATION_PROPAGATOR_PROTOCOL` | State/STM response does not match the request. |
114
+ | `ORBPRO_ESTIMATION_INTERNAL` | Numerical or invariant failure not attributable to input. |
115
+
116
+ No sentinel means success. NaN, an invalid covariance, or a missing required
117
+ record is an error. A non-converged batch may be reported only with
118
+ `NOT_CONVERGED` and its actual iteration history; it may not be relabelled OK.
119
+
120
+ ## Lifetime and threading
121
+
122
+ Request, sample, and result buffers are invocation-owned and remain valid only
123
+ for the call. Modules copy any state retained between input frames. Family
124
+ implementations declare their thread model in `$PLG`; deterministic
125
+ six-dimensional sequential implementations may use `wasi-sequential` while
126
+ still compiling on the sanctioned `wasm32-wasip1-threads` toolchain. The same
127
+ artifact and bytes must pass browser, native, and embedded WasmEdge lanes.
128
+
129
+ ## Conformance kit
130
+
131
+ The official kit checks:
132
+
133
+ 1. generated ABI sizes, offsets, enum values, zeroed padding, and an
134
+ Estimation.fbs schema-lock regeneration;
135
+ 2. a positive reference module using caller-supplied state and STM samples;
136
+ 3. a negative provider-selection control, which fails if a provider name or a
137
+ concrete propagator import is introduced;
138
+ 4. batch state, covariance, RMS, recovered sigma, and exact edited-set vectors;
139
+ 5. real EKF and UKF covariance histories, RTS covariance contraction, and
140
+ SNC/DMC growth;
141
+ 6. the complete measurement roster, light-time and body-rotation corrections,
142
+ media corrections, hardware delay and turnaround handling;
143
+ 7. deterministic simulation and the four initial-orbit methods; and
144
+ 8. byte-equivalent results in the browser, native, and WasmEdge lanes.
145
+
146
+ The kit's reference module is deliberately force-model blind: its propagator
147
+ fixture arrives through the same required `propagator_samples` port as a real
148
+ provider. Replacing that fixture with a compiled-in trajectory is a failing
149
+ negative control, not a reference implementation.
150
+
151
+ ## Manifest surface
152
+
153
+ An estimation module declares the `estimation` harness family and exposes
154
+ `run_estimation`, `simulate_tracking`, and `initial_orbit`. `run_estimation`
155
+ requires `request` and `propagator_samples`; `$TDM`, `$MEM`, and `$TRH` are
156
+ optional typed ports. It emits the Estimation result wire plus signed `$ODR`
157
+ and `$OCM` records. Signatures are applied by the caller's keyslot capability;
158
+ private signing material never appears in the estimation module.
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -109,6 +109,19 @@
109
109
  <h3 id="typed-ingest"><a class="anchor" href="#typed-ingest" aria-hidden="true">#</a>Typed ingest</h3>
110
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
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="ephemeris-ingest"><a class="anchor" href="#ephemeris-ingest" aria-hidden="true">#</a>Ephemeris ingest</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_init_ephemeris</code></td><td><code>int32_t(const uint8_t* bytes, size_t len, uint32_t format)</code></td><td>entities initialized (&gt;0), or a negative <a href="#error-codes">error code</a></td></tr></tbody></table></div>
114
+ <p><code>format</code> is an <code>OrbProEphemerisFormat</code> member (<code>AUTO</code> = identify from the bytes). This is the ONLY legal door for an ephemeris container. It exists because <code>plugin_init</code> is bound to packed <code>OrbProOMMRecord</code> and MUST refuse a length that is not a whole multiple of that struct — so a DAF, a Code-500 record stream or an STK <code>.e</code> body has no entry point through it, and passing one anyway is a size-lock violation dressed as an ingest. Do not smuggle ephemeris bytes through <code>plugin_init</code> as fake OMM records.</p>
115
+ <p>An ephemeris provider is a propagator like any other. It exports <code>plugin_init_ephemeris</code> INSTEAD of the OMM/element ingest verbs, and is otherwise held to every rule on this page: <code>plugin_propagate</code> and <code>plugin_propagate_batch</code> agree exactly, output is <strong>ECEF metres</strong> (§<a href="#frames">Frames</a>), padding bytes are zero, <code>plugin_destroy</code> really releases, and every failure carries its own code. The consumer seam does not change — the host still resolves it by name and drives it through <code>PropagatedPositionProperty</code>.</p>
116
+ <p>Three obligations are specific to this verb:</p>
117
+ <ul>
118
+ <li><strong>The frame is DECLARED, and this is the one family that may exit non-ECEF.</strong> Every other provider outputs ECEF because it computes in a frame of its own choosing and the host cannot know which. An ephemeris container is different: it states its frame outright (a <code>REF_FRAME</code> keyword, a DAF frame code, an STK <code>CoordinateSystem</code>, SP3's terrestrial frame), and rotating a J2000 kernel to ECEF so the consumer can rotate it straight back is two interpolated rotations added to an answer that was already exact. So an ephemeris provider emits the container's own frame and SAYS SO in <code>StateVector.reference_frame</code>, set through <code>orbpro_state_set_reference_frame()</code> — never by assigning the field, which leaves the padding bytes stale.</li>
119
+ </ul>
120
+ <p>The frame it names must be a member of the ABI's own <code>ReferenceFrame</code> roster, translated by NAMED TOKEN. A native frame integer never crosses this seam: five incompatible <code>ReferenceFrame</code> vocabularies meet here and <code>ECI == 0</code>, <code>TEME == 0</code> and <code>FIXED == 0</code> all collide. A container whose declared frame has no member on the roster is <code>UNSUPPORTED_FORMAT</code>, not a guess.</p>
121
+ <ul>
122
+ <li><strong>Interpolation is declared, not implied.</strong> A container that states its own interpolation rule (SPK segment type, OEM <code>INTERPOLATION</code>/<code>INTERPOLATION_DEGREE</code>, STK <code>InterpolationMethod</code>) is evaluated by THAT rule. A module that silently substitutes its own is not reading the file, it is fitting one.</li>
123
+ <li><strong>Ingest is streamed, not slurped.</strong> A multi-hundred-megabyte kernel that loads on native WasmEdge and dies in the browser is a runtime-shaped branch. Read the container by record and declare <code>initialMemoryBytes</code> / <code>maximumMemoryBytes</code> rather than inheriting a per-lane default.</li>
124
+ </ul>
112
125
  <h3 id="batch-and-introspection"><a class="anchor" href="#batch-and-introspection" aria-hidden="true">#</a>Batch and introspection</h3>
113
126
  <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
127
  <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>
@@ -168,7 +181,7 @@
168
181
  <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
182
  <h2 id="error-codes"><a class="anchor" href="#error-codes" aria-hidden="true">#</a>Error codes</h2>
170
183
  <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>
184
+ <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><tr><td><code>-7</code></td><td>UNSUPPORTED_FORMAT</td><td>the ephemeris container is not one this module reads, or <code>AUTO</code> could not identify it</td></tr><tr><td><code>-8</code></td><td>EPOCH_OUT_OF_RANGE</td><td>the requested epoch lies outside every segment the loaded ephemeris covers</td></tr></tbody></table></div>
172
185
  <p>Rules that are not negotiable:</p>
173
186
  <ul>
174
187
  <li><strong>Validated input can never trap.</strong> Malformed input is a code, not a crash.</li>
@@ -277,6 +290,7 @@ node scripts/check-propagator-abi.mjs # the drift gate (runs in npm test)</
277
290
  <li><a class="depth-2" href="#the-export-set">The export set</a></li>
278
291
  <li><a class="depth-3" href="#required">Required</a></li>
279
292
  <li><a class="depth-3" href="#typed-ingest">Typed ingest</a></li>
293
+ <li><a class="depth-3" href="#ephemeris-ingest">Ephemeris ingest</a></li>
280
294
  <li><a class="depth-3" href="#batch-and-introspection">Batch and introspection</a></li>
281
295
  <li><a class="depth-2" href="#wire-layout">Wire layout</a></li>
282
296
  <li><a class="depth-3" href="#orbprostatevector-64-bytes-8-byte-aligned"><code>OrbProStateVector</code> — 64 bytes, 8-byte aligned</a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html" aria-current="page"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
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>
57
+ <li><a href="./estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -63,13 +63,13 @@ taxonomy of 2026-08-14. It is not aspirational.
63
63
  | Designed | An ABI has been drafted against a real consumer. No generated header, no conformance kit, no reference module has landed. |
64
64
  | Planned | A ratified entry in the taxonomy whose individual shape has not been ratified. Nothing is implemented. |
65
65
 
66
- Only **propagator** and **data-source** are Shipped. **maneuver**,
67
- **estimation** and **analytics** are Experimental — analytics on the strength
68
- of ONE sub-harness, [event location](events-abi.html), whose `.fbs`, generated
69
- header, drift gate, shared runner and measured parity envelope have landed and
70
- whose conformance kit has not. Only **rf**, **obstruction** and **conjunction**
71
- are Designed. Every other family is Planned, and its status has not been
72
- ratified individually — a Planned page states scope and nothing more.
66
+ **Propagator**, **estimation**, and **data-source** are Shipped. **Maneuver**
67
+ and **analytics** are Experimental — analytics on the strength of ONE
68
+ sub-harness, [event location](events-abi.html), whose `.fbs`, generated header,
69
+ drift gate, shared runner and measured parity envelope have landed and whose
70
+ conformance kit has not. Only **rf**, **obstruction** and **conjunction** are
71
+ Designed. Every other family is Planned, and its status has not been ratified
72
+ individually — a Planned page states scope and nothing more.
73
73
 
74
74
  A sub-harness is not a twentieth family. The nineteen-family taxonomy above is
75
75
  owner-ratified: a capability that fits inside a ratified family arrives as a
package/docs/index.html CHANGED
@@ -130,7 +130,7 @@
130
130
  <p>Turning observations into state, bringing data in, and deciding what happens next.</p>
131
131
  <div class="card-grid">
132
132
  <a class="card" href="./families/estimation.html">
133
- <div class="card-head"><h4>Estimation</h4><span class="pill pill-experimental">experimental</span></div>
133
+ <div class="card-head"><h4>Estimation</h4><span class="pill pill-shipped">shipped</span></div>
134
134
  <p>Orbit determination and filtering: observations in, estimated state and covariance out.</p>
135
135
  </a>
136
136
  <a class="card" href="./families/data-source.html">
@@ -177,7 +177,7 @@
177
177
  <h2 id="status-vocabulary"><a class="anchor" href="#status-vocabulary" aria-hidden="true">#</a>Status vocabulary</h2>
178
178
  <p>Status on this site is literal, and is taken from the ratified harness-family taxonomy of 2026-08-14. It is not aspirational.</p>
179
179
  <div class="table-wrap"><table><thead><tr><th>Status</th><th>Meaning</th></tr></thead><tbody><tr><td>Shipped</td><td>Ratified <code>.fbs</code> single source, generated header with a drift gate, conformance kit, reference module. Build against it.</td></tr><tr><td>Experimental</td><td>Real code exists and the shape is taking form, but it is not frozen and known defects are open. Do not ship a commercial module against it.</td></tr><tr><td>Designed</td><td>An ABI has been drafted against a real consumer. No generated header, no conformance kit, no reference module has landed.</td></tr><tr><td>Planned</td><td>A ratified entry in the taxonomy whose individual shape has not been ratified. Nothing is implemented.</td></tr></tbody></table></div>
180
- <p>Only <strong>propagator</strong> and <strong>data-source</strong> are Shipped. <strong>maneuver</strong>, <strong>estimation</strong> and <strong>analytics</strong> are Experimental — analytics on the strength of ONE sub-harness, <a href="./events-abi.html">event location</a>, whose <code>.fbs</code>, generated header, drift gate, shared runner and measured parity envelope have landed and whose conformance kit has not. Only <strong>rf</strong>, <strong>obstruction</strong> and <strong>conjunction</strong> are Designed. Every other family is Planned, and its status has not been ratified individually — a Planned page states scope and nothing more.</p>
180
+ <p><strong>Propagator</strong>, <strong>estimation</strong>, and <strong>data-source</strong> are Shipped. <strong>Maneuver</strong> and <strong>analytics</strong> are Experimental — analytics on the strength of ONE sub-harness, <a href="./events-abi.html">event location</a>, whose <code>.fbs</code>, generated header, drift gate, shared runner and measured parity envelope have landed and whose conformance kit has not. Only <strong>rf</strong>, <strong>obstruction</strong> and <strong>conjunction</strong> are Designed. Every other family is Planned, and its status has not been ratified individually — a Planned page states scope and nothing more.</p>
181
181
  <p>A sub-harness is not a twentieth family. The nineteen-family taxonomy above is owner-ratified: a capability that fits inside a ratified family arrives as a sub-harness with its own contract document, and the family page states exactly which part of it is shaped.</p>
182
182
  <p>Where a family page says a thing does not exist, that is a checked statement about the tree today, not a placeholder.</p>
183
183
  <h2 id="vehicle-domains-are-not-a-harness-family"><a class="anchor" href="#vehicle-domains-are-not-a-harness-family" aria-hidden="true">#</a>Vehicle domains are not a harness family</h2>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>
package/docs/llms.txt CHANGED
@@ -46,7 +46,7 @@ WasmEdge, which breaks tri-runtime isomorphism. Modules must be EH-free.
46
46
 
47
47
  ### Estimation, data and logic
48
48
 
49
- - [Estimation](https://digitalarsenal.github.io/space-data-module-sdk/families/estimation.html) — EXPERIMENTAL. Orbit determination and filtering: observations in, estimated state and covariance out.
49
+ - [Estimation](https://digitalarsenal.github.io/space-data-module-sdk/families/estimation.html) — SHIPPED. Orbit determination and filtering: observations in, estimated state and covariance out.
50
50
  - [Data source](https://digitalarsenal.github.io/space-data-module-sdk/families/data-source.html) — SHIPPED. Fetch, parse and normalize external provider data into standards records inside the module.
51
51
  - [Analytics](https://digitalarsenal.github.io/space-data-module-sdk/families/analytics.html) — EXPERIMENTAL. Derived figures of merit computed over a scenario. The event-location sub-harness is shaped and measured; the rest is planned.
52
52
  - [Scheduler](https://digitalarsenal.github.io/space-data-module-sdk/families/scheduler.html) — PLANNED. Ordering and tasking of activities across a scenario timeline.
@@ -54,7 +54,7 @@
54
54
  <li><a href="./families/effects.html"><span>Effects</span><span class="tag tag-planned">planned</span></a></li>
55
55
  </ul>
56
56
  <h2>Estimation, data and logic</h2><ul>
57
- <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-experimental">experimental</span></a></li>
57
+ <li><a href="./families/estimation.html"><span>Estimation</span><span class="tag tag-shipped">shipped</span></a></li>
58
58
  <li><a href="./families/data-source.html"><span>Data source</span><span class="tag tag-shipped">shipped</span></a></li>
59
59
  <li><a href="./families/analytics.html"><span>Analytics</span><span class="tag tag-experimental">experimental</span></a></li>
60
60
  <li><a href="./families/scheduler.html"><span>Scheduler</span><span class="tag tag-planned">planned</span></a></li>