Skip to content

Simulation config: frac_adsb_outage knob + retina-simulation bump - #332

Merged
jehanazad merged 3 commits into
mainfrom
feat/sim-adsb-outage
Sep 8, 2026
Merged

jehanazad merged 3 commits into
mainfrom
feat/sim-adsb-outage

Conversation

@jehanazad

Copy link
Copy Markdown
Contributor

Summary

Plumbs the simulator's new transponder-outage knob through the simulation config API, and bumps libs/retina-simulation to pick it up (offworldlabs/retina-simulation#13).

The simulator previously never stopped ADS-B: every transponder aircraft was tagged in every node frame and pushed every second for its whole life. That left the known-track hold (a node track claimed to a hex staying claimed once ADS-B stops) unverifiable against simulated traffic. With frac_adsb_outage an ADS-B aircraft goes silent mid-flight and comes back — has_adsb stays true, it just stops broadcasting.

Default 0.0, so nothing changes for a deployment that never sets it.

Changes

  • core/state.py: simulation_config / _SIMULATION_CONFIG_DEFAULTS gain frac_adsb_outage: 0.0. Deliberately not added to _SIM_FRAC_FALLBACKS — it is not one of the spawn-type fractions and is not env-seeded with them.
  • routes/test.py: PUT /api/simulation/config accepts frac_adsb_outage (0.0–1.0), validated by the existing frac_* range rule but excluded from the sum constraint — it is a fraction OF the ADS-B population, orthogonal to the type roll, so a dark-heavy scene at the 1.0 ceiling can still take its transponder aircraft silent. GET reports ground_truth_counts["adsb_silent"], counted alongside (not instead of) the type buckets, since a silent aircraft is still a commercial aircraft.
  • routes/sim_ingest.py: the ground-truth push whitelists adsb_silent into ground_truth_meta, defaulting False for older fleet payloads. has_adsb is untouched, so the dark count does not move when a transponder goes quiet.
  • services/state_snapshot.py: _SIM_CONFIG_RESTORE_KEYS gains the key, so an operator's setting survives a rebuild like the other fractions.
  • Submodule pin bump only for libs/retina-simulation.

Test coverage

backend/tests/test_sim_ingest.py extended alongside the existing frac_dark / scene-key cases: default is off, PUT accepted and echoed, out-of-range rejected both ends, the knob accepted at 1.0 while the type fractions already sum to 1.0 (the sum-exclusion guard), counts reporting a silent aircraft without moving the dark count, and the ground-truth meta flag with its legacy-payload default. Existing exact-dict count assertion updated for the new key.

Review notes

  • The knob only bites when the fleet polls the config; the orchestrator applies it alongside frac_dark and also re-rolls aircraft already in the air, so raising it is visible within a poll interval rather than a fleet turnover.
  • The lib PR carries the world/orchestrator side and its own tests.

🤖 Generated with Claude Code

Bump retina-simulation for the ADS-B outage knob and plumb it through the
simulation config API. frac_adsb_outage is the fraction OF the ADS-B
aircraft the simulator takes transponder-silent mid-flight, so it is
deliberately outside the frac_anomalous + frac_drone + frac_dark <= 1.0
constraint — folding it in would make a dark-heavy scene unable to test
outages at all.

The ground-truth push now stores adsb_silent in ground_truth_meta (has_adsb
stays true, so the dark count is unaffected) and GET /api/simulation/config
reports counts["adsb_silent"] beside the type buckets. The snapshot restore
whitelist keeps the new key so an operator's setting survives a rebuild.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@claude

This comment has been minimized.

The capture tooling that measures the known-track hold reads
/api/v1/ground-truth/aircraft, so the silent flag has to be visible there
as well as on the simulation config counts.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@claude

This comment has been minimized.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown

Claude finished @jehanazad's task in 1m 20s —— View job


Review: PR #332frac_adsb_outage knob + retina-simulation bump (updated after synchronize)

  • Gather context (PR description, new commit)
  • Diff new commit against previous review
  • Review submodule pin bump commit
  • Re-check prior findings for whether they were addressed
  • Post final review

This PR now has three commits. The first two (4afb1bf — the frac_adsb_outage knob/validation/snapshot-restore/submodule bump, and 03bfc82 — exposing adsb_silent on the v1 ground-truth endpoint) are unchanged from the last review and remain solid.

The new commit (67f1700, "Pin retina-simulation to main (transponder outages merged)") only re-points the libs/retina-simulation submodule:

-Subproject commit f03cae0a3fad80c6868125dde1c1ca5525508730
+Subproject commit f06d534709c45dac18d1dd24df99e27ec95138a1

This moves the pin off the feature-branch commit (f03cae0, set in the first commit of this PR) onto retina-simulation's main now that offworldlabs/retina-simulation#13 has merged. That's the right thing to do before this PR itself merges — it avoids retina-server's main ever depending on an unmerged branch of the submodule. No backend code changed in this commit, so nothing here alters the earlier analysis.

Note: I can't inspect the submodule's actual diff between those two commits in this sandbox — libs/retina-simulation isn't checked out locally and I don't have network access to fetch it here. Worth a quick sanity check that f06d534 is genuinely retina-simulation's main tip (not a stray commit) before merging.

Carried forward from the last review (still unaddressed, both minor/non-blocking):

  1. No test coverage for adsb_silent on the v1 endpoint (backend/tests/test_output_routes.py). backend/routes/output.py:143 gained "adsb_silent": meta.get("adsb_silent", False) but no test asserts it, present or defaulted. Mirrors what test_sim_ingest.py already does for the ingest side.
    Fix this →
  2. docs/simulation.md config table still missing frac_adsb_outage (around lines 69-75, unchanged). frac_anomalous, frac_drone, frac_dark are documented; the new knob and the adsb_silent ground-truth field aren't.
    Fix this →
  3. Frontend Physics tab still not wired to the new knob (frontend/src/components/PhysicsSettings.tsx) — flagged again only for completeness; likely deferred deliberately.

I wasn't able to execute pytest, the pre-commit gate, or fetch the submodule in this sandboxed environment (no approved network/bash access here), so please confirm CI is green.

@jehanazad
jehanazad merged commit 9e7a22a into main Sep 8, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant