Harden RF node control and agent updates
This commit is contained in:
74
tools/rf001_staircase_job.py
Normal file
74
tools/rf001_staircase_job.py
Normal file
@@ -0,0 +1,74 @@
|
||||
"""Detached software-only worker for one fixed STAIRCASE_SEARCH task."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from tools.rf001_http_control import PROTOCOL_VERSION, STAIRCASE_SEARCH_TASK, utc_now
|
||||
from tools.rf001_rx_http_agent import run_staircase_search
|
||||
|
||||
|
||||
def _atomic_write(path: Path, value: dict[str, object]) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = path.with_suffix(path.suffix + ".tmp")
|
||||
temporary.write_text(
|
||||
json.dumps(value, ensure_ascii=False, separators=(",", ":"), sort_keys=True)
|
||||
+ "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
os.replace(temporary, path)
|
||||
|
||||
|
||||
def run_job(spec_path: Path, result_path: Path) -> dict[str, object]:
|
||||
spec = json.loads(spec_path.read_text(encoding="utf-8-sig"))
|
||||
if not isinstance(spec, dict):
|
||||
raise ValueError("job spec must be a JSON object")
|
||||
task = spec.get("task")
|
||||
if not isinstance(task, dict) or task.get("kind") != STAIRCASE_SEARCH_TASK:
|
||||
raise ValueError("job spec does not contain STAIRCASE_SEARCH")
|
||||
started_at = utc_now()
|
||||
task_result, errors = run_staircase_search(
|
||||
Path(str(spec["work_root"])),
|
||||
str(task["session_id"]),
|
||||
str(task["expected_rx_sha256"]),
|
||||
str(task["expected_reference_sha256"]),
|
||||
progress_path=Path(str(spec["progress_path"])),
|
||||
)
|
||||
result = {
|
||||
"protocol_version": PROTOCOL_VERSION,
|
||||
"task_id": str(task["task_id"]),
|
||||
"agent_id": str(spec["agent_id"]),
|
||||
"status": "COMPLETE" if not errors else "FAILED",
|
||||
"started_at": started_at,
|
||||
"finished_at": utc_now(),
|
||||
"result": task_result,
|
||||
"errors": errors,
|
||||
"rf_tx": 0,
|
||||
}
|
||||
_atomic_write(result_path, result)
|
||||
return result
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--job-spec", required=True, type=Path)
|
||||
parser.add_argument("--result", required=True, type=Path)
|
||||
arguments = parser.parse_args()
|
||||
result = run_job(arguments.job_spec, arguments.result)
|
||||
print(f"TASK ID = {result['task_id']}")
|
||||
print(f"TASK STATUS = {result['status']}")
|
||||
print("HARDWARE ACCESSED = false")
|
||||
print("RF TX = 0")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user