Skip to content

Studio v0.93: panel inventory — which panels are present and their firmware, in every run log - #233

Merged
4 commits merged into
mainfrom
claude/panel-inventory-host
Sep 29, 2026
Merged

4 commits merged into
mainfrom
claude/panel-inventory-host

Conversation

@mbreiser

@mbreiser mbreiser commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Studio records which panels are present and what firmware each one runs in every run log, from controller firmware with the panel-inventory feature (reiserlab/LED-Display_G6_Firmware_Arena#59; spec reiserlab/Modular-LED-Display#71).

  • Wire (js/arena-wire-g6.js): decodeControllerInfo() reads the 0xC2 feature bitmap appended after the MAC (FEATURE_BITS: panel_inventory, qwiic_i2c, ai_stream) and labels capability bit 6 ai_cal; encodePanelInventoryScan(action) 0xD0, encodeGetPanelInventory(first) 0xD1, decodePanelInventory() for the 18-byte page header (scan_id at [17]) + 5-byte entries; PANEL_STATUS_NAMES / PANEL_INVENTORY_FLAGS. Golden tests for all of it.
  • Reader (js/studio-panel-inventory.js, dual-export, DOM-free): readAll() pages the fleet and re-reads when scan_id, first or panel_count disagree between pages; summarize() → present / missing / firmware groups / mismatched (≠ SD image, else outside a strict fingerprint majority, plus no-ISP panels); describe(); toRunMeta().
  • Studio: Studio.features from every 0xC2 decode; the inventory is read on Connect, on the gesture-free reconnect, from Controller ▾ info, and again at run start right before startRunLog(), so run_metadata.panels is a run-start snapshot. The record is always an object — {schema: 1, status: ok | pending | failed | unsupported | disconnected, count, present, missing, panel_status[], firmware[{crc32, panels}], mismatched, ref_crc32, fp_len, presence_valid, fp_valid, fp_in_progress, scan_id, age_ms} — so an absent inventory is never mistaken for "no panels". Studio.panels is cleared before every read, on failure and on disconnect. Provenance box: panels: 20/20 present · fw 0x9BE0D3C7 ×20 (64 KB prefix, no SD image). Console → Panel firmware → Inventory / Rescan (0xD0 action 1, guardDestructive, gated follow-up read). Help-mode text. Older firmware: nothing is sent; the box says "firmware without panel inventory".
  • No version bump: footer and release-notes file are main's (the release commit does that); notes below.

Coordination: #219 (claude/controller-settings-block) rewrites much of arena_studio.html and wants per-panel firmware for its run header — it can read Studio.panels after rebasing over this (~40 lines in the Studio: the refreshPanelInventory block, three connect-path hooks, runOnce, startRunLog, the fleet row). Suggested to share a Next candidate with #219: both touch the 0xC2/connect path and validate on the same bench firmware.

Tier

next candidate

Release notes

Studio

  • The Studio now records which panels are present and what firmware each one runs. On connect it asks the controller for its panel inventory (controller firmware with the panel-inventory feature) and shows it in the Run view's Auto-captured box ("20/20 present · fw 0x9BE0D3C7 ×20 …"). It reads it again at the start of every run, so the run log's panels record (next to firmware) describes the panels at that run's start: a missing panel or one on different firmware is on record for that run.
  • Console → Panel firmware → Inventory / Rescan. Inventory lists the panels grouped by firmware fingerprint and names any that differ from the image on the SD card (or from the majority when there is none); Rescan probes the panels again.
  • The record always says what it is — status ok / pending / failed / unsupported — so an absent inventory is never mistaken for "no panels". On older controller firmware the box says "firmware without panel inventory" and nothing is sent.

Review

Codex GPT-5.5 standard + adversarial cross-review (report in the branch worktree's .codex-review/). Its blocking finding — a stale Studio.panels written into the next run's metadata after a failed re-read — and its design points (run-start capture, durable status, page coherence) are in the second commit.

Test plan

  • pixi run test (full suite) green; test-arena-wire-g6.js 314 checks, new test-studio-panel-inventory.js 49 checks, test-studio-meta.js 46
  • Live on a G6_2x10 with fw connect not an option as a bias camera command - not necessarily a problem but note this. #59: link-up read 20/20 · 0x9BE0D3C7 ×20 · status: ok; run-start record; unsupported / failed paths null the cache and record their status; guarded Rescan → new scan_id with the gated follow-up; disconnect clears everything; no console errors
  • 40/48-panel arena (two-page read) — 12-18 bench
  • A protocol run committing run_metadata.panels to the course repo (on /next/)

🤖 Generated with Claude Code

mbreiser and others added 4 commits September 28, 2026 19:31
…rmware, in every run log (v0.93)

Wire (js/arena-wire-g6.js): decodeControllerInfo() reads the 0xC2 feature bitmap
appended after the MAC (FEATURE_BITS: panel_inventory, qwiic_i2c, ai_stream) and
labels capability bit 6 ai_cal; encodePanelInventoryScan(action) 0xD0,
encodeGetPanelInventory(first) 0xD1, decodePanelInventory() for the 18-byte page
header (scan_id at [17]) + 5-byte entries; PANEL_STATUS_NAMES /
PANEL_INVENTORY_FLAGS. Golden tests for all of it, including the 0xD0 echo, the
past-the-end page and a pre-scan_id 17-byte header (rejected).

Reader (js/studio-panel-inventory.js, dual-export): readAll() pages the fleet and
re-reads from first=0 when scan_id changes between pages; summarize() → present /
missing / firmware groups / mismatched (≠ SD image, else outside a strict
fingerprint majority, plus no-ISP panels); describe(); toRunMeta().

Studio: Studio.features from every 0xC2 decode; Studio.refreshPanelInventory()
after refreshFirmwareVersion() on Connect, on the gesture-free reconnect hook and
from Controller ▾ info, gated on the panel_inventory feature; one follow-up read
while the boot sweep is still running. Provenance box shows "panels: 20/20
present · fw 0x9BE0D3C7 ×20 …"; run_metadata.panels (studio-meta buildMeta)
carries the compact record. Console → Panel firmware gets Inventory / Rescan
(0xD0 action 1 after quiesceDisplay, follow-up read 3 s later). Help-mode text.

Bench (G6_2x10, fw #59 bf2a8e3): link-up read 20/20 · 0x9BE0D3C7 ×20 · scan 9;
Rescan → scan 10 with FP_VALID inside the follow-up window; no console errors.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… cache (Codex review)

- Studio.panels is cleared before every read, on a failed read and on
  disconnect (with Studio.features); Studio.panelsStatus records why.
- runOnce() re-reads the inventory right before startRunLog(), so
  run_metadata.panels is a run-start snapshot, not connect-time state.
- toRunMeta(inv, status) always returns {schema: 1, status: ok|pending|failed|
  unsupported|disconnected, …}; per-panel array renamed panel_status;
  presence_valid / fp_in_progress added.
- readAll() also re-reads when a page's `first` is not the requested offset
  or panel_count changes between pages.
- Rescan is guardDestructive (it stops the display); all follow-up reads go
  through Studio.scheduleInventoryFollowUp (connected + not running).
- Tests for each; verified live on the G6_2x10 (fw #59 c15d840 build).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ile back to main's

Feature PRs no longer bump versions (docs/development/release-process.md rule 4);
the release commit does it and folds the notes in from the PR body.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mbreiser added a commit that referenced this pull request Sep 29, 2026
…and their firmware, in every run log

# Conflicts:
#	pixi.toml
mbreiser added a commit that referenced this pull request Sep 29, 2026
Candidate for Production. PRs: #219, #233, #234.

Release-Manifest: releases/2026-09-29.json
mbreiser added a commit that referenced this pull request Sep 29, 2026
mbreiser added a commit that referenced this pull request Sep 29, 2026
Candidate for Production. PRs: #233, #234.

Release-Manifest: releases/2026-09-29.json
@mbreiser mbreiser closed this pull request by merging all changes into main in 995ab34 Sep 29, 2026
@mbreiser
mbreiser deleted the claude/panel-inventory-host branch September 29, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant