Skip to content

Instantly share code, notes, and snippets.

@ErikEvenson
Created July 6, 2026 18:23
Show Gist options
  • Select an option

  • Save ErikEvenson/584f0c4692b74b85e44513082e08e812 to your computer and use it in GitHub Desktop.

Select an option

Save ErikEvenson/584f0c4692b74b85e44513082e08e812 to your computer and use it in GitHub Desktop.
reviewer-ratify: ErikEvenson/galaxy#1397 lever (B) SP1 — compute-adaptive deferral / forward-anchor (RATIFY + CT-3 sharpened + B-minimal)

reviewer-ratify: ErikEvenson/galaxy#1397 lever (B) SP1 — compute-adaptive deferral / forward-anchor

Engagement: ErikEvenson/galaxy#1397 (LEG-2 live-dock freshness wall) Reviews: implementer SP1 gist d0466bd3028ddea4ac9a49306d6c3f04 ([implementer-publish] on #1397) Reviewer prior: 20b2d5d7 (§2-B framing, risks i/ii/iii) HEAD verified: c5a7e750d376641ab2b6c6299cb574cb9792daf9 (main, clean) Artifact: SP1 design + control-test-plan review (no code, no cluster mutation) Ball after this: IMPLEMENTER (SP2 — implement B-minimal + run CT-1/2/3, control-test-first, CT-3 dispositive)


§1 — Disposition

RATIFY SP1. Design verified against code (high confidence). CT-3 is honest as specified — ratified with two explicit sharpenings (S1, S2 below) that make it exercise the actual adaptive-Δ code path rather than a proxy. B-minimal ratified as the smallest extension and confirmed milestone-compatible. Contingency-C stays parked for post-CT-3-RED, not now. SP2 routed to the implementer with one added hard condition (R7 crash-watchdog).

The implementer did the right thing: FEASIBLE-PENDING-MEASUREMENT, one dispositive gate isolated (CT-3 / risk i), no force-fit GREEN. Concur.


§2 — Design verification against HEAD c5a7e750d (I did not take the SP1 on faith)

SP1 claim Verified Evidence
forward-prop primitive exists, Δ=90 s planner.py:6730-6739 _propagate_test_particle_via_oracle(r_ship,v_ship, SCHEDULE_SNAPSHOT_DEFERRAL_S,…), ship + target
oracle built with horizon covering Δ planner.py:6696 horizon_s = max_planning_horizon_s + SCHEDULE_SNAPSHOT_DEFERRAL_S
same 28-body integration, NOT lossy extrapolation strong planner.py:2492 _propagate_test_particle_via_oracle calls physics_core.simulate_trajectory_encke with no burns; docstring: "bit-identical to a no-thrust ship integrated by the cost function over the same horizon" — the same Encke + perturber-trajectory the cost function uses. This is the load-bearing "not lossy" claim; confirmed at the kernel.
Δ is already fully parameterized — only the value is literal oracle-horizon (:6696), ship/tgt pre-prop (:6731,:6736), cost-slice offset post_prep_offset_idx = round(Δ/sub_dt) (:6773), consumer anchor new_start = request_gt + OFFSET (consumer.py:548-551) — all read the literal; making Δ per-request touches exactly these + the executor mirror
#1104/#1106 is why 90 s error ≈ 0 today planner.py:6716-6729 comment: pre-prop replaced two-body _kepler_step (5c) with oracle N-body prop, eliminating the 137 km #1104 drift; anchor consumer.py:548-575 = request.game_time + OFFSET (#1106)
lock constant is game-engine state.py:664, not planner.py:597 ✅ (SP1 refinement correct) state.py:664 PLANNING_LOCK_TIMEOUT_REAL_S = 120.0; acquire forces time_scale→1.0 (state.py:699-705); cleanup prunes >120 s + restores saved scale (tick_loop.py:1316-1346)
slack mechanism slack ≈ Δ − wall under the freeze producer stale-flag consumer.py:559 slack_s ≤ SCHEDULE_SLACK_FLOOR_S(0.0)stale_on_arrival=True; game-time on both sides (time-scale-invariant)
#1378 refuse-to-arm gate to PRESERVE schedule_executor.py:200 is_stale_on_arrival, used :1425 → routes _STALE_REVALIDATE_REASON :1442
three-copy deferral literal (single-source hazard) consumer.py:34 SCHEDULE_PUBLISH_OFFSET_S=90.0, planner.py:1222 SCHEDULE_SNAPSHOT_DEFERRAL_S=90.0, schedule_executor.py:173 SCHEDULE_DEFERRAL_BUDGET_S=90.0 — R4 per-request-field fix is right; precedent request.expected_time_scale (consumer.py:504-510) confirmed
~16.4 km approach gate is geometry-scaled gates.py:52-62 approach_entry = max(APPROACH_ENTRY_FLOOR_M, APPROACH_ENTRY_FRACTION × 2π·target_a)

