280 lines
8.6 KiB
Markdown
280 lines
8.6 KiB
Markdown
TASK_ID = RF001A_OTA_CAPTURE_002
|
|
TASK_TITLE = Start coordinated RF-001A common-clock OTA capture
|
|
SOURCE_BRANCH = video-development
|
|
EXPECTED_HEAD = 34f5ace54540f947311ada7e81a463c08abfd2d3
|
|
REQUIRES_APPROVAL = YES
|
|
HARDWARE_ACCESS = YES
|
|
RF_RX = YES
|
|
RF_TX = NO
|
|
ALLOW_COMMIT = NO
|
|
ALLOW_PUSH = RX_RESULT_ONLY
|
|
RISK_LEVEL = YELLOW
|
|
|
|
This file is the authoritative current task for the RX laptop.
|
|
The RX assistant must read RX_NODE_STATE.md first, then execute this file.
|
|
If chat history conflicts with these files, the shared RF-001A spec or current Git HEAD, stop and report the conflict.
|
|
|
|
# Current RX task
|
|
|
|
TASK =
|
|
START COORDINATED RF-001A COMMON-CLOCK OTA CAPTURE
|
|
|
|
This is a new YELLOW task. Do not reuse approval or completion state from RF001A_OTA_CAPTURE_001 or any earlier task.
|
|
|
|
One approval for this task covers its read-only checks, bounded RF RX capture, and publication of the two small allowlisted result files to the existing rx-node branch. It never authorizes RF TX.
|
|
|
|
## 1. Preconditions
|
|
|
|
After the user chooses [A] Approve for this exact TASK_ID:
|
|
|
|
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 RX serial 000000000000000097c063dc2e5327d3.
|
|
7. Confirm that configs/rf/rf001a_common_clock.json exists and matches the fixed RF-001A frequency, sample rate, modulation and common-clock plan.
|
|
8. With MASTER CLKOUT physically connected to SLAVE CLKIN, run:
|
|
|
|
hackrf_clock.exe -d 000000000000000097c063dc2e5327d3 -i
|
|
|
|
9. Preserve complete stdout and require the exact line:
|
|
|
|
CLKIN status: clock signal detected
|
|
|
|
10. Require the remote branch origin/rx-node to exist. Do not create it in this task.
|
|
11. Create a unique capture directory outside Git. Refuse an existing directory and never overwrite an earlier capture.
|
|
12. Require at least 2500000000 free bytes on the target volume. Record the measured free-byte count.
|
|
|
|
If any condition fails, do not start capture. Report the failed condition, keep RF TX = 0, and STOP.
|
|
|
|
## 2. Authorized bounded RX capture
|
|
|
|
Only this finite receive operation is authorized:
|
|
|
|
RX serial = 000000000000000097c063dc2e5327d3
|
|
center frequency = 1400000000 Hz
|
|
sample rate = 8000000 samples/s
|
|
RX LNA = 24 dB
|
|
RX VGA = 24 dB
|
|
RF amp = OFF
|
|
antenna bias = OFF
|
|
duration = 120 s
|
|
sample count = 960000000 complex samples
|
|
hardware format = cs8
|
|
expected file size = 1920000000 bytes
|
|
common clock = DETECTED
|
|
|
|
The hackrf_transfer.exe arguments are fixed:
|
|
|
|
-d 000000000000000097c063dc2e5327d3
|
|
-r <unique_capture_path>\rf001a_ota_capture.cs8
|
|
-f 1400000000
|
|
-s 8000000
|
|
-n 960000000
|
|
-l 24
|
|
-g 24
|
|
-a 0
|
|
-p 0
|
|
-B
|
|
|
|
Do not add repeat mode. Do not change gain, clock, frequency or sample rate.
|
|
|
|
## 3. Background runner and durable evidence
|
|
|
|
Use a local runner outside Git. The runner must:
|
|
|
|
- start exactly one hackrf_transfer child;
|
|
- record its PID and start time immediately;
|
|
- record the expected end time as start time plus 120 seconds;
|
|
- redirect complete stdout and stderr to unique local files;
|
|
- wait for that exact child;
|
|
- record its exact exit code, finish time, duration and output size;
|
|
- calculate SHA256 after the file is closed;
|
|
- write started and final JSON atomically;
|
|
- never start a second capture automatically.
|
|
|
|
Start the runner as a controlled background process. Within five seconds, require all four facts:
|
|
|
|
runner process alive = YES
|
|
hackrf_transfer child alive = YES
|
|
capture file created = YES
|
|
capture file growing = YES
|
|
|
|
If any fact is false, publish no READY state. Preserve local evidence, report RX CAPTURE STARTED = NO, keep RF TX = 0, and STOP.
|
|
|
|
## 4. Publish READY immediately
|
|
|
|
As soon as the child is alive and the file is growing, build a local JSON file outside Git with every field below:
|
|
|
|
{
|
|
"schema_version": 1,
|
|
"task_id": "RF001A_OTA_CAPTURE_002",
|
|
"state": "RX_READY_FOR_TX",
|
|
"rx_ready_for_tx": true,
|
|
"process_alive": true,
|
|
"file_growing": true,
|
|
"capture_pid": <actual positive child PID>,
|
|
"published_at": "<current UTC ISO-8601 time>",
|
|
"capture_started_at": "<actual UTC ISO-8601 start time>",
|
|
"expected_capture_end": "<start time plus 120 seconds>",
|
|
"capture_path": "<absolute local capture path>",
|
|
"common_clock_verified": true,
|
|
"source_head": "<current local 40-character Git HEAD>",
|
|
"rf_tx": 0,
|
|
"exit_code": null,
|
|
"file_size": null,
|
|
"duration_seconds": null,
|
|
"overruns": null,
|
|
"usb_errors": null,
|
|
"file_errors": null,
|
|
"sha256": null,
|
|
"clkin_after": "NOT_RUN",
|
|
"rf_tx_observed": "UNKNOWN"
|
|
}
|
|
|
|
Publish it with the approved RX watcher state:
|
|
|
|
python -B tools/rx_agent_watcher.py --publish-result <ready-json-path> --result-branch rx-node
|
|
|
|
The publisher may change only:
|
|
|
|
docs/handoff/results/RX_RESULT.json
|
|
docs/handoff/results/RX_RESULT.md
|
|
|
|
It uses a temporary checkout of the existing rx-node branch. It must not switch the source checkout, push video-development, or add raw IQ, video, waveform or large logs.
|
|
|
|
If publication fails, show the complete error. Do not claim RX READY FOR TX and do not trigger TX automatically. The finite capture may finish normally, but RF TX remains 0.
|
|
|
|
After successful publication, immediately return control to the user without waiting for capture completion:
|
|
|
|
TASK_ID =
|
|
RF001A_OTA_CAPTURE_002
|
|
|
|
RX CAPTURE STARTED =
|
|
YES
|
|
|
|
RX READY FOR TX =
|
|
YES
|
|
|
|
CAPTURE PID =
|
|
|
|
CAPTURE PATH =
|
|
|
|
CAPTURE START TIME =
|
|
|
|
EXPECTED CAPTURE END =
|
|
|
|
RX RESULT PUBLISH =
|
|
PASS
|
|
|
|
RF TX =
|
|
0
|
|
|
|
The READY state describes a live receiver only. It does not authorize RF TX on either computer.
|
|
|
|
## 5. Capture completion
|
|
|
|
After the child exits, read the durable final status. Preserve all local logs and inspect every line for RX overruns, USB errors and file write errors. Do not infer zero when a tool did not report a counter; use JSON null and report NOT_REPORTED.
|
|
|
|
Run the read-only clock check again:
|
|
|
|
hackrf_clock.exe -d 000000000000000097c063dc2e5327d3 -i
|
|
|
|
Require CLKIN to remain detected. The expected complete capture has:
|
|
|
|
exit code = 0
|
|
file size = 1920000000 bytes
|
|
duration = consistent with 120 s
|
|
RX overruns = 0 or NOT_REPORTED
|
|
USB errors = 0 or NOT_REPORTED
|
|
file write errors = 0 or NOT_REPORTED
|
|
CLKIN after capture = DETECTED
|
|
|
|
A shorter file is incomplete. Any reported nonzero error remains evidence. Do not retry automatically.
|
|
|
|
## 6. Publish final result
|
|
|
|
Build a second local JSON document with the same identity and timing fields. Set:
|
|
|
|
state = CAPTURE_COMPLETE
|
|
rx_ready_for_tx = false
|
|
process_alive = false
|
|
file_growing = false
|
|
exit_code = <exact integer>
|
|
file_size = <actual integer bytes>
|
|
duration_seconds = <actual number>
|
|
overruns = <integer or null when not reported>
|
|
usb_errors = <integer or null when not reported>
|
|
file_errors = <integer or null when not reported>
|
|
sha256 = <lowercase 64-character SHA256>
|
|
clkin_after = DETECTED or NOT_DETECTED
|
|
rf_tx_observed = EXPECTED_EXTERNAL_TX or UNKNOWN
|
|
published_at = <current UTC ISO-8601 time>
|
|
rf_tx = 0
|
|
|
|
Use EXPECTED_EXTERNAL_TX only when the coordinated MAIN TX event is known to have occurred inside this capture window. Otherwise use UNKNOWN.
|
|
|
|
Publish with:
|
|
|
|
python -B tools/rx_agent_watcher.py --publish-result <final-json-path> --result-branch rx-node
|
|
|
|
If the push fails, preserve the local JSON and logs, report the error, and do not claim publication success.
|
|
|
|
## 7. Offline decode
|
|
|
|
Do not start automatic decode unless synchronized truth metadata for this exact transmitted waveform is available and consistent. If it is absent, preserve the IQ file and report:
|
|
|
|
OFFLINE DECODE = BLOCKED_BY_TRUTH_METADATA
|
|
|
|
Do not modify the receiver or invent results.
|
|
|
|
## 8. Prohibited actions
|
|
|
|
On the RX laptop, do not perform:
|
|
|
|
- RF TX;
|
|
- continuous RX;
|
|
- automatic capture retry;
|
|
- firmware or CPLD update;
|
|
- hackrf_spiflash;
|
|
- Zadig or USB driver changes;
|
|
- clock reconfiguration;
|
|
- commit or push to video-development;
|
|
- creation of rx-node;
|
|
- publication of raw IQ, video, waveform or large logs.
|
|
|
|
## 9. Final RX report
|
|
|
|
TASK_ID =
|
|
RF001A_OTA_CAPTURE_002
|
|
|
|
RX CAPTURE COMPLETE =
|
|
|
|
EXIT CODE =
|
|
|
|
CAPTURE SIZE =
|
|
|
|
CAPTURE DURATION =
|
|
|
|
RX OVERRUNS =
|
|
|
|
USB ERRORS =
|
|
|
|
FILE WRITE ERRORS =
|
|
|
|
RAW IQ SHA256 =
|
|
|
|
CLKIN AFTER =
|
|
|
|
RF TX OBSERVED =
|
|
|
|
FINAL RX RESULT PUBLISH =
|
|
|
|
OFFLINE DECODE =
|
|
|
|
RF TX =
|
|
0
|
|
|
|
STOP.
|