Skip to content

Release 2026-10-29: Arena Studio v0.101 - #290

Merged
mbreiser merged 14 commits into
mainfrom
release/2026-10-29
Oct 29, 2026
Merged

mbreiser merged 14 commits into
mainfrom
release/2026-10-29

Conversation

@mbreiser

@mbreiser mbreiser commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Release candidate 2026-10-29 rc3 · candidate commit 41c1f51d4d · built on main 59a377b05e

Live on Next: https://reiserlab.github.io/webDisplayTools/next/

Tool Version
Arena Studio v0.100 → v0.101
PR Title Head CI Release notes
#286 rig: pin the rig-nodes package set 0.4.0 at its release tag (LAB-338) 9018462064 green none (declared)
#285 rig: pixi run qc — the five-minute release validation of a tier on a rig PC (LAB-222, LAB-338) 9614a91a90 pending none (declared)
#288 protocols + rig records → private repos (LAB-227) 91bf95849e green Arena Studio
#289 Studio: overwrite guard survives the raw/JSON cache collision; telemetry line reports in-session evictions (LAB-227) 4090716d45 green Arena Studio

Promotion checklist

  • CI green on this PR and on every constituent PR (pixi run release checks)
  • Validated on a rig between sessions — comment Validated 41c1f51 … (pixi run tiers -- validate --rig … --by …). Any change to a constituent PR = rebuild (rc+1) = validate again.
  • Release window: Slack heads-up posted; nobody is mid-experiment (release lists recent rig runs — advisory)
  • After merge: rigs hard-refresh between sessions; if fictrac-bridge/ changed, rig PCs git pull + restart the bridge

Promote with pixi run release (merges with a merge commit — never squash — and tags release-2026-10-29). Manifest: releases/2026-10-29.json.

🤖 Generated with Claude Code release tooling (scripts/tiers/candidate.py)

mbreiser and others added 8 commits October 28, 2026 19:09
…a rig PC (LAB-338)