Mechanism ratified: lever (B) = (1) carry Δ as one per-request deferral_s field (retires the three-copy literal), (2) thread it through the four already-parameterized planner/consumer sites + the executor mirror, (3) raise the lock timeout ≥ Δ so time_scale=1.0 spans the whole solve → game_elapsed ≈ wallslack ≈ Δ − wall > 0. This is a magnitude-extension of a shipping primitive, not a new subsystem. Confidence: high — every load-bearing site checked at the kernel, not the comment.


§3 — CT-3 scrutiny (the dispositive gate — scrutinized hardest)

CT-3 decides feasible-vs-contingency-C, so it must be honest: independent ground truth, actual Δ, actual gate. Verdict: honest as specified, with two sharpenings to lock in.

3.1 Independent ground truth — CONFIRMED genuinely independent (not vacuous)

The concern the tests-must-use-independent-ground-truth rule guards against: CT-3 comparing the planner's oracle against the planner re-running its own oracle. That is not what CT-3 does. I traced both integration paths:

  • Forward-prop under test (planner): _propagate_test_particle_via_oraclesimulate_trajectory_encke against a frozen, one-shot pre-sampled perturber trajectory (oracle built once at request.game_time).
  • Ground truth (live game-engine — the authority the executor trusts): the tick loop advances bodies via physics_core.propagate_bodies_leapfrog plus reanchor_bodies per-tick secular-phase correction (nbody.py:157), and advances the chaser via _update_orbital_object_enckeencke_substep_loop against those live-coupled, reanchored bodies, sub-stepping at MAX_PHYSICS_DT (0.5 s), re-resolving the Encke reference body per tick (simulation.py:926-1065).

These are genuinely divergent inputs over Δ, even though both bottom out on shared Rust kernels:

  1. frozen pre-sampled field vs live-coupled field — the oracle's perturber trajectory does NOT get the live per-tick reanchor_bodies secular-phase nudge; the live engine does. Over 90 s this divergence is ~0 (the #1104/#1106 result); over ~500 s the un-reanchored leapfrog phase-walk is a primary error source — exactly risk (i)/(iii).
  2. per-tick Encke reference re-resolution vs the planner's fixed one-shot frame.
  3. sub-step granularity — live MAX_PHYSICS_DT=0.5 s vs oracle sub_dt.

So CT-3's error ‖r_pred − r_actual‖ measures the real frozen-field-vs-live-coupled divergence at the extended Δ. Not self-referential — ratified. (a) satisfied.

3.2 Actual geometry + actual Δ — satisfied, with sharpening S1

CT-3 runs at the dockable geometry and full Δ (~500 s). S1 (make explicit): the oracle in CT-3 MUST be built at horizon_s = max_planning_horizon_s + Δ (the §3.3 / planner.py:6696 adaptive-Δ horizon), i.e. perturber_traj_pos must span the full ~500 s. If CT-3 reuses a 90-s-horizon oracle the propagation clamps/runs out of samples and measures garbage. Building at horizon ≥ Δ makes CT-3 exercise the actual adaptive-Δ code path — which doubles as a smoke-test of the SP2 change, not a proxy. (b) satisfied under S1.

3.3 Pass/fail bar — satisfied, with sharpening S2

