The project owner holds the permits for over-the-air work, so legality is
not a constraint this document should be reasoning about.
- retitle the section from "safety requirements" to what it actually
covers: circuit integrity and not destroying the hardware
- rewrite the antenna rule on its real technical ground. An antenna opens
a radiating path in parallel with the cable, so the level at the
receiver stops matching the budget and reflections appear; the value of
a cable loopback is that everything in it is known
- reframe "no over-the-air" as a scope boundary against Lab044 rather
than a prohibition
- note in the roadmap that Lab044 is purely a technical choice of band,
power and antenna
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The bench has an AT30S: 30 dB, SMA, rated to 200 W. That removes the last
hardware blocker and changes the safety analysis.
With 30 dB in line, TX at full 0 dB gain lands at about -23 dBm on the
receiver, some 25 dB below the +2.5 dBm damage threshold. The whole
tx_hardwaregain range is therefore safe, so the staged -60 dB start and
the -30 dB ceiling are no longer needed.
- record the attenuator in the inventory and note that its 200 W rating is
irrelevant here, attenuation does not depend on level
- replace the interim procedure with a level budget table and a starting
point of -30 dB, giving about -53 dBm at the receiver
- require a visual check that the attenuator is actually in the path
before the first transmit
- keep the ban on running without it: it guards against operator error,
not against the calculated level
Only the environment blocker is left: pyadi-iio and libiio are missing
from the interpreter on PATH.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hardware confirmed from a photo of the bench: the device is a Pluto+
(2RX/2TX, Gigabit Ethernet), not the stock ADALM-PLUTO, plus an RTL-SDR
dongle and several antennas. No attenuator on hand.
- record the actual inventory and the Pluto+ differences that matter:
Ethernet transport, two channels, adi.Pluto first with adi.ad9361 as
the only permitted fallback
- replace "use an attenuator" with numbers: TX puts out about +7 dBm at
0 dB, the RX damage threshold is about +2.5 dBm, so give a staged gain
procedure starting at -60 dB and capped at -30 dB until an attenuator
arrives
- require the antennas to be physically removed from the bench rather
than merely left unplugged
- add the environment blocker found on inspection: the interpreter on
PATH is a standalone Python 3.13.1 without pyadi-iio, libiio or scipy,
while Lab024a clearly ran somewhere else; identifying and recording
that environment is now the first task
- renumber sections and align the TX gain figure with the safety section
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Specification for the first transmission through real hardware. The
project has no TX call anywhere across Lab001-Lab041, so the whole chain
exists but has never been connected to a transmitter.
Scope is deliberately minimal: get a JPEG through a cable loopback on a
single PlutoSDR and see the picture. Single device means TX and RX share
a reference clock, which removes the carrier offset and clock drift that
the receiver chain handles weakest.
- reuse Lab018 signal parameters unchanged, so hardware is the only new
variable
- reuse image_fragments, packet, build_radio_frame, find_radio_frame
- list the first-time traps: cyclic TX buffer, sample scaling, RX started
after TX, undersized RX buffer, automatic gain, receiver saturation
- define acceptance criteria and required measurements
- state explicitly what is out of scope: retransmission, erasure coding,
higher rate, two devices, over-the-air
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Introduce tools/quick_gate.py: a one-second check that parses every file
in protocol, tests and tools, imports each protocol module, and runs the
functional tests of the labs that need no experiment data.
Wire it to a PostToolUse hook so edits under protocol or tests are checked
automatically, and add two read-only review agents with slash commands that
drive them: verifier for independent re-derivation of results, adversary for
unsafe-state hunting in control, failsafe, session and reset code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audit found seven numbers in simulate_trial that were neither modelled by
Lab041 nor traceable to their claimed source. Video fraction 0.910 did not
match Lab040 (0.9603); base queue length 31 did not match Lab040 (36-38).
- drop video/telemetry/control delivered fractions and queue length: these
belong to Lab037 and Lab040 and are not modelled here
- drop lab041_traffic_impact.png, which plotted only those metrics
- drop negative_speed_cases and speed_limit_exceeded_cases, never computed,
along with the tautological asserts that checked them
- bind braking parameters to the Lab039 nominal profile via named constants
instead of the literals 0.250 and the divisor 6.0
- cite Lab038 as the source of the transferred video and telemetry loads
- rewrite the invariants section: nine architecture-derived properties now
carry functional-check references, five unmeasurable ones move to their
own section
- extend check 04 with negative speed and the 15 m/s boundary
- state explicitly what the matrix rolls, what the architecture fixes and
what is not modelled at all
Regenerated: 180 combinations, 24/24 checks, five CSV and seven PNG.
Six columns removed, no retained value changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>