151 lines
5.2 KiB
Markdown
151 lines
5.2 KiB
Markdown
TASK_ID = RF001A_OTA_TX_004
|
||
TASK_TITLE = Send one finite RF-001A burst into RX capture 004
|
||
SOURCE_BRANCH = video-development
|
||
EXPECTED_HEAD = 168e03d9e778ab2ec63502552d385ec7be3ef677
|
||
REQUIRES_APPROVAL = YES
|
||
HARDWARE_ACCESS = YES
|
||
RF_RX = NO
|
||
RF_TX = YES
|
||
ALLOW_COMMIT = NO
|
||
ALLOW_PUSH = TX_RESULT_ONLY
|
||
RISK_LEVEL = RED
|
||
|
||
---
|
||
|
||
# RF-001A TX 004
|
||
|
||
This task is prepared only. Do not execute it now. Old approval for any earlier
|
||
TASK_ID is invalid. The MAIN watcher waits for a fresh
|
||
`RF001A_OTA_CAPTURE_004` READY event from `origin/rx-node`.
|
||
|
||
## 1. Watcher gate
|
||
|
||
The watcher must require all of the following:
|
||
|
||
- RX TASK_ID = `RF001A_OTA_CAPTURE_004`;
|
||
- state = `RX_READY_FOR_TX`;
|
||
- source HEAD is the current `video-development` HEAD;
|
||
- COMMON_CLOCK_VERIFIED = YES;
|
||
- live child and growing capture are both true;
|
||
- planned RX duration is 59–61 seconds;
|
||
- READY is no more than 30 seconds old;
|
||
- at least 10 seconds remain in the capture window;
|
||
- the observed commit is the current valid `origin/rx-node` HEAD.
|
||
|
||
The watcher then requests exactly:
|
||
|
||
AUTHORIZE RF TX
|
||
|
||
Any other response blocks TX. After the exact phrase, fetch `origin/rx-node`
|
||
again and repeat every commit, digest, task, source HEAD, freshness, common
|
||
clock and remaining-time check. A changed or stale result requires a new RX
|
||
capture and a new exact RED approval.
|
||
|
||
On success publish a schema-version-2 `TX_AUTHORIZED` event to `origin/tx-node`
|
||
with the exact source RX commit and digest, TX TASK_ID `RF001A_OTA_TX_004`,
|
||
`RF_TX_AUTHORIZED = YES`, `RF_TX_STARTED = NO` and `RF_TX = 0`. Also write the
|
||
local authorization record. This event is permission evidence, not proof of a
|
||
transmission.
|
||
|
||
## 2. Read-only TX preflight
|
||
|
||
Before opening TX hardware:
|
||
|
||
1. Run `git pull --ff-only origin video-development`.
|
||
2. Require branch `video-development`, a clean tracked worktree and local HEAD
|
||
equal to `origin/video-development`; `EXPECTED_HEAD` must be its ancestor.
|
||
3. Run `hackrf_info`; require TX serial
|
||
`000000000000000097c063dc323b97d3`.
|
||
4. Require the recorded MASTER CLKOUT command = PASS, both antennas connected,
|
||
approximately 2 m distance, clear LOS, and video disabled.
|
||
5. Verify the waveform without radio access:
|
||
|
||
python -B -X utf8 tools/rf001a_prepare.py --verify-dir data/raw/rf001/rf001a_common_clock_001
|
||
|
||
6. Require:
|
||
|
||
waveform path = data/raw/rf001/rf001a_common_clock_001/tx_waveform.cs8
|
||
waveform size = 17667656 bytes
|
||
waveform SHA256 = 75f3fa39bfa4ee419f0676c54e4b9c486d7ff64bd0fe2fc06343b20c9d117ecd
|
||
sample count = 8833828 complex samples
|
||
duration = 1.1042285 s
|
||
offline exact packets = 100/100
|
||
|
||
If any value differs, do not transmit.
|
||
|
||
## 3. Final executor gate
|
||
|
||
Immediately before hardware access, the controlled executor must read the
|
||
local authorization and re-fetch `origin/rx-node`. Require:
|
||
|
||
- TX TASK_ID = `RF001A_OTA_TX_004`;
|
||
- RX TASK_ID = `RF001A_OTA_CAPTURE_004`;
|
||
- authorization phrase = `AUTHORIZE RF TX`;
|
||
- authorization binds the current READY commit and digest;
|
||
- `rf_tx_started = false` and `rf_tx = 0` in the authorization record;
|
||
- at least 10 seconds remain in the same READY window.
|
||
|
||
If any check fails, do not open HackRF.
|
||
|
||
## 4. One finite TX burst
|
||
|
||
Only after all gates pass may the executor create a 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
|
||
|
||
Never add repeat mode and never retry automatically.
|
||
|
||
At the exact process start, publish `TX_STARTED` to `origin/tx-node`, preserving
|
||
the authorization binding and recording `TX_STARTED_AT` as accurately as the
|
||
host permits. Set `RF_TX_STARTED = YES` and `RF_TX = 1` because this event is
|
||
evidence of an actual started process.
|
||
|
||
Write the strict schema-version-2 event JSON outside Git and publish it with:
|
||
|
||
python -B tools/tx_agent_watcher.py --publish-tx-event <started-json> --acknowledgement-branch tx-node
|
||
|
||
After that exact process exits, publish `TX_COMPLETE` with `TX_FINISHED_AT`,
|
||
the integer process exit code, underrun count and error count. Preserve the
|
||
complete stdout and stderr outside Git. The event reports what happened; it
|
||
does not by itself prove that packets were received. Captured IQ remains the
|
||
source for exact packet verification.
|
||
|
||
Publish the completion JSON with the same `--publish-tx-event` command. The
|
||
publisher requires the matching `TX_AUTHORIZED` and `TX_STARTED` history.
|
||
|
||
The only files permitted on `tx-node` are:
|
||
|
||
docs/handoff/results/TX_RESULT.json
|
||
docs/handoff/results/TX_RESULT.md
|
||
|
||
Do not publish waveform, IQ, video, source code, local state or large logs.
|
||
|
||
## 5. Final report
|
||
|
||
TASK_ID = RF001A_OTA_TX_004
|
||
RX READY FOR TX = YES / NO
|
||
RX RESULT HEAD =
|
||
RX RESULT DIGEST =
|
||
TX AUTHORIZED EVENT = PASS / FAIL
|
||
TX STARTED AT =
|
||
TX FINISHED AT =
|
||
TX PROCESS EXIT CODE =
|
||
TX UNDERRUNS =
|
||
TX ERRORS =
|
||
TX COMPLETE EVENT = PASS / FAIL
|
||
RF TX STOPPED = YES / NO
|
||
|
||
STOP after the one finite burst and event publication. Firmware, CPLD, Zadig,
|
||
USB driver changes, clock reconfiguration, a second burst, commit or push to
|
||
`video-development` are forbidden.
|