Files
SDR-Rover/docs/handoff/NEXT_TX_TASK.md
2026-09-21 18:05:28 +03:00

6.9 KiB

TASK_ID = RF001A_OTA_TX_003 TASK_TITLE = Transmit one coordinated RF-001A QPSK burst SOURCE_BRANCH = video-development EXPECTED_HEAD = bc55d0516d REQUIRES_APPROVAL = YES HARDWARE_ACCESS = YES RF_RX = NO RF_TX = YES ALLOW_COMMIT = NO ALLOW_PUSH = NO RISK_LEVEL = RED

This file is the authoritative current task for the MAIN PC TX node. Read TX_NODE_STATE.md first. If chat history, this file, the shared RF-001A spec or current Git HEAD conflicts, stop and report the conflict.

Current TX task

TASK = TRANSMIT ONE COORDINATED RF-001A QPSK BURST

This is a new RED task. Publication of this file is not permission to transmit. It does not inherit any approval from RF001A_OTA_TX_001, RF001A_OTA_TX_002, the RX task, a previous watcher prompt or a previous RF run.

1. Coordination gate

Start the local model-free watcher before the RX task begins:

tools\start_tx_watcher.cmd

The watcher polls origin/rx-node every 5 seconds and accepts only a strict result for:

RX TASK_ID = RF001A_OTA_CAPTURE_003
STATE = RX_READY_FOR_TX
RX_READY_FOR_TX = YES
PROCESS_ALIVE = YES
FILE_GROWING = YES
COMMON_CLOCK_VERIFIED = YES
RF_TX = 0

The watcher records RF_HANDOFF_CHANNEL_TEST_001 READY and COMPLETE states without prompting for RED approval and never treats them as production readiness. A production READY publication must be no more than 30 seconds old. Its planned capture window must be 120 seconds. At least 10 seconds must remain. COMMON_CLOCK_VERIFIED must be YES, source_head must equal the expected video-development HEAD, and the result commit must be the current valid origin/rx-node HEAD.

When a valid new READY result appears, the watcher prints:

RX IS READY

TASK ID =
CAPTURE STARTED =
CAPTURE END EXPECTED =

TX TASK =
RF001A_OTA_TX_003

RF TX REQUIRES RED APPROVAL

Enter:
AUTHORIZE RF TX

Without the exact phrase AUTHORIZE RF TX, do not transmit.

After the phrase, the watcher fetches rx-node again and repeats the result commit, digest, task ID, source HEAD, READY, freshness, common-clock and capture-window checks. If the result changed or less than 10 seconds remain, it refuses authorization and requires a new RX capture.

The watcher never opens HackRF hardware. On success it writes one local authorization record under:

.local\tx_authorizations\

The record has rf_tx_started = false and rf_tx = 0. It is the handoff to the separately controlled TX executor. It is not evidence that transmission occurred.

2. Fixed RF-001A parameters

center frequency = 1400000000 Hz
sample rate = 8000000 samples/s
modulation = QPSK
symbol rate = 500000 symbols/s
inner FEC = 2/3
payload = 256 bytes
packet count = 100
inter-packet gap = 5 ms
digital carrier offset = +125000 Hz
TX VGA = 20 dB
RF amp = OFF
antenna bias = OFF
common 10 MHz reference = VERIFIED
distance = approximately 2 m
LOS = YES
video = OFF

The waveform is one finite burst. Never add repeat mode.

3. Read-only preflight

Before the watcher can request RED approval:

  1. Run git pull --ff-only origin video-development.

  2. Require branch video-development.

  3. Require git status --short --untracked-files=no to produce no output.

  4. Require local HEAD to equal origin/video-development and EXPECTED_HEAD to be its ancestor.

  5. Run hackrf_info and preserve complete stdout.

  6. Require TX serial 000000000000000097c063dc323b97d3.

  7. Require the recorded MASTER CLKOUT command result = PASS.

  8. Require confirmation that both antennas are connected, the nodes are approximately 2 m apart, and LOS is clear.

  9. Verify the prepared waveform without radio access:

    python -B -X utf8 tools/rf001a_prepare.py --verify-dir data/raw/rf001/rf001a_common_clock_001

  10. Verify the actual cs8 bytes through the existing offline receiver:

    python -B -X utf8 tools/qpsk_rf_rx.py --iq-file data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8 --iq-format cs8 --truth-metadata configs/rf/rf001a_truth_metadata.json --report \rf001a_tx_offline_verify.json

Require:

canonical waveform = PASS
hardware-format cs8 = PASS
offline hardware-format roundtrip = 100/100 exact
TX waveform path = data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8
TX waveform size = 17667656 bytes
TX waveform SHA256 = 75f3fa39bfa4ee419f0676c54e4b9c486d7ff64bd0fe2fc06343b20c9d117ecd
sample count = 8833828 complex samples
expected duration = 1.1042285 s

If any value differs, do not transmit.

4. Final check before opening TX hardware

The controlled TX executor must read the authorization record immediately before TX and require:

  • task_id = RF001A_OTA_TX_003;
  • authorization = AUTHORIZE RF TX;
  • rx_task_id = RF001A_OTA_CAPTURE_003;
  • dry_run = false;
  • action = MANUAL_EXECUTOR_GATE_OPEN;
  • rf_tx_started = false;
  • rf_tx = 0;
  • the authorization references the latest fetched rx-node result commit and digest;
  • current time is still inside the READY capture window with at least 10 seconds remaining.

Fetch origin/rx-node once more and compare its current result digest and commit with the authorization record. Re-run the READY and time checks. If anything differs, if the result is stale, or if fewer than 10 seconds remain, do not transmit and require a new RX capture and a new exact RED approval.

5. One authorized TX execution

Only after every preceding condition passes may the executor create a new unique evidence directory outside Git and run exactly one finite command:

hackrf_transfer.exe
-d 000000000000000097c063dc323b97d3
-t data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8
-f 1400000000
-s 8000000
-n 8833828
-x 20
-a 0
-p 0
-B

Run it once, synchronously, and preserve:

  • exact process PID;
  • start and end UTC timestamps;
  • exact exit code;
  • complete stdout and stderr;
  • every TX underrun line;
  • every USB error;
  • waveform path, size and SHA256;
  • command parameters.

Set RF TX STOPPED = YES only after the finite process exits. Never retry automatically. Never start a second burst.

6. Final TX report

TASK_ID =
RF001A_OTA_TX_003

RED AUTHORIZATION =
AUTHORIZE RF TX / MISSING

RX READY FOR TX =
YES / NO

RX RESULT HEAD =

RX RESULT DIGEST =

TX SERIAL =

TX WAVEFORM SHA256 =

TX START TIME =

TX END TIME =

TX EXIT CODE =

TX UNDERRUNS =

USB ERRORS =

RF TX STOPPED =
YES / NO

BURSTS TRANSMITTED =
0 / 1

RF TX =
0

At report time, RF TX = 0 means no transmission process remains active.

7. Prohibited actions

Do not:

  • transmit without the fresh READY state and exact RED phrase;
  • reuse an earlier authorization record;
  • use repeat mode;
  • transmit a second burst;
  • retry automatically;
  • change frequency, gains, clock configuration or waveform;
  • update firmware or CPLD;
  • use Zadig or change USB drivers;
  • commit or push from this task.

STOP after the single finite burst or any failed gate.