@essrt/physics 1.13.0 → 1.15.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essrt/physics",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "ESSRT (Expanding Solar System Resonance Theory) physics core \u2014 pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.",
5
5
  "essrt": {
6
6
  "modelVersion": "v11.0",
@@ -766,8 +766,8 @@ export const REFERENCE_DATA = Object.freeze({
766
766
  "sunSiderealYearDiffSeconds": 0.02,
767
767
  "frameworkSunVsJplRmsArcsec": 0.95,
768
768
  "meeusCh25SunVsJplRmsArcsec": 1.28,
769
- "moonSeriesLonVsJplRmsArcsec": 2.96,
770
- "moonSeriesLatVsJplRmsArcsec": 0.65,
769
+ "moonSeriesLonVsJplRmsArcsec": 2.84,
770
+ "moonSeriesLatVsJplRmsArcsec": 0.35,
771
771
  "mercuryNewtonianArcsecCy": 532,
772
772
  "mercuryObservedICRFArcsecCy": 575,
773
773
  "mercuryPark2017RateArcsecCy": 575.31,
@@ -235,4 +235,16 @@ function createSunPlanetaryCompletion({ embWobbleArcsec, carrierRatesDegPerCy })
235
235
  * landings. */
236
236
  const PAIRED_SUN_HARMONICS_SHA256 = 'e2cf42e9770c9e0a';
237
237
 
238
- module.exports = { createSunPlanetaryCompletion, PAIRED_SUN_HARMONICS_SHA256 };
238
+ /** sha256/16 of JSON.stringify([...planets, moonElongation]) — the seven
239
+ * full-precision carrier rates (deg/cy TT) the TERMS table was extracted
240
+ * under at N3. The model wiring recomputes the rates live from the planet
241
+ * records, so a planet-period / year / month input change moves the
242
+ * carriers automatically while the table stays frozen — a silent few-
243
+ * arcsec stale below the api gate's ≤8″ backstop. test:model recomputes
244
+ * this fingerprint from live constants (identical arithmetic to model.js)
245
+ * and fails on mismatch: re-run the N3 extraction chain
246
+ * (tools/explore/n2-sun-framework-carriers.mjs →
247
+ * n3-carrier-swap-preview.mjs), re-embed TERMS, and update this value. */
248
+ const PAIRED_CARRIER_RATES_SHA256 = '893e055ee12343bd';
249
+
250
+ module.exports = { createSunPlanetaryCompletion, PAIRED_SUN_HARMONICS_SHA256, PAIRED_CARRIER_RATES_SHA256 };
@@ -56,6 +56,53 @@
56
56
  * (max 6.2″). Coefficients are stored with the run→real argument
57
57
  * mapping already applied (the extraction's heliocentric-planet vs
58
58
  * geocentric-sun π-offset is folded into the signs).
59
+ *
60
+ * THE J2 NODE FAMILY (FQ-7 Round 3, plan §12i) — five derived terms on
61
+ * Ω-family arguments (NOT expressible on the integer Delaunay lattice,
62
+ * which is why every earlier extraction missed them; the 200-yr band
63
+ * probe named them, the dense 2-day JPL sample confirmed them real, and
64
+ * the channel isolation identified them as EARTH'S J2 acting on the
65
+ * lunar orbit — the same channel whose secular piece DLT-1 derives as
66
+ * the Earth-figure +0.1925″/cy² T² term). Extracted from the B−A
67
+ * differential of epoch-phased 3-body twin integrations (J2 on vs off,
68
+ * identical ICs; per-run fits on each run's OWN mean angles — fitting
69
+ * the raw differential leaks A·δrate·t quadrature, measured as 2.4″
70
+ * fake rows), dt-halving converged ≤0.003″. TWO DOCUMENTED CONTROLS
71
+ * certify the channel and calibrate the run→instrument frame mapping:
72
+ * the derived pure-Ω λ term reproduces the Meeus flattening additive
73
+ * (+1962e-6 sin(Lp−F)) at 1.028, and the derived β sin(Lp) reproduces
74
+ * the −2235e-6 additive at 0.971 — both already shipped via the
75
+ * catalog additive family and therefore NOT re-shipped here. JPL
76
+ * out-of-sample (validation only, never fit): official all-phase λ
77
+ * 2.964 → 2.922″, β 0.653 → 0.606″; dense 2-day λ 2.378 → 2.321″,
78
+ * β 0.655 → 0.601″; syzygy-fleet elongation improves. Instruments:
79
+ * fq7-band-probe.mjs · fq7-jpl-band.mjs · fq7-j2-node.mjs ·
80
+ * fq7-r3-ship.mjs · fq7-r3-preview.mjs. The Ω carrier polynomial is an
81
+ * IAU-class instrument literal — the same DECLARED-INPUT status as the
82
+ * Delaunay carriers above (Ω ≡ Lp − F of the same catalog class).
83
+ *
84
+ * THE FQ-7 DUST ROUND (plan §12i) — 43 λ + 33 β derived Delaunay terms
85
+ * appended to LON_TERMS/LAT_TERMS below. The broadband-dust census
86
+ * (fq7-dust-census.mjs, secular-guarded v2: cubic detrend + T/T²
87
+ * quadrature absorbers on the head arguments, without which the
88
+ * doctrine-blocked T-modulated parameter class masquerades as fake
89
+ * 184-yr sideband families) ranked the post-R3 capturable content; the
90
+ * dense-JPL arbitration (fq7-dust-arbitration.mjs) measured EVERY
91
+ * trusted leader REAL at ratio 0.9–1.1; the labels bit-match MPP02
92
+ * main-problem catalog rows below the Meeus ~0.4″ truncation cutoff, in
93
+ * argument classes no earlier extraction catalog enumerated (odd kD,
94
+ * |kM| = 3, |kF| = 4/5). Main-problem ⇒ the D1 3-body lab derives them:
95
+ * one 120-yr run, λ and β columns, head fidelity 0.51%/0.07%,
96
+ * dt-halving drift 0.000″, lab/census ratio ∈ [0.7, 1.4] required
97
+ * (4 λ census rows the lab does NOT fully produce stay unshipped —
98
+ * derive or don't ship). Lab signs match the MPP02 catalog signs row
99
+ * for row (the frame-consistency control). JPL out-of-sample: official
100
+ * all-phase λ 2.922 → 2.840″, β 0.606 → 0.353″ — the β endpoint AT the
101
+ * R1-measured MPP02-vs-JPL floor (~0.33″); dense 2-day λ 2.321 →
102
+ * 2.219″, β 0.601 → 0.384″; syzygy fleet improves; the sign-flip
103
+ * control degrades every gate. Instruments: fq7-dust-census.mjs ·
104
+ * fq7-dust-arbitration.mjs · fq7-dust-extraction.mjs ·
105
+ * fq7-dust-preview.mjs.
59
106
  */
60
107
 
61
108
  'use strict';
@@ -131,6 +178,52 @@ const LON_TERMS = [
131
178
  [4, 0, -2, 2, -0.169],
132
179
  [4, -2, -2, 0, 0.161],
133
180
  [0, 0, 5, 0, 0.112],
181
+ // FQ-7 DUST ROUND — the argument classes no earlier catalog enumerated
182
+ // (odd kD, |kM| = 3, |kF| = 4); lab-derived, MPP02-catalog-certified,
183
+ // JPL-arbitrated (see header note):
184
+ [0, 0, 0, 4, 0.422],
185
+ [3, 0, 0, 0, 0.402],
186
+ [2, -3, 0, 0, 0.341],
187
+ [3, 1, -1, 0, 0.275],
188
+ [3, 0, 0, -2, -0.250],
189
+ [2, -3, -1, 0, 0.240],
190
+ [3, -1, -1, 0, -0.233],
191
+ [3, 1, 0, 0, 0.147],
192
+ [0, 3, 0, 0, -0.096],
193
+ [4, -1, -3, 0, 0.096],
194
+ [2, -1, 3, 0, 0.094],
195
+ [2, 0, -3, -2, -0.093],
196
+ [0, 0, 1, 4, 0.092],
197
+ [6, -1, -2, 0, 0.091],
198
+ [1, 1, 2, 0, 0.090],
199
+ [4, 0, 0, 2, -0.084],
200
+ [3, -1, -2, 0, -0.082],
201
+ [0, 0, 1, -4, -0.081],
202
+ [2, 0, 4, 0, 0.078],
203
+ [2, 0, 0, -4, -0.078],
204
+ [0, 1, 0, -2, 0.074],
205
+ [2, -1, 1, 2, -0.073],
206
+ [2, -1, -1, -2, -0.073],
207
+ [6, -1, -1, 0, 0.072],
208
+ [2, 1, -1, 2, 0.068],
209
+ [2, 0, -5, 0, 0.067],
210
+ [2, 1, 0, 2, 0.066],
211
+ [4, 0, 1, -2, -0.065],
212
+ [2, -2, 2, 0, 0.065],
213
+ [2, -2, 0, -2, 0.065],
214
+ [3, -1, 0, 0, 0.063],
215
+ [0, 2, 2, 0, -0.062],
216
+ [5, 0, -2, 0, -0.059],
217
+ [0, 1, -2, -2, 0.050],
218
+ [4, 1, 1, 0, -0.050],
219
+ [0, 1, -4, 0, -0.048],
220
+ [0, 1, 2, 2, 0.045],
221
+ [1, 0, 1, 2, 0.044],
222
+ [3, 0, -3, 0, -0.043],
223
+ [1, 0, 3, 0, -0.042],
224
+ [1, 2, 0, 0, -0.041],
225
+ [0, 3, -1, 0, -0.038],
226
+ [1, -2, 0, 0, 0.037],
134
227
  ];
135
228
 
136
229
  /** Latitude tail: [kD, kM, kMp, kF, sin″] — 30 derived terms ≥ 0.1″
@@ -166,6 +259,41 @@ const LAT_TERMS = [
166
259
  [1, 0, -2, -1, -0.1093],
167
260
  [2, 2, -1, 1, -0.1044],
168
261
  [1, 1, 1, 1, 0.1014],
262
+ // FQ-7 DUST ROUND — lab-derived, MPP02-catalog-certified,
263
+ // JPL-arbitrated (see header note):
264
+ [3, 0, 0, -1, -0.352],
265
+ [3, 0, -1, -1, -0.305],
266
+ [4, -1, -2, 1, 0.214],
267
+ [3, 0, -1, 1, -0.206],
268
+ [0, 2, -1, 1, -0.094],
269
+ [6, 0, -1, -1, 0.094],
270
+ [0, 0, 4, -1, 0.091],
271
+ [2, -1, 0, -3, 0.087],
272
+ [6, 0, -2, -1, 0.081],
273
+ [1, 0, -2, 1, -0.078],
274
+ [0, 1, -3, -1, -0.075],
275
+ [2, 1, -2, -1, 0.073],
276
+ [2, -2, 1, -1, 0.069],
277
+ [2, 0, -2, 3, -0.065],
278
+ [1, 0, 2, 1, -0.064],
279
+ [2, -1, -2, 1, -0.064],
280
+ [2, 1, 2, -1, -0.063],
281
+ [4, 0, 0, -3, 0.062],
282
+ [0, 1, 3, 1, -0.062],
283
+ [6, 0, -2, 1, 0.060],
284
+ [2, -2, 1, 1, 0.059],
285
+ [2, 1, 0, -3, -0.059],
286
+ [4, -1, 1, -1, 0.057],
287
+ [0, 2, 0, 1, -0.055],
288
+ [0, 2, 1, 1, -0.054],
289
+ [2, -1, -3, -1, 0.054],
290
+ [4, -1, -2, -1, 0.052],
291
+ [4, 1, -1, 1, -0.051],
292
+ [1, 1, -1, 1, -0.051],
293
+ [2, 1, -2, 1, 0.049],
294
+ [3, 0, -2, 1, -0.048],
295
+ [4, 0, 2, -1, 0.048],
296
+ [6, 0, -1, 1, 0.042],
169
297
  ];
170
298
 
171
299
  /** Planetary mean-longitude polynomials, degrees per Julian century TT
@@ -198,6 +326,27 @@ const PLANETARY_LON_TERMS = [
198
326
  [[0, 1, 0, -1, 0, 0, -1], -0.0077, 0.2235],
199
327
  ];
200
328
 
329
+ /** Lunar mean-node polynomial [deg at J2000, deg/cy, deg/cy²] TT —
330
+ * the Ω carrier for the J2 node family (declared input, see header). */
331
+ const OMEGA = [125.0445479, -1934.1362891, 0.0020754];
332
+
333
+ /**
334
+ * The J2 node family (see header): [[kD,kM,kMp,kF,kΩ], sin″] — pure
335
+ * sin-parity (the derivation's cos components read ≤0.005″), ADD-composed
336
+ * like the Delaunay tail.
337
+ * @type {Array<[number[], number]>}
338
+ */
339
+ const NODE_LON_TERMS = [
340
+ [[0, 0, 1, 0, -1], -0.544],
341
+ [[0, 0, 1, 0, 1], 0.546],
342
+ [[0, 0, 0, 2, 1], 0.371],
343
+ [[2, 0, 0, 0, 1], 0.103],
344
+ ];
345
+ /** @type {Array<[number[], number]>} */
346
+ const NODE_LAT_TERMS = [
347
+ [[0, 0, 0, 1, -1], -0.375],
348
+ ];
349
+
201
350
  const D2R = Math.PI / 180;
202
351
 
203
352
  /**
@@ -219,6 +368,9 @@ function moonSeriesExtensionDeg(T) {
219
368
  const th = k[0] * l[0] + k[1] * l[1] + k[2] * l[2] + k[3] * l[3] + k[4] * l[4] + k[5] * D + k[6] * Mp;
220
369
  lon += cA * Math.cos(th) + sA * Math.sin(th);
221
370
  }
371
+ const Om = poly(OMEGA);
372
+ for (const [k, s] of NODE_LON_TERMS) lon += s * Math.sin(k[0] * D + k[1] * M + k[2] * Mp + k[3] * F + k[4] * Om);
373
+ for (const [k, s] of NODE_LAT_TERMS) lat += s * Math.sin(k[0] * D + k[1] * M + k[2] * Mp + k[3] * F + k[4] * Om);
222
374
  return { dLonDeg: lon / 3600, dLatDeg: lat / 3600 };
223
375
  }
224
376