Bar = the geometry-scaled ~16.4 km approach gate (gates.py:52). Correct. S2 (make explicit): the live-engine ground-truth advance over Δ must be a pure no-thrust coast (no burns fire in [t0, t0+Δ] — true by construction: the schedule hasn't armed; burns start at start_game_time = t0+Δ) and must be deterministic (paused cluster, fixed-dt ticks, no RNG — the DE seed is planner-side only; the sim leapfrog+Encke is deterministic). Both conditions make r_actual@Δ the reproducible authority and apples-to-apples with the no-burn test-particle prop. (c) satisfied under S2.

CT-3 disposition: honest and dispositive as specified; ratified with S1 (oracle horizon ≥ Δ) and S2 (deterministic pure-coast ground-truth advance) folded in. RED (error ≥ gate) → risk (i) fatal → HALT-and-publish contingency-C to Erik; do not tune Δ upward to chase it (that is the third-tweak trap R8, and Δ-chasing cannot fix a stale-in-position snapshot).


§4 — B-minimal vs B-structural (SP2 variant call)

Ratify B-minimal for SP2. It is milestone-compatible. Here is the load-bearing reasoning:

The #1397 milestone is a continuous unobserved from-pad run. The apparent objection to B-minimal is its "~500 s real-time game freeze." That phrasing overstates the cost — and the correction is the whole call:

  1. time_scale=1.0 is NOT a pause; it is de-acceleration. A pause is _cached_paused → the tick batch breaks and no ticks fire (tick_loop.py). time_scale only governs game-seconds per wall-second. At 1.0 the sim keeps ticking — bodies advance, the chaser keeps coasting, ~500 game- seconds still elapse over the ~500 s wall window. Game-time never stops. The run stays continuous. That is precisely why the forward-anchor pre-props the chaser forward by Δ≈500 s — because the chaser really does move through those 500 s. Continuity — the milestone's actual semantic — is preserved.

  2. The freeze is an already-shipped, already-milestone-accepted behavior — B-minimal only extends its duration. acquire_planning_lock already forces time_scale→1.0 for up to 120 s on every planning solve today (state.py:699-705, the #1104 compute-time-deviation bound). B-minimal introduces no new mechanism; it raises the timeout so the existing 1× window covers the ~500 s dockable solve instead of capping at 120 s. Since the demonstration is unobserved, the only visible effect is that the sim doesn't fast-forward during the single LEG-2 dockable solve — no observer is watching it not-accelerate, and no tick is skipped.

  3. B-minimal preserves #1378 triviallyschedule_executor.py untouched; the snapshot stays honest by freeze AND forward-prop. Confidence: high on milestone-compatibility.

B-structural (decouple lock from time_scale, run at saved Nx during compute) is correctly deferred: it re-opens the #1104 137 km exposure (Δ must cover wall × time_scale, and the operator can change time_scale mid-solve — Δ becomes coupled to a live, mutable quantity), i.e. the risk-(ii) re-arch. Adopt B-structural only if a future campaign genuinely needs the sim to keep accelerating through the dockable solve. For the #1397 from-pad demo it buys nothing the milestone needs. Call: B-minimal now; B-structural parked as a named follow-on, not a blocker.


§5 — SP2 routing (implementer)

Ratified scope for SP2, control-test-first:

  1. Implement B-minimal: (a) add request.deferral_s (per-request Δ, submitter-tagged by solve- class — dockable ≈ 550-600 s, fast ≈ 90 s; single source, retires the three-copy literal, mirrors the expected_time_scale tag pattern); (b) thread Δ through the four planner/consumer sites (§3.3)

    • the schedule_executor.py:173 mirror + the determinism guard test; (c) raise PLANNING_LOCK_TIMEOUT_REAL_S ≥ Δ for the dockable class only.
  2. R7 is a hard condition, not optional (I verified it): the 120-s prune in _planning_lock_cleanup_loop (tick_loop.py:1316-1346) is also the planner-crash recovery ("a hard planner crash leaves the lock held forever"). Raising the timeout to ~600 s must NOT defeat crash recovery. SP2 must keep a separate hard crash-watchdog distinct from the freshness Δ — e.g. a planner-thread liveness heartbeat, or max(Δ, wall_ceiling)+buffer as a distinct crash timeout — so a genuinely hung planner is still reclaimed. Do not let the freshness budget swallow the crash budget.

  3. Run the control tests, CT-3 dispositive: CT-1 (fresh-AND-dockable flip stale→fresh solely by Δ), CT-2 (#1378 stale-fire PRESERVED under the parameterized-Δ path — test_freshness_gate_1378 stays GREEN), CT-3 with S1 + S2 folded in (frozen-oracle prop vs live-engine deterministic pure-coast advance at horizon ≥ Δ, vs the 16.4 km gate). CT-3 GREEN → the live dock (coordinator's step, trips the sudo gate — operator auth). CT-3 RED → HALT-and-publish contingency-C to Erik (C1 offline-dock+segment-rescope / C2 fund-lock-re-arch); do not Δ-chase (R8).

  4. Third-tweak guard (R8): Δ is a new structural mechanism, not a knob re-tune — first adjustment is clean. But a further adjustment of Δ or the lock timeout inside SP2 fires the third-tweak rule → HALT + publish rather than tune.

No escalation. Design is sound, CT-3 can be made honest (and is, under S1/S2), B-minimal is milestone-safe. Contingency-C remains parked for a CT-3 RED, per the implementer's own gate.


§6 — Self-check

  • Reviewer artifact only — no galaxy-repo edits, no cluster mutation.
  • Every load-bearing SP1 site independently verified at HEAD c5a7e750d (§2), incl. the "not lossy" claim at the simulate_trajectory_encke kernel and the CT-3 ground-truth independence at both integration paths.
  • CT-3 scrutinized against tests-must-use-independent-ground-truth — confirmed independent (frozen pre-sampled field vs live reanchored coupled field), not self-referential.
  • Fully-qualified ErikEvenson/galaxy#NNNN refs throughout.
  • B-minimal/B-structural adjudicated with an explicit milestone-semantics argument (continuity preserved; 1× ≠ pause).
  • Did NOT self-close #1397. Ball → implementer for SP2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment