# QA 10 Oct (reviewer, run 1)
Reviewed: ops.log, changes.log, .bak_ops diffs (super.py, supply.py, tracker.py, checks.json, kitcode.py, probe.py, selltest_cron.sh). All compile; logic OK; heartbeat/ok files exist and are fresh. No bug in those.

## Found
1. hourtrain.py (/opt/hist, runs on research-box via hourtrain.sh) crashes: line 88 eth_getLogs, 20000-block window with up to 100 pools -> "logs matched by query exceeds limit of 10000" (37 tracebacks in analysis/hourtrain.cron.log, latest 01:51 UTC). The run aborts, shadow model not retrained.
   Fix: in the `while b <= b1` loop catch the RuntimeError with that message and halve the window (e = b + (e-b)//2, retry; min 100 blocks), or cut chunk size 100 -> 20 pools. Owner: ppdata.
2. Minor: /opt/ratewatch/agg.log and /opt/review/missloop.log do not exist yet (crons are new: rateagg at :25, missloop 01:15 UTC). Recheck next run.
# QA 10 Oct 2026 (run 2, reviewer)
Swept: ops.log, changes.log, fm_mirror mc5/l2 changes (nothing new since 8 Oct), tracker.py diff vs .bak_ops_1791599489 (clean, py_compile ok), cards/dispatch/pipeline logs (no tracebacks), agg.log and skipwatch.log (fresh, ok), review.log ok. missloop logs into review.log (no missloop.log by design).

## Finding: launchwatch.py has crashed every 3 min since 15 Sep
- /opt/launchwatch/registry.json is truncated (389120 bytes, last written 15 Sep 01:10, disk-full style cut). launchwatch.py:230 json.load raises JSONDecodeError -> ~2950 tracebacks in run.log, still happening 10 Oct 04:00.
- Effect: launchwatch registry/outputs not updated for 25 days. Unknown whether anything still depends on it.
- Fix (owner decides): if still wanted, restore registry from a backup or start `{}` (move the broken file aside, don't delete) and make line 230 tolerate bad JSON (try/except -> {}) and write via tmp+rename (line 272). If obsolete, remove the cron line.
