Cow Remote unified firmware — Opus 5.5 review¶
Status: historical review, followed by fixes and push418d3b5 on2026-09-22. Unified6.16 is a hardware-validation preview, not yet bench-qualified. Current delivery: cow-flasher-configurator-mode-plan. The original findings and evidence below are retained as the review snapshot.
2026-09-22. The owner requested Claude Opus 5.5 specifically. The installed subscription CLI resolved and returned claude-opus-5-5, high effort. Tools and MCP servers were disabled, with dontAsk permissions and no fallback model. Review ran 389 seconds. CLI list-price estimate $2.9286222, not an additional subscription charge. Provider usage refresh returned a cached/stale observation (13% five-hour, 2% shared weekly), so no fresh allowance claim is made. One bounded foreground reviewer; no background worker was running. No source files changed during review (snapshot hashes verified).
The in-progress firmware builds in Release with GCC 13.3 without warnings, and the original host integration suite passes. Those checks missed the cases below. Passing them does not make the branch ready for the robot.
Confirmed findings¶
| Priority | Finding | Evidence and next correction |
|---|---|---|
| High | Playback can be armed while driving and begin after movement is released. | Reproduced with production callbacks and button driver: hold Forward, hold PB7 over 1 s, release Forward, wait for idle, release PB7. Playback starts. Require neutral/other-buttons-idle when arming as well as when releasing; a separate deliberate neutral gesture should start playback. |
| High | Interrupted recording save can produce a valid-looking spliced route. | Reproduced: save an old route, interrupt a replacement after its header and first sample, reboot, start playback. First sample is new and following sample is old. Invalidate header first and commit validity last; assess checksum/versioning before altering the file format. |
| High | Recording EEPROM operations block the cooperative control loop. | Source confirms Recorder_Stop writes header plus up to 1,000 separate sample transactions synchronously inside a button callback. Player_Start also reads up to 1,000 samples synchronously and starts its clock before loading. Master's driver initializes/deinitializes I2C per call and polls write readiness. Physical duration is unmeasured; Opus's seconds estimate is not bench evidence. Prefer bounded/nonblocking storage, ensure neutral output before long operations, and start playback timing after loading. A single bulk write alone still blocks and is not a complete control-loop fix. |
| Medium | A short Play press does not stop playback. | Reproduced: PB7 short press/release leaves playback running; only long hold/release toggles it. Make stop immediate and consume the gesture so holding that same press cannot restart playback. |
These behaviors already exist in the Record lineage. Opus labelled the two Play gesture issues as merge-introduced, but comparison with Record 3754b32 shows that classification is wrong. They are inherited concerns made more noticeable when the same controls can also mean Normal-mode actions.
Other review observations and triage¶
- USB SAVE/LOAD/RESET and PAIR_BEGIN now reject some factory/busy states. The new gates are deliberate in the chosen mode-switch design; compatibility with actual provisioning sequences needs review. Do not simply remove the gates based on the model's suggestion. Current host tests omit the factory/diagnostic command tail.
- The V1 channel is reapplied from RAM each packet in Recording mode, whereas Normal keeps the initialized channel. This is inherited from Record's telemetry receive path. Verify/document CHANNEL semantics and prevent inadvertent live retuning.
- Opus suggested a possible RF power mismatch. Source inspection resolves that part: master's legacy initialization and Record receive setup both select 1 Mbps and -12 dBm. No mismatch is established.
- An allstop arriving during the V1 send path can be processed after the outgoing command was assembled. This ordering exists in the Record lineage; test the real receive/send path and receiver-side stop enforcement.
- USB RESET persistently selects Normal but gives no explicit mode/restart notice. Improve the response/documentation.
- Downgrade to master 6.15 or Record 6.6 sees an unknown A7 configuration marker and can reset settings/pairing. Document before offering binaries.
- WORKING_HOUR parsing takes an address inside a packed struct; the host compiler warns. This is existing code. Parse through an aligned local and verify on the MCU rather than assuming the target library handles it safely.
- Recorder samples omit timestamps; scheduler stalls can compress playback time. A simplistic counter increment does not by itself solve all missed-sample behavior.
- Existing receiver firmware must be checked against both V1 byte-four interpretations and V2 stop flag layout. The remote's mode switch preserves its two source branches' formats; that does not prove every deployed robot accepts both.
- CubeIDE Debug and Release builds and real GPIO/radio/EEPROM bench tests remain unperformed. Source entries were added for V2; checking the tree finds no duplicate Core radio source copies. The standalone Release build is verified, IDE parity is not.
What the review found sound¶
Pending mode is separate from configFlash, so periodic/pairing/power-off writes do not accidentally persist it. Active mode stays fixed until restart. Startup/reentry waits for release. Record and playback are mutually exclusive through the UI. Migration writes its marker last. PC15 is registered once. Storage remains 60 seconds with 54 reserved configuration bytes.
Evidence¶
Private artifacts: ~/engineering/review-artifacts/cow-unified-opus55/ contains the source hash manifest, bounded launch metadata, reviewer result and independent reproduction log. No firmware changes or branch push were performed during this review. Follow-up implementation must address the accepted findings and expand the tests before the branch is presented as ready to flash.
Focused incomplete-save follow-up — 2026-09-22¶
Exact Claude Opus 5.5 completed a second bounded, tool-free read-only review (98 seconds). Capture is RAM-only: interruption before Recorder_Stop loses the new capture but leaves the previous EEPROM recording. During Recorder_Stop, the new valid header is written before sample data; an interruption can leave new commands followed by old ones. Playback later accepts this mixed route when the user requests Play; reboot itself does not start playback. The independently reproduced replacement was 20 samples: first new (-500,300), next old (700,-200). Real playback timing may skip early samples because its clock starts before loading.
Recommended design, not implemented: keep one slot, use a versioned 32-byte header, invalidate and read back the invalid state before changing payload, serialize/write payload in bounded page chunks, verify readback against the expected CRC, and commit header last. Validate metadata, CRC and command ranges before enabling playback; reject invalid routes with neutral output. Readback of invalidation is essential: an acknowledged but ineffective write must not leave an old valid header during replacement. CRC is error detection, not a mathematical guarantee against every corruption. Page-write atomicity and brownout behaviour require the actual EEPROM datasheet and hardware tests. Storage liveness and playback clock origin remain separate fixes.
This preserves 1000 samples/60 seconds and 54 spare configuration bytes. Single slot: header0x80, payload0xA0, end-exclusive0x1040. Optional A/B slots at0x80 and0x1040, each4032bytes, fit exactly through0x1FFF; they retain an old route after failed replacement but consume all recording-region space. Old recordings need not survive, so the single-slot design is proportionate.
Primary triage of follow-up: do not treat the model's estimated seconds as measured timing; do not accept its universal “every torn state rejected” wording; a torn final write that nevertheless yields the complete intended header and payload is valid. Its invalidation sequence needs explicit readback before payload. Proposed CRC testing should permit intact old data before replacement and complete new data after commit, while rejecting mixed routes. No source edits or push occurred. Private artifact: ~/engineering/review-artifacts/cow-incomplete-recording-opus55/.