One command checks the candidate on /next/ (or Production) end to end: the tier's
build.json → a scratch worktree at that SHA with its own pixi environment, the
candidate's graph with the rig's flags, FicTrac (or the simulator), the Studio
emulator pre-check, the tier's Studio in a QC Chrome profile driven over DevTools
(build SHA, protocol load, bridge connect, the one Web Serial click, Run
experiment), export + runlog-check + closed-loop-report + bench-check, teardown,
a pass/fail table and a ready-to-paste validation note. Per-rig rows and the
checklist text live in rig/qc/profiles.toml (ww18, ww14, bergamo, mac); the
procedure is rig/QC.md; tests/test-rig-qc.py pins the pure half.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
rig/pixi.toml reads the channel at https://raw.githubusercontent.com/reiserlab/rig-nodes/v0.4.0/channel
(the tag form; 0.3.0 was pinned by the payload commit's SHA only because its tag had landed one commit
early) with rig_nodes / rig_interfaces ==0.4.0, re-locked with pixi 0.83 (`pixi lock` in rig/; the `dev`
environment's git sources on rig-nodes main re-pinned to fa83d39). 0.4.0 vs 0.3.0: the ScanImage JSON
connector moved to the private 2P rig repo (rig-nodes#4), the host monitor's typed HostStats floats are
quantized and its portable process sampling is cheaper (rig-nodes#6); no .msg change.

Verified on the Mac with ~/Documents/GitHub/rig-nodes renamed away: `pixi install --locked` (default +
typed, 4 s each), `pixi run test` 60/60 (host monitor self_cpu_median 0.006 of a core — the macOS cost gate
the 0.3.0 sampler failed here), `pixi run -e typed test` 63/63, `check-typed` lists the 8 types incl.
HostStats, a plain `pixi install` leaves the lock as written. Gateway: hello_ack still advertises the
scanimage connector (the emulator's --scanimage-cmds node checks need the private node, as on main).

Docs: WINDOWS-TEST.md expected harness count 60 / 63, README.md adapters list, the okey-cokey dashboard
plan's tiff_run_to_mcap.py line (private since 2026-10-28), the rig-nodes dependency comment.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Rig-specific protocols and per-rig records leave the public repo so a rig's protocol
tweaks never need a webDisplayTools release. Rule: a protocol stays here only if a
tool, test, QC profile or fixture depends on it.

- Removed (copied first to reiserlab/arena-experiments 8db48e6 and
  reiserlab/scanimage-2026-bergamo 00bccfd, each with PROVENANCE.md): the three
  bias_camera_closed_loop_poc* protocols (→ protocols/ww18/), fictrac_bias_test,
  fictrac_direction_test, fictrac_coupling_bias_fly_test, led_activation_quadrant_test
  (+ patterns), mode3_drill_1trial (→ protocols/shared/); the three 2P protocols +
  two pattern folders (→ bergamo protocols/); the ww18 and okey-cokey (ww14) run
  sheets, handover, dashboard plan, BIAS config and .ps1 start scripts
  (→ rigs/ww18/, rigs/ww14/).
- protocols/index.json drops the moved keys; protocols/MOVED.md maps every old path
  to its new home.
- tests/test-protocol-roundtrip-v3.js parses the 2P sweep from a fixture copy
  (tests/fixtures/v3_g6_2p_color_led_sweep.yaml).
- scripts/make-color-optomotor-patterns.js --gs16 and
  scripts/make-2p-diagnostic-patterns.js take --out <dir> (the 2P targets are no
  longer in this repo; without --out they explain where they went and exit 2).
- rig/README.md, rig/WINDOWS-TEST.md, the protocol-yaml skill, two course docs and
  the decision record's "stays" row point at the new locations.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…uard miss)

GitHub returns one ETag for the raw and the JSON form of a contents URL; after
a raw read (?p= open, promote, previews) Chrome revalidated the cached raw body
for the later JSON request and served it on the 304, so res.json() threw and
every existence check (resolveRepoSaveTarget, the silent-fork guard) answered
"no": a changed protocol overwrote the repo copy with no "Overwrite?" prompt.
Found on ww18 during the LAB-227 private-repo test, 2026-10-29. GH.run now
sends cache: 'no-store'; runBytes keeps caching since nothing JSON is stored.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… counter

The ring block header's `dropped` is the controller's eviction count since its
boot, so a Studio connected hours later logged "dropped 1929" with gaps 0 and
read as in-run loss (ww18, 2026-10-29). The drainer now keeps the counter at
its first block of a ring incarnation (`droppedBase`, reset on a fresh ring)
and exposes `droppedSession`; the once-a-minute stats line leads with
"evicted this session N (controller lifetime M)". `telemetry_dump` and the soak
stats carry the new field; the raw `dropped` stays for the record.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ostics moved to the private repo, LAB-227)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on protocol needs FicTrac)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…EAK (ww18 rc1 QC findings)

Two findings from the first `pixi run qc` on ww18 (candidate 2026-10-29 rc1, 2026-10-29):

1. bench-check's hold checks assume a still ball. A live fly turned it −1108° in 8 s, the
   display followed FicTrac with 0.00 % idx mismatch, and the QC table said FAIL. New
   qclib.hold_verdict(): when ONLY hold lines failed and closed-loop-report shows an epoch with
   |net turn| >= 45°, the row is SKIP naming the turns; a hold miss on a still ball, or any other
   bench-check failure, stays FAIL. ww18's run/reports look text says so. Tests in test-rig-qc.py.

2. Teardown on Windows left the graph's nodes and the router as orphans ("graph stopped", then
   "ports free again" FAIL on 7447/8765/60000). qc.py stops rig.py with
   rig_nodes.supervise.signal_group(SIGINT), which on Windows is CTRL_BREAK_EVENT on the process
   group; Python delivers that as SIGBREAK, which rig.py did not handle, so it died before its
   `finally` stopped the children. rig.py now registers SIGBREAK where it exists (bridge_node and
   host_monitor already did). QC.md documents both.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mbreiser and others added 6 commits October 29, 2026 16:44
…a whole-epoch hold

Michael on the rc1 QC: with FicTrac live the ball can always move, so a check that the display
HOLDS frame 25 / 75 for a whole epoch is the wrong test on a rig. What the two epochs exist to
verify is the v0.91 start frame: the first post-tare index equals the trialParams frame_index
(closed-loop-start-frame.md). closed-loop-report now emits `first_idx_after_tare` +
`opens_on_start_frame` per epoch (and marks "200 @25 ✓" in the table); qc.py records "epochs open
on their start frame" from it; the rest of the epoch is the existing idx-mismatch check. The ww18
profile drops its `holds` (bench-check still judges completion, arena acks, channel, build; `holds`
stays available for a bare or blocked ball, with hold_verdict's SKIP when the ball turned). Tests
in test-closed-loop-report.py cover the open on 25 / 75 and a ≤ 3.3 bridge opening on 0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…f a tier on a rig PC (LAB-222, LAB-338)
# Conflicts:
#	rig/docs/okey-cokey-foxglove-dashboard-plan.md
…sion; telemetry line reports in-session evictions (LAB-227)
Candidate for Production. PRs: #286, #285, #288, #289.

Release-Manifest: releases/2026-10-29.json
@mbreiser

Copy link
Copy Markdown
Contributor Author

✅ Validated 41c1f51 — candidate 2026-10-29 rc3 — on ww18 by Michael

pixi run qc -- --tier next --rig ww18 --auto on ww18 (reiserlab-ww18, G6 2x10 fly-on-ball, real FicTrac 96 fps, a live fly on the ball), 2026-10-29 ~16:49 ET, driven by the ww18 Claude session with Michael's Connect click: QC PASS, exit 0, 104 s wall.

Build label: candidate 2026-10-29-rc3, sha 41c1f51, PRs 286, 285, 288, 289; page meta 41c1f51, channel next, footer Arena Studio v0.101 | 2026-10-29 16:45 ET.

  • Candidate checked out and installed in its own worktree (rig_nodes 0.4.0); router + gateway + foxglove_bridge up; hello_ack bridge 3.4 / behavior_v2.
  • Emulator pre-check all PASS (437 frames, 384 applied, 0 stale withheld).
  • Studio on /next/: build SHA = candidate, protocol bench_closed_loop_2x10 loaded (rig cshl_g6_2x10_ball), no console errors, 99 frames/s in the page, controller 12bba7e9 2x10 sdfast connected.
  • Run experiment completed (4 steps, 22 s); export + bag closed and indexed; runlog-check a_ok 1544, 1/1 run files complete.
  • closed-loop-report: 2 epochs, idx mismatch 0.00 % / 0.13 %; epochs open on their start frame: epoch_a_frame25 25->25, epoch_b_frame75 75->75 (first post-tare index). Fly net turn +226 deg / +13 deg per epoch.
  • bench-check 7/7 (completion, arena acks, no glyphs, run_metadata, channel next, build 41c1f51).
  • Teardown clean: graph.log ends with "[rig] stopped", no orphan processes, ports 7447/8765/8766/60000 free (the rc1 orphan finding is fixed by rig: pixi run qc — the five-minute release validation of a tier on a rig PC (LAB-222, LAB-338) #285's SIGBREAK handler).

Remarks: panel inventory "unsupported" on this firmware (expected). Three cosmetic zenoh "Unable to publish link event: session closed" ERROR lines at bridge shutdown (rig-nodes follow-up). rc1 of this candidate had failed on the two QC-tool findings fixed in #285 (hold checks vs. a live fly; Windows teardown); rc2 was superseded unvalidated.

Artifacts on ww18: C:\qc\2026-10-29\summary.md, validation-note.md, reports\ (runlog-check, closed-loop-report, bench-check).

@mbreiser
mbreiser marked this pull request as ready for review October 29, 2026 21:13
@mbreiser
mbreiser merged commit 62dbbe7 into main Oct 29, 2026
8 checks passed
@mbreiser
mbreiser deleted the release/2026-10-29 branch October 29, 2026 21:13
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