@@ -11858,6 +11858,52 @@ def test_kinematic_local_velocity_budget_uses_one_phase_speed() -> None:
1185811858 assert report["phaseSpeed"] == pytest.approx(report["relativeSpeed"], rel=1e-9), report
1185911859
1186011860
11861+ @requires_node
11862+ def test_kinematic_local_orbits_continue_when_global_gravity_is_zero() -> None:
11863+ """Zero global gravity must not disable the independent local stellar clock."""
11864+ report = _run_node(
11865+ """
11866+ const nodes = [
11867+ { id: 'black-hole', anchor_role: 'global', community_id: 'core',
11868+ system_anchor_id: 'black-hole', gravity_mass: 8, radius: 8,
11869+ x: 0, y: 0, vx: 0, vy: 0 },
11870+ { id: 'star', anchor_role: 'community', community_id: 'solar',
11871+ system_anchor_id: 'star', gravity_mass: 4, radius: 5,
11872+ x: 120, y: 0, vx: 0, vy: 0 },
11873+ { id: 'planet', community_id: 'solar', system_anchor_id: 'star',
11874+ orbit_tier: 1, gravity_mass: 1, radius: 2,
11875+ x: 150, y: 0, vx: 0, vy: 0 },
11876+ ];
11877+ const options = {
11878+ gravity: 0, softening: 32, centralSoftening: 40, localSoftening: 12,
11879+ localGravitySetting: 48, orbitalSpeed: 400, layoutSeed: 19,
11880+ timestep: .032, speedLimit: 48,
11881+ };
11882+ const angle = () => Math.atan2(nodes[2].y - nodes[1].y,
11883+ nodes[2].x - nodes[1].x);
11884+ const before = angle();
11885+ const first = I.advanceGalaxyKinematicOrbits(nodes, options);
11886+ const afterFirst = angle();
11887+ const second = I.advanceGalaxyKinematicOrbits(nodes, options);
11888+ const afterSecond = angle();
11889+ emit({ first, second,
11890+ localTravel: Math.atan2(Math.sin(afterSecond - before),
11891+ Math.cos(afterSecond - before)),
11892+ carrierTravel: Math.hypot(nodes[1].x - 120, nodes[1].y),
11893+ finite: nodes.every(node =>
11894+ [node.x, node.y, node.vx, node.vy].every(Number.isFinite)),
11895+ firstStepMoved: Math.abs(afterFirst - before) > 1e-8,
11896+ });
11897+ """
11898+ )
11899+ assert report["finite"] is True
11900+ assert report["first"]["satellites"] > 0
11901+ assert report["second"]["satellites"] > 0
11902+ assert report["firstStepMoved"] is True
11903+ assert abs(report["localTravel"]) > 1e-5
11904+ assert report["carrierTravel"] <= 1e-9
11905+
11906+
1186111907@requires_node
1186211908def test_live_carrier_is_capped_before_local_motion_budgeting() -> None:
1186311909 report = _run_node(
0 commit comments