@essrt/physics 10.0.0 → 11.0.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.
@@ -18,10 +18,20 @@
18
18
  // J2000 node lamDotRel ≡ 1 by construction, so the caller's anchor is
19
19
  // preserved exactly.
20
20
  //
21
- // Scope: this channel feeds the model/chart surface for the sidereal year
22
- // OF DATE. The scene's sidereal frame stays on the certified H/13
23
- // identity — a 3e-8 relative frame change is invisible in the render and
24
- // would disturb the certified frozen-clock pair.
21
+ // Scope: this channel is the sidereal year OF DATE everywhere — the
22
+ // model/chart surfaces AND the scene: since plan 06 R1 the Sun's mean
23
+ // longitude of date integrates the one-family tropical year (this channel
24
+ // minus the movement's own general precession), so the scene's measured
25
+ // sidereal angle reproduces this law (the scene-sampled gate,
26
+ // tools/verify/scene-year-lengths.js). The frozen era clock's sidereal
27
+ // year (mass-loss only, no planetary drift) is the certified era device,
28
+ // not a member of this family.
29
+ //
30
+ // ESTIMATOR (2026-09): each banked node is the least-squares slope of a
31
+ // quadratic fitted to the dump's unwrapped L over ±5 kyr — the former
32
+ // 2-kyr boxcar of per-step rates telescoped to the difference of the
33
+ // OSCULATING longitude at the window's two ends and left 0.1–0.3 s of
34
+ // node noise (−266 ms at +4000 against DE441; +18…28″ of Sun by 6500).
25
35
 
26
36
  const { SIDEREAL_CHANNEL_ARTIFACT } = require('./sidereal-channel-artifact.cjs');
27
37
 
@@ -10,81 +10,112 @@
10
10
  // pair's members is amplified ~20×/s by P = T_s/(T_s − T_t).
11
11
  //
12
12
  // The rules this factory owns:
13
- // • ONE FAMILY: tropical = massLoss·(1 − p_geom/360) with p_geom the
14
- // movement's own equinox rate (wobble included); sidereal = the D6
15
- // λ̇ channel; anomalistic = the SECULAR mean-element construction on
16
- // the chain's apsidal tangent (the injected fn — the same rate family
17
- // the panel's Prec. cell shows; structure fallback when absent); every
18
- // value λ̇-corrected coherently (rate form — beats invariant to
19
- // second order).
20
- // • ONE BASIS: SI seconds (days = seconds/86400 at the caller).
13
+ // • ONE FAMILY: sidereal = the D6 λ̇ channel; tropical = the sidereal
14
+ // year minus the movement's own GENERAL-PRECESSION rate of date (the
15
+ // broken-angle equinox longitude, wobble included), in RATE form with
16
+ // the sampler's Julian-year unit named; anomalistic = the tropical
17
+ // year minus the movement's own equinox-referenced apsidal rate of
18
+ // date (the same year-over-year reading — the scene's perihelion
19
+ // passages ARE this movement); every value λ̇-corrected coherently
20
+ // (rate form — beats invariant to second order).
21
+ // • ONE BASIS: SI seconds (days = seconds/86400 at the caller); periods
22
+ // in JULIAN years (the beat's duration ÷ 365.25 d — the unit the
23
+ // frame's precession rate is quoted in, so 360°/rate and the pair's
24
+ // beat are the SAME number; measured 2026-09: the dimensionless
25
+ // T_sid/(T_sid − T_trop) counts TROPICAL years, 2.1e-5 off — 0.55 yr
26
+ // on the axial period, 26 ms on the tropical year against the frame).
21
27
  // • BEATS FROM THE PAIR: each precession period is computed from the
22
28
  // two years THIS factory returns — recomputing a beat from the
23
29
  // displayed/served values reproduces it exactly.
