Status, plan and log for the show machine
Running record of what Gavin and Claude have done on this project, plus how to pick up from here. Append new sessions at the bottom (newest last). Never put passwords or tokens in this file.
Related files:
docs/plan.md: the shared checklist and open questions. docs/index.md is the public status page (https://gavaiken.github.io/river-bitcube/).docs/a-river-becoming-hardware.md: verified hardware reference (ropes, PSAC10 boxes, rack controller, universes, panels, cameras).docs/a-river-becoming-notes.md: design notes digested from the meetings.This repo is public. Never commit passwords, tokens, camera logins, private keys or phone numbers. Names, hostnames, IPs, ports, device usernames and account emails may be published (Gavin, 18 Oct). Secrets live only in untracked secrets.local.json on bitcube.
LED + AI art installation for Gray Area (SF) that should read as a river. 20 LED ropes (8,000 px) are the rain/flow, ~30 HUB75 panels are “pools” in the flow, plus driftwood and river rocks. An AI “river” agent (Dave’s, on Modal) gets input from Reolink cameras at the gallery and at a real river (Starlink + solar). Prototyping happens at Agape (Gavin’s house). Install at Gray Area Oct 22–27, 2026. Gavin joined Oct 6 to handle pixel mapping and the CPU→LED path.
| Who | Role |
|—|—|
| Colin | Artist; lead / organiser, ordering |
| Justine Sun Dela Cruz | Meeting notes, visual references, coordination |
| Will Gardiner | Networking, cameras, Tailscale (tailnet owner), Windows box, rope-light app |
| Dave (drocamor) | Agent + generated visuals on Modal; owns the river-agent repo |
| Andi | HUB75 panels, Colorlight config (from their own Windows PC), TouchDesigner |
| Lilian (Lily) | Rigging; Gray Area liaison with Seabrook |
| Gavin | Pixel mapping, TouchDesigner harness; built the Chromatik model + TD patch on Oct 7 |
Dave's visuals (Modal / web canvas)
│
TouchDesigner on bitcube ── "glue"
├─ crop 20×400 region ─► Art-Net (2.x.x.x /8) ─► AoShow rack controller ─► PSAC10 ×2 ─► 20 ropes
└─ crop/rotate panel regions ─► 1080p frame ─► HDMI ─► Colorlight sender ─► 5A-75B ─► HUB75 panels
Cameras (Reolink, RTSP + pan/tilt) ─► GL.iNet router running Tailscale ─► Modal agent ("brain")
drocamor/river-agent (Dave’s, private). Merged PRs to main auto-deploy to Modal. Will added a rope-lights PR.gavaiken had no access. Ask Dave to add him. Clone it once access is granted (done 2026-10-18).tail03bc1a), max 6 users (free plan). Gavin accepted an Admin invite on 2026-10-17.user (Administrator), auto-logs in at boot. Password: ask Will (not stored here).ssh bitcube (alias in ~/.ssh/config → 100.73.68.60, key ~/.ssh/id_ed25519, key in C:\ProgramData\ssh\administrators_authorized_keys). SSH sessions run with full admin rights (High integrity), and no UAC prompts appear.dots cask windows-app) → PC 100.73.68.60, user user. Caveat: RDP takes over the console session, so the HDMI/panel output goes away while connected and the screen is left locked on disconnect. Hand it back with tscon <session id> /dest:console (run over SSH as admin).smb://100.73.68.60/River / smb://bitcube.local/River. Share River = C:\Users\user\River, full access for user.bitcube.local), profile set to Private on 2026-10-17. Ethernet has 2.0.0.8/8 (Art-Net to the LED controller) + 192.168.1.99/24. Tailscale 100.73.68.60. Single HDMI display, 1920×1080, Intel Iris Xe.ssh bitcube "powershell -NoProfile -EncodedCommand $(printf '%s' "$PS" | iconv -t UTF-16LE | base64)", and filter CLIXML noise from the output. Processes started with Start-Process die when the SSH session ends, so run long jobs in the foreground (e.g. a backgrounded ssh on the mini).river-bitcube\*.cmd; README in river-bitcube\):
Start-River.cmd (10 s): opens river-bitcube\river-local-oct-18.toe (the rain checkpoint; river.toe until 18 Oct 16:54) in TouchDesigner, or TD empty if that file doesn’t exist.Start-Claude.cmd (20 s): a Claude terminal in C:\Users\user\River.Start-Status.cmd (40 s): Chrome with the status page on the M14.RiverSnapshot: gallery-cam still to the snapshot branch every 15 min, 08:00–02:00.C:\Program Files\Derivative\TouchDesigner\bin\TouchDesigner.exe, Non-Commercial licence (TOPs capped at 1280×1280).RopeLights, which runs C:\Users\user\RopeLights\runtime\python.exe app.py --config config.local.json (its own Python, plus a small web app with rope patterns). It has no trigger, so it won’t start after a reboot. Don’t run it while TD also sends Art-Net.C:\Users\user\Archive\2023-bitcube-startup\ (README + restore steps, the original startup shortcut, startup-inventory-2026-10-17.txt). The project files stay in Desktop\Bitcube4, and its old Chromatik setup is in ~\Chromatik.~/Chromatik/Models/Rain.lxm, River.lxm, ~/Chromatik/Models/River-pixelmap/ (map + builder script). Not yet copied to the mini or bitcube.river_masks.zip: Gavin was dragging it to \\bitcube\River at the end of the session (not yet confirmed or unzipped).The live checklist is docs/plan.md (items and open questions) and the session status is docs/execution-plan.md. This is the short handoff view.
Showing now: the local rain checkpoint (river-local-oct-18.toe, opened at login) on the 18 working ropes and HUB75 quad 1, with no Modal.
Waiting on people:
gallery/sync.py on bitcube, whether SITE_TOKEN is set, and the canvas design size. Unblocks session D (his visuals on the ropes and HUB75, falling back to local rain). INGEST_TOKEN, location/channel names and clip cadence unblock session E (cameras into his agent).config.local.json; the Gray Area network (bitcube’s dual NIC, the cameras’ network); a fixed address for the gallery cam.Next work:
10.0.7.76/32. Never advertise the venue’s own LAN from another device (docs/sessions/A.md, 17:50).river-agent: pull and push it from a machine that has them, or ask Dave for a deploy key. Needed before D and E.Housekeeping (not urgent):
tools\snapshot_task.ps1 once from an elevated PowerShell so RiverSnapshot also runs with nobody logged in.signal-cli as a linked device (offered, not done). For now Gavin sends Signal messages himself.Done from the 17 Oct list: TouchDesigner licence (Non-Commercial); river-agent access and clone; TD driving the ropes over Art-Net and HUB75 quad 1 over HDMI; box IPs (2.0.0.10/.11) and the universe mapping (Will’s config); colour order (RGB); live Art-Net overrides the boxes’ own program, and silence hands it back.
dots.drocamor/river-agent (no access yet).bitcube SSH alias on the mini.Bitcube5.toe in TD 2022 and a Chromatik alpha at every login. Archived it with a README and restore steps./DIR: it uninstalled 2022 and installed at the default path. The .toe file association was removed. Gavin cancelled the tool call, but the install had already started and finished anyway.River\Start-River.cmd + Startup shortcut) and River\README.md.River SMB share. Gavin can now see bitcube in Finder on his MacBook.tvnserver, automatic). Its firewall rule allows all profiles, i.e. the whole house Wi-Fi as well, which the team chose. Connect with macOS Screen Sharing: vnc://100.73.68.60. VNC shows the real console/HDMI output; RDP doesn’t (it uses its own session and blanks the panels).C:\Users\user\River\river_masks\river_masks.toe (+ panel_crop.glsl, panel_preview.glsl, Backup). It takes a web view in and crops boxes out: the panel crops go to HDMI (works), and a prototype Art-Net output for the ropes is not yet validated. The launcher looks for River\river.toe, so this project does not autostart yet.River\LEDSetting_2.2.6_3180(2).zip appeared in the share (probably a Colorlight/LED config tool; unverified).dots cask windows-app). The Brewfile sync hit a yadm rebase conflict on the Air; Claude gave resolution steps (keep both sides, yadm add, GIT_EDITOR=true yadm rebase --continue, yadm push). Not confirmed resolved.C:\Users\user\.local\bin to the user PATH. Claude Code is running locally on bitcube, which is now the main agent for device work.C:\Users\user\RopeLights\config.local.json: box 1 2.0.0.10 = universes 0–39 (ropes 0–9), box 2 2.0.0.11 = 40–79 (ropes 10–19), 4 universes reserved per rope (3 used), RGB, source 2.0.0.8. This answers hardware open question 1, pending visual calibration.river.toe.C:\Users\user\River is the working copy, and docs\ there is now the source of truth. Installed on bitcube via winget: ffmpeg, GitHub CLI, Python 3.13. Added td/bridge/ (WebServer DAT bridge on localhost:9980, installed once from the TD Textport), tools/td.ps1, tools/cam_snap.ps1, and secrets.local.example.json.C:\Users\user\.ssh\river_bitcube_deploy, read-write on gavaiken/river-bitcube only; set via core.sshCommand in this repo). No personal GitHub login on bitcube. Revoke it under the repo Settings, Deploy keys..\tools\td.ps1 "app.build"). td.ps1 now prints plain text (stdout, then result). The /screenshot endpoint was fixed: TD passes query params in request['pars']. From Git Bash use powershell -ExecutionPolicy Bypass -File tools/td.ps1 ..., because the system policy blocks scripts.River\river.toe now exists and is in git. It is Andi’s river_masks network + /claude_bridge + /project1/ropes + /project1/panels, so the login launcher opens it with the bridge already live. Andi’s shader DATs now point to river_masks/*.glsl. Andi’s original river_masks.toe is untouched. TD saves incrementally (river.N.toe, gitignored) and also writes river.toe./project1/ropes = canvas (/project1/null5, Dave’s Web Render 500×800) → crop → fit 20×400 (column = rope, top row = pixel 0) → artnet_out (Python, synced from td/ropes/artnet_out.py, sent from an Execute DAT at 40 fps).
config.local.json. Its packets are byte-identical to RopeLights’, checked against Will’s own packets() for all 80 universes.Active, Source (canvas / identify / order / black), Identify, Brightness 0.15, Maxbrightness cap 0.4, Boxwatts limiter 600 W/box, Fps 40, crop. Status: op('/project1/ropes/artnet_out').module.status(op('/project1/ropes')).2.0.0.8:6454 exclusively, like RopeLights, so the two can’t both send: if RopeLights is running, TD’s output fails and turns itself off. Turning Active off sends a blackout.dmxout1 (Art-Net broadcast, empty routing table) is now deactivated.stop.ps1 refused because a non-elevated shell can’t read the S4U task process path, so Claude created stop.request itself. That is the same graceful path: the app blacked out and exited in 0.5 s. Task state: Ready. Restart it with Start-Rope-Lights.cmd only after setting TD Active off.2.0.0.10 and 2.0.0.11./project1/panels puts quad 1 (Andi’s rect 0) at HDMI (0,0) and quad 2 (rect 1) at (256,0) via td/panels/panel_layout.glsl. Its window is 512×128, borderless, always on top, DPI-native, and reopens at load.
Source test/canvas/black, Brightness 0.8, Quad1pos/Quad2pos.window1 (one quad) stays closed.LiveKernelEvent 141, “igfxn stopped responding”). It happened when the first panel_layout.glsl sampled sTD2DInputs[2/3] before those inputs were wired. The shader now uses only literal indices behind #if TD_NUM_2D_INPUTS.
build_panels.py wires inputs on successive frames.td/build/build_ropes.py and td/build/build_panels.py are idempotent (.\tools\td.ps1 -File ...).Active, Source=order at 15% (~35 W box 1, ~97 W box 2); panels Source=test, window open; TD at 60 fps.reverse_ropes/color_order in Will’s config, or a TD-side remap), then switch both Sources to canvas, a local fallback visual for when Modal is down, and cameras once Will sends the URLs.Sweep toggle), and Quad2off blanks quad 2. The screen corner now shows a static quad 1 with no extra lines. Recheck the panels.LED 1920X1080 on HDMI (the Colorlight sender), so DisplaySwitch /extend has nothing to extend to and wasn’t run. Options to keep the desktop off the panels:
tools/rope_tests.ps1 colour|order|direction|all, new sources box1_red, box2_green, rope, heads). The run at 01:35:42–01:37:22:
color_order unchanged pending Gavin’s report.project.save(path) with TD’s incremental save on (general.inc = 2) tried to write river.1.toe, found it existed and opened a modal “Replace?” that froze the bridge. Fixes:
general.inc set to 0 and saved to TD prefs.tools/td_save.ps1: checks the pref, saves, verifies the river.toe timestamp and deletes stray river.N.toe.td.ps1: 20 s timeout. On timeout it lists TD’s windows and names any dialog (exit 3); it now shows TD tracebacks plainly and always sets its exit code.comp.storage, which TD pickles on save. Socket and config now live in a sys.modules holder, migrated live without dropping output.general.startupfilename still points to Desktop\Bitcube4\Bitcube4.toe (startupfilemode 2). It’s harmless while the launcher passes river.toe.Active off; port 6454 released). Panels Source=black, window still open.river.toe saved in this dark state, so a reboot comes up dark. RopeLights stopped (task Ready, no trigger).dmxout1 off). So when Art-Net stops, the hardware falls back to its own program: either the rack controller’s SD card (program 2) or the PSAC10s’ PLAY mode. That answers hardware open question 3: live Art-Net overrides it, and silence hands control back.Active on with Source=black (continuous zeros at 40 fps, 0 W), saved into river.toe.Ethernet) showed Disconnected again. bitcube’s Tailscale was offline from about 02:45 until the reboot, and the mini’s own Tailscale had stopped (restarted with Gavin’s OK, same settings).M14) is now plugged in as well as the Colorlight sender (LED 1920X1080).C:\Users\user\River is now a plain folder (not a repo, still the SMB share) holding two checkouts:
river-bitcube\: this repo, moved from the River root. Copied with robocopy, then old root copies deleted.river-agent\: Dave’s repo, copied from the mini’s clone. bitcube has no GitHub credentials for it.CLAUDE.md describing the layout.river.toe there (td_save.ps1). TD now runs from river-bitcube\river.toe with no errors. Startup shortcut now targets river-bitcube\Start-River.cmd.td/build/*.py, the bridge installer, CLAUDE.md and the README.safe.directory for river-agent in bitcube’s global git config and core.filemode=false in that repo, since an exec-bit difference had shown as a change.192.168.8.103, river E1 Outdoor Pro 192.168.8.217, RTSP /Preview_01_main on 554, user admin. The password is in the untracked secrets.local.json only. bitcube reaches both over Will’s tailnet, and tools\cam_snap.ps1 gallery|river works (12:10).
frames\ (git-ignored).tools/cameras/test_cam_move.py, and the details are in the hardware doc.drocamor/river-agent (push access) and posted an SSH public key for bitcube (comment river, SHA256:aXW4LMdJXbPfPv8mRImLDWTjkVZ3f6Y818HEqin+/No). The key is not yet added: the mini session’s attempt was blocked pending Gavin’s confirmation.administrators_authorized_keys, with Gavin’s OK). Dave can ssh user@bitcube.tail03bc1a.ts.net over Will’s tailnet.bcdedit /set {fwbootmgr} displayorder {bootmgr} /addfirst); Ubuntu stays in the list.AutoAdminLogon=1 but no stored password, so it fell back to the login screen. Installed Sysinternals Autologon (winget) and set user / BITCUBE; the password is an LSA secret.DevicePasswordLessBuildVersion=0 (Hello-only sign-in was on).ForceDaemon) was off, so Tailscale only connected while someone was logged in to Windows. That’s why bitcube was offline from the 01:55 shutdown (a manual Start → Shut down, via RuntimeBroker) until Gavin logged in at 12:02.tailscale set --unattended=true, so it now connects at boot before login and survives logout.Start-Claude.cmd plus a Startup shortcut (Start-Claude.lnk). 20 s after login it opens Windows Terminal in C:\Users\user\River and runs Claude with a prompt to read the root CLAUDE.md, both repos’ CLAUDE.md/README and all of river-bitcube\docs, check git status, summarise, and then wait. Not yet seen running; the next reboot will show it.user with no password screen. TD opened river-bitcube\river.toe (12:27:55), with the bridge OK and 0 errors. Windows Terminal + Claude started in River (12:28:04), and bitcube was on Tailscale. About 1 minute end to end. The lighting NIC (Ethernet) is still Disconnected: physical cable or LED controller power.docs/index.md (welcome/status), docs/plan.md (checklist with owners plus open questions) and docs/_config.yml. Made gavaiken/river-bitcube public and enabled GitHub Pages from main:/docs → https://gavaiken.github.io/river-bitcube/ (all pages return 200).CLAUDE.md now says the repo is public and sets the coordination rules: git pull first, one Claude at a time, tick plan.md and update index.md + the log in the same commit as the work.tools/rope_capture.ps1 on bitcube with the river cam (it’s the E1 Outdoor Pro sitting on the LED controller, not the gallery cam): baseline, each rope alone at 40%, heads, box1 red, box2 green.
tools/rope_identify.py) puts ropes 1/4/8/10 in the right coil pile, 2/3/5/6/7 in the middle and 11/13/14 on the left.frames/ (people appear in them).docs/plan.md:
10.0.7.76, read from the Reolink app). The mini Claude aimed it with tools/cameras/ptz.py (down 0.4 s, left 0.3 s, right 0.12 s) so it sees every coil pile, the HUB75, both PSAC10s and the controller.docs/img/rope-map-2026-10-18.png.location/justifyoffsetto = specifydisplay, monitor expression picks the LED… monitor). The camera confirms quad 1 shows the test pattern correctly (red TL with the quad-1 marker, green TR, blue BL, yellow BR). The earlier “split right column” was the test bar, now off. Saved river.toe; build_panels.py updated. Image: docs/img/hub75-quad1-test-2026-10-18.jpg.Start-Status.cmd + Startup shortcut Start-Status.lnk. 40 s after login, after TD (10 s) and the Claude terminal (20 s), it runs tools/status_page.ps1, which opens Chrome (--new-window --start-maximized) on the primary monitor (M14).file:///…/docs/index.md.tools/tests/status_page.Tests.ps1, 5/5 passing (Invoke-Pester .\tools\tests).docs/execution-plan.md): a status table (✅/➡️/❌), lettered sessions with machine and model (A = coordinator on the Mac mini; B–G on bitcube), numbered steps, and a SESSION SUMMARY format that each session ends with, for pasting back to the coordinator.docs/sessions/<letter>.md (a line per step, then a SESSION SUMMARY) and updating the Status table in docs/execution-plan.md after every step. Gavin says “sync” to session A, which runs git pull and reports. The contract is in docs/execution-plan.md and CLAUDE.md. P1 (ropes 9/17 swap test) was deferred by Gavin; B is next.river-local-oct-18.toe, a Save As of the running river.toe made before any building, so river.toe is untouched. TD runs it now. The login autostart still opens river.toe (not changed, per Gavin).tools\td_save.ps1 now saves the file TD has open by default; -Target <file>.toe does a Save As. A plain save in the checkpoint can no longer overwrite river.toe.tools/pixelmap/, venv .venv, pytest tools/pixelmap, 22 tests): new rope Source gray (Graybit 0–13, Grayinvert). Gray code: rope index 5 bits, pixel 9 bits, each bit plus its inverse, plus black; two passes with retakes on disagreement; one ffmpeg RTSP reader at 1440×808.
capture.py ropes takes about 2 minutes. decode.py gives per camera pixel (rope, px, conf), per rope pixel a weighted-median (u, v), outlier and island rejection, and fill along the rope (no chords across jumps between piles).tools/pixelmap/pixelmap-2026-10-18.json.capture.py hub75 + hub75.py, stored as hub75_quad1 in the pixel map./project1/river_local (td/build/build_river_local.py, built-in TOPs only, 1280×720 in camera space):
rowswrapped → flop → 20×400 → ropes Canvas; Corner Pin → panels Quad1. Checked with the Uvtest field (td/scripts/check_river_local.py): max error 0.0006.Source=canvas, Brightness 0.4 (cap), about 70–200 W total; panels Source=canvas, Brightness 0.5, quad 2 blanked; TD 60 fps, Art-Net about 35 fps sent, no drops. Andi’s Web Render is off in this file.cook(force=True).`r and `t become control characters. Write files from Python or the Write tool.b04n lit ropes 0–15 fully (box 1 at its 600 W limit plus about 360 W on box 2) and b13n lit 64% of every rope, each twice, at 0.4. capture.py now dims every bit/inverse pair so no box draws more than half its power at the cap (graycode.pattern_brightness, at most 300 W/box), and logs the brightness per pattern. The 15:42 capture stays valid: the decoder is unchanged.gray_frame returns black for an out-of-range bit, instead of a pattern that could light all ropes white.build_river_local.py refuses to run unless a river-local*.toe is open, so it can’t rewire river.toe. It builds from the newest pixelmap-*.json; decode.py and hub75.py use the same rule.capture.py puts the ropes (Active, Source, Brightness, Graybit, Grayinvert) and panels Source back as they were, even on failure. Checked on the hardware at 16:04.td_save.ps1 saves river.toe when TD has an incremental river.N.toe open. There are clear errors when the HUB75 isn’t seen or no rope is mapped, and a test checks artnet_out.gray_frame against the decoder. 26 tests.RiverSnapshot (registered by tools/snapshot_task.ps1) runs tools/snapshot.ps1 daily from 08:00, every 15 min for 18 h. Each run grabs a 640×360 gallery-cam JPEG and force-pushes it as gallery.jpg to the orphan branch snapshot.
%LOCALAPPDATA%\river-snapshot\repo.git with the deploy key, so it never touches the working checkout. The log is next to it (snapshot.log, camera login masked).conhost --headless so no console window flashes on the M14. Auto-login means it runs whenever bitcube is up.Invoke-Pester .\tools\tests (18 tests).<img> starts as the checkpoint still and switches to the live snapshot only after it loads, so the page never shows a broken image. It shows the snapshot time from the GitHub API./project1/panels/window now shows a screen Container COMP sized to the LED monitor (1920×1080, found by EDID name). It is opaque black, with an atlas child that shows panel_out at native size (nearest filtering) pinned to the top-left.
y counts up from the bottom, and justifyv='top' on the child didn’t move it, so the atlas has y = parent().height - me.height.river-local-oct-18.toe and then river.toe. river.toe (the autostart file) is open now: ropes black, panels test pattern.artnet_out.tick compared absTime.seconds with last_send from comp.storage. Storage is saved in the .toe, but absTime restarts at 0 when a project loads, so the sender waited as long as TD had been running at the last save. While it waited, the hardware played its own program (the coils went full red at 16:44).
last_send ahead of the clock is reset. Verified by save and reload: Art-Net resumes 1.4 s after load.Start-River.cmd now opens river-local-oct-18.toe. Restart test at 16:53:46: Windows back at 16:54:39, TD in the rain file with the bridge answering at 16:54:53. Ropes Source=canvas (rope_canvas), panels Source=canvas with the window open, Art-Net sending. Watts vary 8–27 per box as drops pass; 60 fps. The gallery cam shows the teal/blue rain on the coils. Session C’s sender-stall fix held: the ropes didn’t go red on load.system.json is the source of truth; the clickable SVG diagram groups nodes by place (the River, Agape/Gray Area scenarios, Modal cloud, Tailscale), with IPs, usernames and the Modal↔bitcube API; system.md + llms.txt serve agents. Runs on the Mac mini (Opus, plan mode). Gavin’s rule: everything except secrets.river-local-oct-18.toe (the last also lists Start-Claude, Start-Status and RiverSnapshot). Session C’s “Waiting on Gavin” item about it is closed.10.0.7.76 on Agape WiFi, aimed at the piles).plan.md as the live checklist.docs/system/system.json is the source of truth: 6 places, 60 nodes (all 20 ropes with box, OUT and universes), 83 links, scenarios now (Agape) and show (Gray Area, planned), the Modal↔bitcube API with live examples, 13 secrets by name and location, 15 open questions, and the source of every fact. Anything not checked is marked unverified or awaiting:<Name>.docs/system/index.html is a self-contained page: SVG map, a details panel for every node and link, deep links (#node=bitcube, #link=artnet-box1, #scenario=show, #tab=api), search by name/IP/hostname, Now/Show switch, List, API, Secrets, Open questions and For agents tabs, light/dark, phone layout, keyboard access.tools/system_docs.py generates docs/system/system.md (text plus a Mermaid diagram per scenario). docs/llms.txt indexes the docs for agents..venv/bin/pytest tools/tests, 62): structure (ids, link ends, placement per scenario, enums, Will’s rope mapping, API states); a secret-pattern scan of the published files; every tracked file checked against the real values in bitcube’s secrets.local.json, read over ssh at test time and never printed; system.md in sync; headless Chrome (Playwright with the installed Chrome) clicking every node and link. These checks caught two page bugs, both fixed.SITE_TOKEN is not set on Modal: /data/*.json answers without a token (17:21). Recorded in plan.md’s open questions.10.0.7.0/24 (the Agape LAN) into Will’s tailnet. Session A and Gavin fixed it at 17:47, and bitcube now shares the gallery cam as 10.0.7.76/32 (session A’s notes).0.0.0.0:9980 but answers only localhost./32 route..worktrees/session-i) because session A was committing in the same checkout.Source=black set live in river-local-oct-18.toe (output max 0.0, gallery cam shows the panel dark; the window still covers the LED display in black). Not saved, so the next reboot or reload brings the HUB75 rain back. The ropes still show the rain (about 136 W). To turn it back on: .\tools\td.ps1 "setattr(op('/project1/panels').par, 'Source', 'canvas')".2.0.0.10 and .11 no longer answer ping). TD still sends the rain over Art-Net, which is harmless to unpowered boxes, so the rain comes back as soon as they are powered on.