Commit Graph

2 Commits

Author SHA1 Message Date
ruv 3a5fe5e0de feat(firmware): mirror weight-blob parser into ruv_temporal (#513)
Closes the format contract on the firmware side. Source-only — Phase 5
toolchain blocker still prevents actually compiling, but when it
unblocks this is one less thing to write under time pressure.

- src/weights.rs — no_std mirror of v2/.../weights.rs. Same magic
  ('RVNE'), same version 1, same CRC32-IEEE polynomial (matches the C
  side in temporal_task.c). Bit-for-bit lockstep with the host: a
  blob produced by host WeightBlob::serialize() parses here as a
  WeightBlobView byte-for-byte.

  Borrowed-slice parse design: the firmware loader receives weights
  via mmap'd EMBED_FILES or NVS read into a heap buffer. The parser
  takes &[u8] with no copy — view fields point into the caller's
  buffer. Caller is responsible for keeping the buffer alive for the
  view's lifetime.

  Loader errors map to esp_err_t-style codes via
  weight_load_err_to_esp() so the C ABI can surface specific failure
  modes (ESP_ERR_INVALID_ARG for magic/version/size, ESP_ERR_INVALID_CRC
  for corruption, ESP_ERR_INVALID_SIZE for shape validation failures).

- src/lib.rs — ruv_temporal_init now optionally validates a non-NULL
  weights blob. NULL pointer is still allowed during the Phase 4/5
  bring-up window (kernel forward isn't actually consuming weights
  yet), but when caller passes a real blob we parse + sanity-check
  declared dims against runtime arguments. Catches deploy bugs at
  init() rather than at first classify() — the firmware Tmr Svc work
  in v0.6.4 taught us that classify-time crashes are the worst kind.

- README.md — Phase 6 marked done (verified by 8MB firmware build with
  feature off in commit 7994af822). Added module map table covering
  lib.rs / window.rs / weights.rs / ruv_temporal.h / shim.c.

What's deliberately NOT in this commit:
  - Cross-compile validation. Same toolchain blocker as before.
  - Kernel-side wiring of weights into the forward pass. That's
    Phase 6+ of the firmware roadmap — once the kernel is wired,
    weights become a required arg, not an optional one.
  - Tests on the firmware side. They'd need build-std working to run;
    16/16 host tests cover the format end-to-end via the lockstep
    polynomial.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-08 11:53:19 -04:00
ruv 22d47a71e3 feat(firmware): scaffold ruv_temporal ESP-IDF Rust component (ADR-095 Phase 4, #513)
Phase 4 of the #513 roadmap: ESP-IDF component skeleton at
`firmware/esp32-csi-node/components/ruv_temporal/`. Source is complete
and self-consistent; cross-compile to xtensa-esp32s3-none-elf is
blocked by a known-broken esp-rs nightly snapshot (details in the
component README).

What's in the scaffold:

- `Cargo.toml` — staticlib, no_std + alloc, deps on the path-vendored
  `ruvllm_sparse_attention` (matching ADR-096's host-side dep) and
  `esp-alloc`/`critical-section` for the no_std allocator and lock
  primitives.
- `src/lib.rs` — public C ABI (init / push / classify / destroy /
  self_test) with `#[no_mangle]` exports, a `[#used]` keepalive table
  to defeat aggressive linker stripping, esp-alloc as the global
  allocator (heap region added at runtime by the firmware), and a
  loop-on-panic handler (Phase 5 will route through esp_system_abort).
- `src/window.rs` — `FrameRing`, the rolling-window buffer that
  `ruv_temporal_push` writes to. Chronological iteration via
  `iter_chronological()` so the kernel sees oldest-first.
- `include/ruv_temporal.h` — the public C header consumed by
  edge_processing.c. Threading contract documented inline (single
  dedicated FreeRTOS task, no internal locks).
- `CMakeLists.txt` — runs `cargo +esp build` as an ESP-IDF
  pre-component-register step, then registers the static library
  through `idf_component_register` + `target_link_libraries(...
  INTERFACE ...)`. `shim.c` exists only because
  `idf_component_register` requires SRCS.
- `.cargo/config.toml` + `rust-toolchain.toml` — pin the build to
  `xtensa-esp32s3-none-elf` and the `esp` toolchain channel so
  `cargo build` without flags Just Works once the toolchain is
  unblocked.
- `README.md` — Phase status table, Phase 5 toolchain blocker
  explanation, and the espup install fix.

ABI calls into edge_processing.c (Phase 6) and COM8 validation
(Phase 7) follow once the cross-compile is unblocked.

Closes nothing yet; advances #513.

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-05-08 09:44:01 -04:00