24
- // • Scene MEASUREMENTS validate this family (sub-0.5 s, the report's
25
- // measured columns); they are instruments, never mixed into beats.
30
+ // • THE SCENE IS THE REFERENCE (owner, 2026-09-30: "all calculations
31
+ // should match what we measure in the scene"): the scene's Sun
32
+ // integrates the tropical year below and turns with this movement's
33
+ // frame and apsidal line, so its measured sidereal, tropical and
34
+ // anomalistic years reproduce this family to the millisecond once the
35
+ // planetary completion terms are removed per event (the scene-sampled
36
+ // gate, tools/verify/scene-year-lengths.js). Before this restatement
37
+ // the scene read the law's sidereal year 26 ms short at J2000 and up
38
+ // to 1 s off at depth (the projected equinox rate), and the published
39
+ // anomalistic year rode the planet chain's secular tangent — seconds
40
+ // from the scene's own perihelion passages within a few millennia,
41
+ // 395 s at +25 kyr where e passes 0.0034.
26
42
  // • The frozen era clock stays the certified era device (opt-out /
27
43
  // era-certification record), not a member of this family.
28
44
 
29
45
  const { createCardinalStructure } = require('../cardinal/one-source-structure.cjs');
30
46
  const { createSiderealYearChannel } = require('./sidereal-year-channel.cjs');
31
47
 
48
+ /** SI seconds in one Julian year — the sampler's time unit (t = years from J2000 TT, 365.25 d). */
49
+ const JULIAN_YEAR_SECONDS = 365.25 * 86400;
50
+
32
51
  /**
33
52
  * @param {{
34
- * sampleAt: (year: number) => {e: number, periOfDateDeg: number, equinoxLonJ2000Deg: number},
53
+ * sampleAt: (year: number) => {e: number, periOfDateDeg: number, equinoxLonJ2000Deg: number, generalPrecessionLonDeg: number},
35
54
  * massLossSiderealSecondsAtYearFn: (year: number) => number,
36
- * apsidalSecularDegPerYrFn?: (year: number) => number,
37
55
  * }} opts
38
- * sampleAt: the one-source movement sampler, calendar-year keyed
39
- * (createDeepOrbitalHistory build().at wrapped by the caller — series
40
- * tier where the artifact is available, mode tail beyond).
56
+ * sampleAt: the one-source movement sampler, keyed in the sampler's own
57
+ * year (Julian years from J2000 TT, 2000 = J2000; createDeepOrbitalHistory
58
+ * build().at wrapped by the caller — series tier where the artifact is
59
+ * available, mode tail beyond).
41
60
  * massLossSiderealSecondsAtYearFn: the caller's secular mass-loss
42
61
  * sidereal-year law, SI seconds, IAU-anchored at J2000.
43
- * apsidalSecularDegPerYrFn: the chain's SECULAR apsidal tangent of date
44
- * (keplerian-chain computeApsidalSecularDegPerYr for Earth — deg/yr,
45
- * J2000-ecliptic frame). When given, the anomalistic year is the
46
- * mean-element construction on this smooth rate; when absent, it falls
47
- * back to the cardinal structure's measured year-over-year interval
48
- * (which carries the banked series' century-scale ϖ̇ wobble).
49
62
  */
50
- function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn, apsidalSecularDegPerYrFn }) {
63
+ function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn }) {
51
64
  if (typeof sampleAt !== 'function' || typeof massLossSiderealSecondsAtYearFn !== 'function') {
52
65
  throw new Error('createYearLengths: sampleAt and massLossSiderealSecondsAtYearFn are required');
53
66
  }
54
67
  const w180 = (/** @type {number} */ d) => ((d + 540) % 360) - 180;
55
68
  const chan = createSiderealYearChannel({ massLossSiderealSecondsAtYearFn });
69
+ /** A year length from a longer year and a retrograde angular rate of the
70
+ * reference point, RATE form: 1/T = 1/T_long + p/(360°·JY) — exact (the
71
+ * linear T_long·(1 − p/360) drops (p/360)², 47 ms on the tropical year),
72
+ * with p in degrees per JULIAN year (the sampler's unit; read as "per
73
+ * tropical year" it was 26 ms short). @param {number} tLong @param {number} pDegPerJulianYr */
74
+ const shorterYear = (tLong, pDegPerJulianYr) => 1 / (1 / tLong + pDegPerJulianYr / (360 * JULIAN_YEAR_SECONDS));
75
+ /** The movement's own general precession of date, degrees per Julian
76
+ * year, retrograde positive — the year-over-year advance of the
77
+ * broken-angle equinox longitude (wobble included). @param {number} year */
78
+ const generalPrecessionDegPerJulianYr = (year) =>
79
+ w180(sampleAt(year - 0.5).generalPrecessionLonDeg - sampleAt(year + 0.5).generalPrecessionLonDeg);
80
+ /** The movement's own apsidal rate of date RELATIVE TO THE EQUINOX (the
81
+ * climatic-precession rate, ~0.017°/yr at J2000), degrees per Julian
82
+ * year, prograde positive. @param {number} year */
83
+ const apsidalVsEquinoxDegPerJulianYr = (year) =>
84
+ w180(sampleAt(year + 0.5).periOfDateDeg - sampleAt(year - 0.5).periOfDateDeg);
56
85
  // The mean tropical year OF DATE, raw (pre-λ̇): the movement's own
57
- // equinox-rate form — carries the real precession-rate wobble, unlike
58
- // the smooth secular mean (a wobble-free mean under a wobbling family
59
- // was one of the duplicated implementations this factory retires).
60
- const tropicalRawSeconds = (/** @type {number} */ year) => {
61
- const p = w180(sampleAt(year - 0.5).equinoxLonJ2000Deg
62
- - sampleAt(year + 0.5).equinoxLonJ2000Deg); // retrograde → positive
63
- return massLossSiderealSecondsAtYearFn(year) * (1 - p / 360);
64
- };
86
+ // general-precession rate — carries the real precession-rate wobble,
87
+ // unlike the smooth secular mean (a wobble-free mean under a wobbling
88
+ // family was one of the duplicated implementations this factory retires).
89
+ const tropicalRawSeconds = (/** @type {number} */ year) =>
90
+ shorterYear(massLossSiderealSecondsAtYearFn(year), generalPrecessionDegPerJulianYr(year));
65
91
  const structure = createCardinalStructure({
66
92
  sampleAt,
67
93
  tropicalYearSecondsAtYearFn: tropicalRawSeconds,
68
94
  });
69
95
  const trop = (/** @type {number} */ year) => chan.correctedYearSeconds(year, tropicalRawSeconds(year));
70
96
  const sid = (/** @type {number} */ year) => chan.siderealYearSecondsAtYear(year);
71
- // The anomalistic year OF DATE — the SECULAR (mean-element) construction
72
- // when the chain tangent is injected: T_anom_raw = T_sid_raw·360/(360 − w)
73
- // with w = dϖ/dt (deg/yr, J2000-ecliptic, the SAME rate family the panel's
74
- // Prec. cell shows), then λ̇-corrected coherently. The displayed beat
75
- // anom/(anom − sid) then equals the chain period 360/w EXACTLY at J2000
76
- // (the rate-form correction leaves beats invariant), and the J2000 value
77
- // lands +0.07 s from the published mean-element 365.259636 d. The former
78
- // structure form (the year-over-year interval on the banked series) read
79
- // the series' century-scale ϖ̇ wobble — ±0.015″/yr ≈ ±0.35 s, an alias at
80
- // the series' 250-yr sampling — and sat +0.20 s above the smooth tangent
81
- // at J2000 (owner-found: the panel beat read 111,491 where the Prec. cell
82
- // read 111,570). The measured-interval form stays on the cardinal
83
- // structure for callers that want the wobble.
84
- const anom = apsidalSecularDegPerYrFn
85
- ? (/** @type {number} */ year) => chan.correctedYearSeconds(year,
86
- massLossSiderealSecondsAtYearFn(year) * 360 / (360 - apsidalSecularDegPerYrFn(year)))
87
- : (/** @type {number} */ year) => chan.correctedYearSeconds(year, structure.anomalisticYearSeconds(year));
97
+ // The anomalistic year OF DATE: the tropical year lengthened by the
98
+ // movement's own apsidal advance against the equinox (a perihelion
99
+ // passage is a pure mean-anomaly event — no equation-of-centre term), in
100
+ // rate form, then λ̇-corrected coherently. This IS the scene: its apsidal
101
+ // wheel turns with periOfDateDeg, and the scene's perihelion-to-perihelion
102
+ // intervals read this form to 0.03–0.13 s at every sampled epoch. The
103
+ // former construction on the planet chain's secular apsidal tangent (the
104
+ // same family as the Perihelion Longitudes Prec. cell) agreed at J2000
105
+ // (+0.07 s) and parted from the scene by +3.3 s at 0 AD, −6.6 s at 6000,
106
+ // −14 s at 10,000 and −395 s at +25,000 (e = 0.0034, the apsidal line
107
+ // swings fast) — the chain tangent's dϖ̇/dt runs ~40 % steep against the
108
+ // secular mean elements, the series' reads them to ~1 s over ±4 kyr. The
109
+ // rate the beats and the Prec. cell quote is apsidalRateFixedDegPerJulianYr
110
+ // below — ONE family, so 360°/rate and anom/(anom − sid) are the same
111
+ // number. The year-over-year reading carries the banked series' own
112
+ // century-scale ripple (±0.015″/yr ≈ ±0.35 s; the cadence is named in the
113
+ // artifact) — it is the movement's, not smoothed away.
114
+ const anom = (/** @type {number} */ year) =>
115
+ chan.correctedYearSeconds(year, shorterYear(tropicalRawSeconds(year), -apsidalVsEquinoxDegPerJulianYr(year)));
116
+ /** A beat period in JULIAN years from two year lengths (SI s): the time for
117
+ * the shorter year to gain one turn on the longer, ÷ 365.25 d. @param {number} tLong @param {number} tShort */
118
+ const beatJulianYears = (tLong, tShort) => tLong * tShort / ((tLong - tShort) * JULIAN_YEAR_SECONDS);
88
119
 
89
120
  return Object.freeze({
90
121
  /** Mean tropical year of date, SI seconds. @param {number} year */
@@ -93,12 +124,16 @@ function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn, apsidalS
93
124
  siderealYearSecondsAtYear: sid,
94
125
  /** Anomalistic year of date, SI seconds. @param {number} year */
95
126
  anomalisticYearSecondsAtYear: anom,
96
- /** Axial precession period of date (equinox regression beat), years. @param {number} y */
97
- axialPrecessionYearsAtYear: (y) => { const s = sid(y), t = trop(y); return s / (s - t); },
98
- /** Perihelion (apsidal-vs-equinox) precession period of date, years. @param {number} y */
99
- perihelionPrecessionYearsAtYear: (y) => { const a = anom(y), t = trop(y); return a / (a - t); },
100
- /** Apsidal precession period of date vs the fixed stars, years (hypersensitive: ±1 s ↔ ≈400 yr; the identifier keeps the historical "inclination" name). @param {number} y */
101
- inclinationPrecessionYearsAtYear: (y) => { const a = anom(y), s = sid(y); return a / (a - s); },
127
+ /** Axial precession period of date (equinox regression beat), JULIAN years. @param {number} y */
128
+ axialPrecessionYearsAtYear: (y) => beatJulianYears(sid(y), trop(y)),
129
+ /** Perihelion (apsidal-vs-equinox) precession period of date, JULIAN years. @param {number} y */
130
+ perihelionPrecessionYearsAtYear: (y) => beatJulianYears(anom(y), trop(y)),
131
+ /** Apsidal precession period of date vs the fixed stars, JULIAN years (hypersensitive: ±1 s ↔ ≈400 yr; the identifier keeps the historical "inclination" name). @param {number} y */
132
+ inclinationPrecessionYearsAtYear: (y) => beatJulianYears(anom(y), sid(y)),
133
+ /** The movement's own general precession of date, ″ per Julian year (retrograde positive) — 360°/this ≡ axialPrecessionYearsAtYear to second order. @param {number} y */
134
+ generalPrecessionArcsecPerJulianYr: (y) => generalPrecessionDegPerJulianYr(y) * 3600,
135
+ /** The movement's own apsidal rate of date against the FIXED frame, ″ per Julian year (prograde positive) — the rate the Perihelion Longitudes Prec. cell shows for Earth; 360°/this ≡ inclinationPrecessionYearsAtYear exactly. @param {number} y */
136
+ apsidalRateFixedArcsecPerJulianYr: (y) => { const a = anom(y), s = sid(y); return 360 * JULIAN_YEAR_SECONDS * (1 / s - 1 / a) * 3600; },
102
137
  /** The per-cardinal layer (D6 rules: year lengths λ̇-corrected; offsets/spreads raw — μs-class/second-order there). */
103
138
  cardinal: Object.freeze({
104
139
  /** @param {number} y @param {'VE'|'SS'|'AE'|'WS'} type */
package/src/model.js CHANGED
@@ -24,7 +24,6 @@ import { createPhaseMachinery } from './phase/index.cjs';
24
24
  import { createYearLengths, ONE_FAMILY_WINDOW_YEARS } from './earth/year-lengths.cjs';
25
25
  import { createDeepOrbitalHistory } from './earth/deep-orbital-history.cjs';
26
26
  import { CHAIN_ARTIFACT } from './planets/chain-artifact.js';
27
- import { buildPlanetChainsFromArtifactData, computeApsidalSecularDegPerYr } from './planets/keplerian-chain.cjs';
28
27
  import { computeSecularShape } from './planets/secular-shape.cjs';
29
28
  import { createPlanetSpinChannelFromArtifacts, computeObliquityJ2000Deg } from './planets/spin-channel.cjs';
30
29
  import { createDeltaTCycles } from './deltat/cycles.cjs';
@@ -533,9 +532,6 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
533
532
  // path; the npm package alone has no 8 MB series), the movement runs the
534
533
  // SERIES tier exactly like the browser — killing the mode-vs-series
535
534
  // value split (measured: 6 s on the anomalistic year at J2000).
536
- // The engine-D planet chains (ONE build; the one-family route's apsidal
537
- // tangent and the lunisolar surface's n_aps read the same instance).
538
- const kcChainsM = buildPlanetChainsFromArtifactData(CHAIN_ARTIFACT);
539
535
  // The ONE-SOURCE movement: the hybrid's ε(t) (plan 06 Phase 3 S3b — THE
540
536
  // published obliquity) and the one-family year lengths, on the same
541
537
  // per-tier sampler.
@@ -611,13 +607,12 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
611
607
  }
612
608
  return samplers.get(key).at(t);
613
609
  };
614
- // The anomalistic rides the chain's SECULAR apsidal tangent (the same
615
- // rate family the panel's Prec. cell shows) — ONE helper, keplerian-chain.
616
- const kcChains = kcChainsM;
610
+ // The anomalistic year rides THIS movement's own apsidal line (the
611
+ // scene's perihelion) — the factory owns the construction; the planet
612
+ // chain's secular tangent is no longer a member (year-lengths.cjs).
617
613
  const yearLengths = createYearLengths({
618
614
  sampleAt,
619
615
  massLossSiderealSecondsAtYearFn: (year) => deepLod.siderealYearSecondsAtAge(yearToTMa(year)),
620
- apsidalSecularDegPerYrFn: (year) => computeApsidalSecularDegPerYr(year, kcChains.earth, kcChains),
621
616
  });
622
617
  return {
623
618
  yearLengths,
@@ -1505,23 +1500,23 @@ export function assembleModel(C, F, laws = {}, secularSeriesArtifact = /** @type
1505
1500
  const psiDot = r === null ? 1296000 / certifiedAxialPrecessionJ2000Years() : r;
1506
1501
  return 1296000 / (psiDot - s3ArcsecPerYr);
1507
1502
  },
1508
- /** The apsidal (perihelion vs the stars) period from the engine-D chain's secular tangent, years — inside the published window only (the tangent is an extrapolation beyond the banked series: it turns negative at −5 Myr); null beyond. @param {number} year @returns {number|null} */
1509
- apsidalPeriodYearsAtYear: (year) => (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM) : null),
1503
+ /** The apsidal (perihelion vs the stars) period of date, JULIAN years — the ONE movement's own apsidal rate (the scene's perihelion; anom/(anom − sid) of the one family, ≡ 360°/apsidalRateFixedArcsecPerJulianYr), inside the published window only; null beyond. Before 2026-09 this rode the planet chain's secular tangent, which parted from the scene's perihelion passages by seconds of anomalistic year within a few millennia (year-lengths.cjs). @param {number} year @returns {number|null} */
1504
+ apsidalPeriodYearsAtYear: (year) => (Math.abs(year - 2000) <= ONE_FAMILY_WINDOW_YEARS ? yearLengthsM.inclinationPrecessionYearsAtYear(year) : null),
1510
1505
  /** T_aps(t) / T_p(t) — the apsidal period in of-date precession periods (4.33 at J2000, a reading; 0.84 … 9.9 across ±26 kyr, measured); null beyond the published window. @param {number} year @returns {number|null} */
1511
1506
  apsidalPerPrecessionAtYear: (year) => {
1512
1507
  if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
1513
- return (360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM)) / publishedAxialPrecessionYearsAtYear(year);
1508
+ return yearLengthsM.inclinationPrecessionYearsAtYear(year) / publishedAxialPrecessionYearsAtYear(year);
1514
1509
  },
1515
- /** T_peri(t) = 1/(1/T_p + 1/T_aps) — the perihelion-of-date period (equinox precession + inertial perihelion motion, frame arithmetic at every epoch), years, on the of-date T_p; null beyond the published window. @param {number} year @returns {number|null} */
1510
+ /** T_peri(t) = 1/(1/T_p + 1/T_aps) — the perihelion-of-date period (equinox precession + inertial perihelion motion, frame arithmetic at every epoch), JULIAN years, on the of-date T_p — ≡ the one family's anom/(anom − trop); null beyond the published window. @param {number} year @returns {number|null} */
1516
1511
  periOfDatePeriodYearsAtYear: (year) => {
1517
1512
  if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
1518
- const tp = publishedAxialPrecessionYearsAtYear(year), taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
1513
+ const tp = publishedAxialPrecessionYearsAtYear(year), taps = yearLengthsM.inclinationPrecessionYearsAtYear(year);
1519
1514
  return 1 / (1 / tp + 1 / taps);
1520
1515
  },
1521
1516
  /** T_peri(t) / T_p(t) (0.812 at J2000 — the J2000 reading); null beyond the published window. @param {number} year @returns {number|null} */
1522
1517
  periOfDatePerPrecessionAtYear: (year) => {
1523
1518
  if (Math.abs(year - 2000) > ONE_FAMILY_WINDOW_YEARS) return null;
1524
- const tp = publishedAxialPrecessionYearsAtYear(year), taps = 360 / computeApsidalSecularDegPerYr(year, kcChainsM.earth, kcChainsM);
1519
+ const tp = publishedAxialPrecessionYearsAtYear(year), taps = yearLengthsM.inclinationPrecessionYearsAtYear(year);
1525
1520
  return (1 / (1 / tp + 1 / taps)) / tp;
1526
1521
  },
1527
1522
  /** The published of-date window, years from 2000. */
@@ -78,6 +78,8 @@ export function createDeepOrbitalHistory({ zModes, zetaModes, zetaSeries, zSerie
78
78
  orbitNormalY: number;
79
79
  equinoxLonJ2000Deg: number;
80
80
  equinoxLonRateDegPerYr: number;
81
+ generalPrecessionLonDeg: number;
82
+ generalPrecessionLonRateDegPerYr: number;
81
83
  };
82
84
  };
83
85
  alphaArcsecPerYr: number;
@@ -1,7 +1,7 @@
1
1
  export const SIDEREAL_CHANNEL_ARTIFACT: Readonly<{
2
2
  t0Yr: -10000000;
3
3
  stepYr: 2000;
4
- windowYr: 2000;
4
+ windowYr: 10000;
5
5
  lamDotRel: number[];
6
6
  meta: {
7
7
  dumpSha256: string;
@@ -9,4 +9,4 @@ export const SIDEREAL_CHANNEL_ARTIFACT: Readonly<{
9
9
  chaprontGate: number;
10
10
  };
11
11
  }>;
12
- export const SIDEREAL_CHANNEL_ARTIFACT_HASH: "528101ca3410dc9b";
12
+ export const SIDEREAL_CHANNEL_ARTIFACT_HASH: "a6f4729c2de722af";
@@ -1,29 +1,23 @@
1
1
  /**
2
2
  * @param {{
3
- * sampleAt: (year: number) => {e: number, periOfDateDeg: number, equinoxLonJ2000Deg: number},
3
+ * sampleAt: (year: number) => {e: number, periOfDateDeg: number, equinoxLonJ2000Deg: number, generalPrecessionLonDeg: number},
4
4
  * massLossSiderealSecondsAtYearFn: (year: number) => number,
5
- * apsidalSecularDegPerYrFn?: (year: number) => number,
6
5
  * }} opts
7
- * sampleAt: the one-source movement sampler, calendar-year keyed
8
- * (createDeepOrbitalHistory build().at wrapped by the caller — series
9
- * tier where the artifact is available, mode tail beyond).
6
+ * sampleAt: the one-source movement sampler, keyed in the sampler's own
7
+ * year (Julian years from J2000 TT, 2000 = J2000; createDeepOrbitalHistory
8
+ * build().at wrapped by the caller — series tier where the artifact is
9
+ * available, mode tail beyond).
10
10
  * massLossSiderealSecondsAtYearFn: the caller's secular mass-loss
11
11
  * sidereal-year law, SI seconds, IAU-anchored at J2000.
12
- * apsidalSecularDegPerYrFn: the chain's SECULAR apsidal tangent of date
13
- * (keplerian-chain computeApsidalSecularDegPerYr for Earth — deg/yr,
14
- * J2000-ecliptic frame). When given, the anomalistic year is the
15
- * mean-element construction on this smooth rate; when absent, it falls
16
- * back to the cardinal structure's measured year-over-year interval
17
- * (which carries the banked series' century-scale ϖ̇ wobble).
18
12
  */
19
- export function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn, apsidalSecularDegPerYrFn }: {
13
+ export function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn }: {
20
14
  sampleAt: (year: number) => {
21
15
  e: number;
22
16
  periOfDateDeg: number;
23
17
  equinoxLonJ2000Deg: number;
18
+ generalPrecessionLonDeg: number;
24
19
  };
25
20
  massLossSiderealSecondsAtYearFn: (year: number) => number;
26
- apsidalSecularDegPerYrFn?: (year: number) => number;
27
21
  }): Readonly<{
28
22
  /** Mean tropical year of date, SI seconds. @param {number} year */
29
23
  tropicalYearSecondsAtYear: (year: number) => number;
@@ -31,12 +25,16 @@ export function createYearLengths({ sampleAt, massLossSiderealSecondsAtYearFn, a
31
25
  siderealYearSecondsAtYear: (year: number) => number;
32
26
  /** Anomalistic year of date, SI seconds. @param {number} year */
33
27
  anomalisticYearSecondsAtYear: (year: number) => number;
34
- /** Axial precession period of date (equinox regression beat), years. @param {number} y */
28
+ /** Axial precession period of date (equinox regression beat), JULIAN years. @param {number} y */
35
29
  axialPrecessionYearsAtYear: (y: number) => number;
36
- /** Perihelion (apsidal-vs-equinox) precession period of date, years. @param {number} y */
30
+ /** Perihelion (apsidal-vs-equinox) precession period of date, JULIAN years. @param {number} y */
37
31
  perihelionPrecessionYearsAtYear: (y: number) => number;
38
- /** Apsidal precession period of date vs the fixed stars, years (hypersensitive: ±1 s ↔ ≈400 yr; the identifier keeps the historical "inclination" name). @param {number} y */
32
+ /** Apsidal precession period of date vs the fixed stars, JULIAN years (hypersensitive: ±1 s ↔ ≈400 yr; the identifier keeps the historical "inclination" name). @param {number} y */
39
33
  inclinationPrecessionYearsAtYear: (y: number) => number;
34
+ /** The movement's own general precession of date, ″ per Julian year (retrograde positive) — 360°/this ≡ axialPrecessionYearsAtYear to second order. @param {number} y */
35
+ generalPrecessionArcsecPerJulianYr: (y: number) => number;
36
+ /** The movement's own apsidal rate of date against the FIXED frame, ″ per Julian year (prograde positive) — the rate the Perihelion Longitudes Prec. cell shows for Earth; 360°/this ≡ inclinationPrecessionYearsAtYear exactly. @param {number} y */
37
+ apsidalRateFixedArcsecPerJulianYr: (y: number) => number;
40
38
  /** The per-cardinal layer (D6 rules: year lengths λ̇-corrected; offsets/spreads raw — μs-class/second-order there). */
41
39
  cardinal: Readonly<{
42
40
  /** @param {number} y @param {'VE'|'SS'|'AE'|'WS'} type */
package/types/model.d.ts CHANGED
@@ -61,11 +61,11 @@ export function assembleModel(C: Readonly<Record<string, any>>, F: Readonly<Reco
61
61
  nodalPeriodYears: number;
62
62
  /** The obliquity beat 2π/(ψ̇(t) − |s₃|), years — the SHIPPED deep-time obliquity period (falsification leg 1; 41,224 at J2000, on the composed rate). @param {number} year @returns {number} */
63
63
  obliquityBeatYearsAtYear: (year: number) => number;
64
- /** The apsidal (perihelion vs the stars) period from the engine-D chain's secular tangent, years — inside the published window only (the tangent is an extrapolation beyond the banked series: it turns negative at −5 Myr); null beyond. @param {number} year @returns {number|null} */
64
+ /** The apsidal (perihelion vs the stars) period of date, JULIAN years — the ONE movement's own apsidal rate (the scene's perihelion; anom/(anom − sid) of the one family, ≡ 360°/apsidalRateFixedArcsecPerJulianYr), inside the published window only; null beyond. Before 2026-09 this rode the planet chain's secular tangent, which parted from the scene's perihelion passages by seconds of anomalistic year within a few millennia (year-lengths.cjs). @param {number} year @returns {number|null} */
65
65
  apsidalPeriodYearsAtYear: (year: number) => number | null;
66
66
  /** T_aps(t) / T_p(t) — the apsidal period in of-date precession periods (4.33 at J2000, a reading; 0.84 … 9.9 across ±26 kyr, measured); null beyond the published window. @param {number} year @returns {number|null} */
67
67
  apsidalPerPrecessionAtYear: (year: number) => number | null;
68
- /** T_peri(t) = 1/(1/T_p + 1/T_aps) — the perihelion-of-date period (equinox precession + inertial perihelion motion, frame arithmetic at every epoch), years, on the of-date T_p; null beyond the published window. @param {number} year @returns {number|null} */
68
+ /** T_peri(t) = 1/(1/T_p + 1/T_aps) — the perihelion-of-date period (equinox precession + inertial perihelion motion, frame arithmetic at every epoch), JULIAN years, on the of-date T_p — ≡ the one family's anom/(anom − trop); null beyond the published window. @param {number} year @returns {number|null} */
69
69
  periOfDatePeriodYearsAtYear: (year: number) => number | null;
70
70
  /** T_peri(t) / T_p(t) (0.812 at J2000 — the J2000 reading); null beyond the published window. @param {number} year @returns {number|null} */
71
71
  periOfDatePerPrecessionAtYear: (year: number) => number | null;
@@ -116,6 +116,8 @@ export function assembleModel(C: Readonly<Record<string, any>>, F: Readonly<Reco
116
116
  axialPrecessionYearsAtYear: (y: number) => number;
117
117
  perihelionPrecessionYearsAtYear: (y: number) => number;
118
118
  inclinationPrecessionYearsAtYear: (y: number) => number;
119
+ generalPrecessionArcsecPerJulianYr: (y: number) => number;
120
+ apsidalRateFixedArcsecPerJulianYr: (y: number) => number;
119
121
  cardinal: Readonly<{
120
122
  yearLengthSeconds: (y: number, type: "VE" | "SS" | "AE" | "WS") => number;
121
123
  eocOffsetSeconds: (y: number, type: "VE" | "SS" | "AE" | "WS") => number;