"Location", never "campus", in everything people read; SC FOH joined with its MIDI links

- pages (NA 98 Locations / 99 Location, re-imported via PAGES_VERSION), keys, settings page, setup and
  install messages, alerts, docs, the Apollo Beach kit; python3 -m settings.location and /location/...
  addresses (the old names still answer for installed Macs)
- Apply reads the before settings from the file: an in-place edit skipped the watchdog restart
- SC: SUPERRACK (+SoundGrid) and X32 EDIT from SC FOH; FOH TRACKS and TRACKS LIGHTS MIDI links watched

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 13:42:22 -04:00
co-authored by Claude Opus 5.5
parent d0c755824b
commit 7068244ba4
31 changed files with 951 additions and 788 deletions
+547 -547
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -51,7 +51,7 @@ Weaknesses
Strengths
- Wizards that map one-to-one onto the user's own examples: Add a MIDI link with live pickers, Add or remove a HyperDeck adjusting the REC members too, Change the playlist by pasting a link, Add a computer, Add a Windows app task, New campus; plus a demo-mode walkthrough.
- Wizards that map one-to-one onto the user's own examples: Add a MIDI link with live pickers, Add or remove a HyperDeck adjusting the REC members too, Change the playlist by pasting a link, Add a computer, Add a Windows app task, New location; plus a demo-mode walkthrough.
- The live Stream Deck picture on the Overview from sp_state with click-through to the key, a global search box, and a "Stream Deck" (where it sits) versus "Keys" (what it does) split a volunteer gets in one sentence.
- The safest Apply order (restart the watchdog, prove it, then pages and nav with a dry run shown), the key guide regenerated on every Apply, History never auto-pruned, and "Undo last apply" on the Overview.
- Makes alert_after_seconds and the fix cooldown editable with the key texts following; validates fix kinds in load_config; requires host or conn on ping checks; the settings server imports only load_config, CHECKS and make_page so a page bug cannot take the panel down.
@@ -68,7 +68,7 @@ Weaknesses
### Ideas the judges asked to graft (and where they landed)
- From teaching: restart the watchdog and prove it started before pages are rebuilt or imported, and roll pages back too (K10).
- From teaching: the job wizards for the named asks (K4, P4) and "New campus from this one" (K17).
- From teaching: the job wizards for the named asks (K4, P4) and "New location from this one" (K17).
- From teaching: the live deck on the Overview from sp_state with click-through (K4); the "what this key will say" preview (K5); the key guide rebuilt on every Apply (K15); History never auto-pruned (K14); Undo the last change (K14); "done by hand" ticks (K8 manual_done); alert_after_seconds and the fix cooldown editable with the key texts following (K12); a global search box (D10).
- From simplest: the AST-based schema sync test and "defaults in code must equal the schema" instead of removing the defaults from the watchdog (K16); the Phase 0 round-trip test (K16, P0).
- From simplest: the password-free edit gate, later reduced from allow-list plus unlock plus typed APPLY to one editing code (K2, C3).
@@ -156,7 +156,7 @@ Round 1 critics read the first full plan, round 2 the revision that answered the
| 2 | Simplicity | major | The settings page needs its own Spotify permission, a Test button and an extra Allow step. | ADOPTED | K9 one permission light; K7 Run now goes through the watchdog so the page never drives Spotify; the P1 spike checks the grant. |
| 2 | Simplicity | minor | Map cells are walls of text. | ADOPTED | K4 and K8: one status word per row, what it does, the keys that turn red. |
| 2 | Simplicity | minor | Six different "test" buttons with unclear effects. | ADOPTED | K9 read-only buttons say "Check ..." ; K7 "Run this fix now" is the one that acts. |
| 2 | Simplicity | minor | Update the program and the campus export sit on the normal Site screen; pull_site.py is a terminal step. | SIMPLIFIED | C12 Install the staged folder and Export site bundle sit under Site setup (set up once); the K17 export replaces pull_site.py; scp remains (K13). |
| 2 | Simplicity | minor | Update the program and the location export sit on the normal Site screen; pull_site.py is a terminal step. | SIMPLIFIED | C12 Install the staged folder and Export site bundle sit under Site setup (set up once); the K17 export replaces pull_site.py; scp remains (K13). |
| 2 | Simplicity | minor | Per-editor drafts with take-over and discard add a multi-user merge concept. | ADOPTED | K10 one shared draft; the 409 names who changed what. |
| 2 | Simplicity | minor | The Keys grid draws three overlays; "+ New key" offers ALL, ALARMS and NET. | ADOPTED | K5 draws the 8x4 deck; fixed chips for ALL / ALARMS / NET. |
| 2 | Simplicity | minor | Overview carries admin wizards, gear, a log tail and duplicate lights. | ADOPTED | K4 problems, the deck, computers, three job buttons plus More jobs, status lines (round 3 Simplicity set the three). |
@@ -193,7 +193,7 @@ Round 1 critics read the first full plan, round 2 the revision that answered the
| 3 | Completeness | major | install.sh's deploy list omits the remote-access templates and companion-objects. | ADOPTED | K13 deploys both; K17 nav_templates/<version>.json. |
| 3 | Completeness | major | Windows batching with %ERRORLEVEL% expands before the command runs, so every check reports OK. | ADOPTED | K12 generates per-command conditional echo pairs (SPn=0 on success, SPn=1 otherwise), never a bare %ERRORLEVEL%, verified once on the Lighting PC. |
| 3 | Completeness | minor | No expected module per check type; a HyperDeck check on a generic TCP connection is silently wrong. | ADOPTED | K12 EXPECTED_MODULE filters the pickers and warns on mismatch; it lives in the K16 registry. |
| 3 | Completeness | minor | restart_page is optional but the Keys screen always has the tab and chips. | ADOPTED | K9 "this campus has no Restart page" switch (built in P3). |
| 3 | Completeness | minor | restart_page is optional but the Keys screen always has the tab and chips. | ADOPTED | K9 "this location has no Restart page" switch (built in P3). |
| 3 | Completeness | minor | Windows cannot cross midnight. | ADOPTED | K18. |
| 3 | Completeness | minor | Add a MIDI link has no typed fallback when the Mac is off. | ADOPTED | P4. |
| 3 | Completeness | minor | The Ingest self record can be named by ssh fixes, remote checks and midi_peer (a runtime KeyError). | ADOPTED | K12 host validated (exists, has ssh, not self); builders switch to local for the self record. |
@@ -280,7 +280,7 @@ C14, preview run. Review has no "Preview the deck with these settings" button th
- Raw Custom commands (K6) are a remote-command surface on seven computers, guarded by one code over plain HTTP on a LAN. Mitigation: LAN-only binding narrowed by hosts.ingest.networks (K1), origin check and lockout (K2), the code asked again and the command shown red in Review (K6), zsh -n / sh -n, History naming the editor (K14), and the private repo's access list deciding who holds the code.
- Probes are parameterised, not fixed (K8): names and paths from the config reach ssh lines. Mitigation: shlex-quoted and regex-checked parameters, a fixed command set, the metacharacter test (K16), never run during a fix, 6 s timeout, never wake a PC.
- Windows DefaultShell (K12): the batched checks assume cmd.exe. Mitigation: a light on the PC's card and refusal of cmd-batched checks when the shell is not cmd; verified once on the Lighting PC; setting DefaultShell stays a by-hand system change for the user.
- Python 3.13 removes telnetlib, which netgear.py uses (K12 self-check for 3.9-3.12). Mitigation: the self-check light; a newer macOS at another campus would lose the Dante map and PoE cycling until telnetlib is replaced, which is not in this plan.
- Python 3.13 removes telnetlib, which netgear.py uses (K12 self-check for 3.9-3.12). Mitigation: the self-check light; a newer macOS at another location would lose the Dante map and PoE cycling until telnetlib is replaced, which is not in this plan.
- Companion tRPC spike unknowns (P1): custom-variable creation, trigger import, resetControl blanking a cell, the OBS variable, the page walk, whether one Automation grant covers both agents. Mitigation: recorded answers before any Apply step depends on them, with fallbacks (by hand, "unknown", schedule-only).
- Reads are open on the LAN (K2): logs, history bodies and the fleet map are visible to anyone who joins the network. Mitigation: the webhook is masked everywhere, no secret is in History, the bind is narrowed to the named LAN interfaces (K1).
- The only live signal is a recording HyperDeck (K11, C7), and a stale live-now.json falls back to the schedule. Mitigation: Review says "schedule only" when stale, Q2 fills the windows, OBS follows the spike.
+11 -11
View File
@@ -19,13 +19,13 @@ Values are typed once: every string that names a program, path, task or helper l
| `site.id` NEW | Site setup > Site (Advanced) | Site id | Short name for folders and files ("na"). | `[a-z0-9_-]+`; restart |
| `site.name`, `site.ingest_name`, `site.ingest_hostname`, `site.ingest_ips[]` NEW | Site setup > Site | Site name, this Mac's name, network name, addresses | Used in log headers, alert text, key notes and generated setup scripts (replaces "NA Ingest" and the IPs in windows-setup.ps1). [Check this Mac's network ports] fills the addresses. | non-empty; IPs valid; restart (a changed note alone never forces a re-import, D11) |
| `site.settings_port` NEW | Site setup > Site (Advanced) | Port | Where this page listens: loopback plus every private-address port, narrowed by this Mac's LAN list. Default 8020. | 1024-65535; the dialog states the consequence (the page moves to the new address); settings |
| `site.editing_code` NEW | Site setup > Site (Advanced) | Editing code | The code that switches Editing on. It is a setting in this campus's `config.json`, kept in the private git repo, so everyone with the repo has it (the user's choice, 2026-10-13); browsers remember it with the person's first name. Masked in every API response unless the request carries it. The one code: no admin code, no address list, no page-generated code. | non-empty; changing it: the dialog says every browser must enter the new code; none |
| `site.editing_code` NEW | Site setup > Site (Advanced) | Editing code | The code that switches Editing on. It is a setting in this location's `config.json`, kept in the private git repo, so everyone with the repo has it (the user's choice, 2026-10-13); browsers remember it with the person's first name. Masked in every API response unless the request carries it. The one code: no admin code, no address list, no page-generated code. | non-empty; changing it: the dialog says every browser must enter the new code; none |
| `site.live_services[]` NEW | Site setup > Schedules | Live services | When a service is on: Apply, Run now, Restart the watchdog, Re-import, Check the switcher and Install are refused and your draft stays saved; auto-fix may run; alarms are always on. Defaults to `auto_fix.windows`; the Phase 0 migration writes it. | days in mon..sun; `HH:MM`; end <= start = runs past midnight (allowed); warn if empty; restart (ServiceMode is built at start) |
| built-in live signal: a watched HyperDeck that "follows the recording" is recording | Site setup > Schedules ("Also counts as live", read-only line with "Live now?") | - | Derived from every hyperdeck check with "follows the recording"; the watchdog writes `live-now.json` on change / every 5 s with a timestamp; older than 30 s = schedule only (said in Review). No connection/variable/value triple on the page; "OBS is streaming" is added as a built-in kind only if the Phase 1 spike finds the module variable. | DNE; warn when no watched deck follows the recording |
| `site.contacts` NEW | Site setup > Site | Contacts | Printed on the cheat sheet. | free text; none |
| `site.dvs_helper`, `site.solo_dir` NEW | Site setup > Site (Advanced) | DVS helper path, Studio B helper folder | One owner for paths that fixes, checks and scripts repeat; builders and templates regenerate from them. | absolute path; restart |
| `alert_webhook`, `site.alert_prefix` NEW, `timing.alert_after_seconds` NEW | Site setup > Site / Schedules (Advanced) | Alert message (web hook), message starts with, alert after | Posts "<prefix>: Companion has not answered for N s" and the all-clear; also a line for every command edit applied. Blank = off. Shown masked everywhere ("set, 44 chars"); [Change] [Send a test alert]. | http(s) or blank; 5-600; restart (captured in run()) |
| `ssh_key` | Site setup > Site (Advanced) | Login key | Private key on this Mac for every other computer; light + public half with [Copy]. [Make the login key] on the Setup tab makes the panel's own pair at a new campus (asks first). | file exists, 0600; `.pub` readable; restart |
| `ssh_key` | Site setup > Site (Advanced) | Login key | Private key on this Mac for every other computer; light + public half with [Copy]. [Make the login key] on the Setup tab makes the panel's own pair at a new location (asks first). | file exists, 0600; `.pub` readable; restart |
| `companion.host/port/db` | Site setup > Companion (Advanced) | Address, port, settings database | Where Companion answers. The DB is read read-only for labels and addresses (module version only if the Phase 1 spike finds it trivially); blank = newest `vN.N/db.sqlite`. push_page and nav_keys read these too. | host non-empty; 1-65535; path exists; live probe; restart |
| `variables.state/heartbeat/command`, `variables.flash` NEW | Site setup > Companion (Advanced) | Variable names (state `sp_state`, heartbeat `sp_hb`, command `sp_cmd`, blink `flash_tick`) | Must exist in Companion: a hard error when Companion answers, a warning ("could not check") when it does not. Renaming the blink variable means renaming it inside the trigger in Companion too (said beside the field). | `[A-Za-z0-9_]+`; exists; pages + restart |
| `page`, `page_name`; `restart_page.page`, `restart_page.page_name` | Keys tab header (only home; the Companion section links here) | Page numbers and names | Name derived "<n>\nStatus" / "<n>\nRestart" unless overridden. Number change: the old page keeps its keys; Apply resets our marked keys on it (asks; if the spike shows `controls.resetControl` cannot blank a cell, Review lists "delete these N keys on page 19 by hand") and re-runs the page-number buttons. Name-only change on an existing page: rename it in Companion first (live name shown). "Pages exist" light. | int >= 1; distinct; name contains the number; live checks; pages |
@@ -68,7 +68,7 @@ Values are typed once: every string that names a program, path, task or helper l
| `tiles[].id` | Keys (Advanced) | Id | Used inside Companion; master is `all`. | `[A-Za-z0-9_]+`; unique vs restart keys; pages |
| `tiles[].label` | Keys | Label | First line and prefix of faults. | <= 10 warn; pages |
| `tiles[].pos` | Keys (drag) | Position / tray | Blank = in the tray "Shown inside the RF group (no key of their own)". | in grid; not col 0 rows 0-2; no overlap incl. jump/back pos; pages |
| `tiles[].kind` | Keys | Kind | single key / group; ALL and ALARMS are fixed chips (moved and edited, never created or deleted); NET may be removed at a campus that does not want it (at most one; D13). | exactly one ALL, one ALARMS, at most one NET; pages |
| `tiles[].kind` | Keys | Kind | single key / group; ALL and ALARMS are fixed chips (moved and edited, never created or deleted); NET may be removed at a location that does not want it (at most one; D13). | exactly one ALL, one ALARMS, at most one NET; pages |
| `tiles[].members[]` | Keys | Group members | Worst member shown ("worst member + N"); hold fixes all. | ids exist; not self; a hidden key must be in a group (warn); restart (pages when hold-ability changes, detected by the build) |
| `tiles[].checks[]` | Keys | Checks | See per type. Changing a key's check list drops that key's remembered acknowledgements and auto-fix tries (said in Review). | type in CHECKS; restart (pages when the build differs) |
| `tiles[].hold_always` | Keys > When held | also when the key is green | Even when green (HD, TASCAM, SPOTIFY). | fix exists with label; pages |
@@ -96,12 +96,12 @@ Values are typed once: every string that names a program, path, task or helper l
| artnet `source/max_silence_seconds/msg` | check row | Sender, silence, text | Port 6454 is fixed. | IP; 1-60; restart |
| atem check `part/msg` | check row | Part, text | Needs the ATEM section. | restart |
| `atem.host/node/library/reference`, `atem.compare` NEW, `atem.source_folder` NEW | Site setup > ATEM | Switcher address, patterns (resolved paths shown), saved file (upload or pick the newest from the folder), folder, what to keep in line | The upload (capped at 20 MB; XML with a DOCTYPE or entity declarations refused; parsed in the settings process with the watchdog's own parser) replaces `atem-reference.xml` atomically together with the config; its hash goes into History; the old file is kept dated under `history/atem/`; refused during a live service; Review shows "product name matches / N audio and M camera values differ from the current file" and needs the tick "I checked this is the right file for this switcher"; [Check the switcher now] reads only (3 s, a second connection, guarded). | IP; globs resolve; XML parses with the watchdog's own parser, no DOCTYPE or entity declarations, <= 20 MB; compare is a subset of MIX_OPTIONS/CCU_PARAMS; folder exists (light); restart |
| "this campus has no ATEM" switch (the `atem` section absent) | Site setup > ATEM | tick box | Hides the section; an atem check or a saved-switcher-file fix then fails validation with the key named. | cascade listed; restart |
| "this location has no ATEM" switch (the `atem` section absent) | Site setup > ATEM | tick box | Hides the section; an atem check or a saved-switcher-file fix then fails validation with the key named. | cascade listed; restart |
| `restart_page.jump_pos/back_pos`, `restart_page.keys[].id/label/pos/fix/watch[]` | Keys (Restart tab) | jump/back chips; restart keys: label, position, fix, "keep flashing HOLD TO FIX while these are down" | watch = fix ids and "conn:<label>". | id unique vs tiles; fix exists; labels live-checked; pages (fix/watch: restart) |
| "this campus has no Restart page" switch (the `restart_page` section absent) | Keys (Restart tab) | tick box | make_page builds no Restart page and no jump key; the restart keys and the jump chip go with it (cascade listed). | cascade listed; pages |
| "this location has no Restart page" switch (the `restart_page` section absent) | Keys (Restart tab) | tick box | make_page builds no Restart page and no jump key; the restart keys and the jump chip go with it (cascade listed). | cascade listed; pages |
| Companion connection labels | Site setup > Companion | live list with module id, status, watched by; rename-to for a vanished label; [Add a key for it] on unwatched ones | | warning only |
| custom variables / blink trigger / modules / pages exist / our pages / page-number buttons | Site setup > Companion | lights; "coloured on N of M pages" (counted when the section is opened) + [Colour them now] + [Undo]; [Re-import the pages now] | Set up once by the person who installed Companion. | by hand except nav revert and re-import |
| `companion-objects/` (trigger export, quiet Tascam module, nav templates per version) NEW | Help > Set up a new campus | shown with the import steps | Captured from NA once (Phase 1); not editable on the page. | repo files, deployed to the data dir |
| `companion-objects/` (trigger export, quiet Tascam module, nav templates per version) NEW | Help > Set up a new location | shown with the import steps | Captured from NA once (Phase 1); not editable on the page. | repo files, deployed to the data dir |
| Windows program table (`runs[].kind=task`) | Computers (card) | task name, exe candidates, args, at logon | Generates windows-setup.ps1, task names in fixes and the "is running on a Windows PC" check. | cmd-safe regex; none (dependents -> restart) |
| `$Key`, `$IngestIPs` in scripts | Computers > Setup | from `ssh_key.pub` and `site.ingest_ips` | | - |
| `{{PT_BUNDLE_ID}}`, `{{SOLO_MENU_PATH}}` in the solo agent | Computers (Studio B card, Advanced) | Pro Tools bundle id, solo menu path | Differ per Pro Tools version/language; defaults are today's values. | non-empty; regenerating shows the agent needs a rebuild + Accessibility re-grant |
@@ -171,7 +171,7 @@ The other NA records: **prop** (sshd, DVS daemon NA-ProPresenter-Mac, helper_dvs
- Every Mac: Remote Login on; Ingest login key authorised (generated `mac-authorize.sh`); host key known (with "changed since last time" + [Forget the old login key]); `/usr/bin/python3` present (for MIDI reads); DVS helper + sudoers (computers with `helper_dvs`); Audio MIDI Setup sessions named as the checks expect (expected beside live; a peer added by the Add a MIDI link job shows "will be added on first hold"; a typed session shows NO SESSION until it exists); apps at the listed paths; Studio B: solo agent running, `solo-mode.json` fresh, `trusted: true` (Accessibility), swiftc present for a rebuild.
- Every Windows PC: sshd Automatic + running; OpenSSH DefaultShell is cmd.exe (light); firewall rule allows this site's Ingest IPs; key login works (both authorized_keys files); a `\StatusPanel\` task per `task` run; services' failure-restart; WoL on the adapter; BIOS WoL (Done by hand); Public profile when rtpMIDI is listed (light + Done by hand); Vista autoload (Done by hand); Wi-Fi power (Done by hand); RESULT block pasted (fills ssh user, MAC, IP); the host-key-changed line as on Macs.
- This Mac: Command Line Tools / python 3.9-3.12; watchdog agent (loaded, running, ExitTimeOut set to the derived value); settings agent; Companion checklist (variables, blink trigger, pages exist, our pages, quiet Tascam module, ATEM module, "use last page" noted); keychain item (if `dante_switches`); the watchdog's Spotify permission (if a spotify check); DVS helper + sudoers (if dvs_ingest); login key pair ([Make the login key] at a new campus); editing code present; ports for LAN / Dante / switch management up; Art-Net port bound (if artnet); saved-file folder mounted (if `atem.source_folder` is set); Remote Login on (for the MacBook's `checklist-<id>` alias); Church Translate not loaded.
- This Mac: Command Line Tools / python 3.9-3.12; watchdog agent (loaded, running, ExitTimeOut set to the derived value); settings agent; Companion checklist (variables, blink trigger, pages exist, our pages, quiet Tascam module, ATEM module, "use last page" noted); keychain item (if `dante_switches`); the watchdog's Spotify permission (if a spotify check); DVS helper + sudoers (if dvs_ingest); login key pair ([Make the login key] at a new location); editing code present; ports for LAN / Dante / switch management up; Art-Net port bound (if artnet); saved-file folder mounted (if `atem.source_folder` is set); Remote Login on (for the MacBook's `checklist-<id>` alias); Church Translate not loaded.
**Generated scripts** (`settings/generate.py`): "Generate" fills `remote-access/mac-authorize.sh.template`, `mac-dvs-helper.sh.template`, `windows-setup.ps1.template`, `install-solo-mode.sh.template` and `solo-mode-agent.swift.template` with the placeholders `{{PUBLIC_KEY}}`, `{{INGEST_IPS}}`, `{{APPS}}`, `{{DVS_HELPER}}`, `{{SOLO_DIR}}`, `{{SOLO_LABEL}}`, `{{PT_BUNDLE_ID}}`, `{{SOLO_MENU_PATH}}` and `{{SITE}}` from the site's public key, Ingest IPs, program table, helper paths and site name; every Mac value is shell-quoted, every Windows value passes the cmd-safe regex (and contains no `!` or `^`); the Windows script also sets the OpenSSH DefaultShell to cmd.exe. Each script is shown with Copy / Download and the exact place to paste it (ARD "Send UNIX Command as root" / PowerShell as administrator / scp + ssh for Studio B; a rebuilt solo agent needs Accessibility re-granted on that Mac). The page never runs them (guideline 12). The schema check compares `site.solo_dir` against the generated strings of the Studio B checks, the solo fix and the swift template, so all three agree by construction. The templates are deployed to the data dir by `install.sh`, and `test_generate_from_data_dir` (Phase 5) proves generate.py finds and fills every one of them there.
@@ -332,10 +332,10 @@ Every inventory item, and where the plan handles it or why it is deliberately no
| mdns instance/name (picker); Bonjour type fixed | Keys; type DNE |
| midi_rx source/name/max_silence_seconds | Keys |
| remote host/cmd/msg/shell NEW (Macs and Windows PCs); artnet source/max_silence/msg (port DNE); atem check part/msg | Keys; remote built from "A program is running on a Mac" / "on a Windows PC" / "A helper file is fresh" builders, Custom under Advanced with the editing code typed again, `sh -n` on the batched Mac line, Windows pairs with no `%ERRORLEVEL%` (verified on the Lighting PC), DefaultShell light, never run before Apply; host not self |
| atem section/host/node/library (resolved)/reference (upload, dated history)/source_folder NEW; MIX_OPTIONS/CCU_PARAMS; parser; atem_watch.js constants; atem_state.js | Site setup > ATEM incl. `atem.compare`, pick-newest from the folder, upload cap/DOCTYPE/diff/tick, live refusal, the saved file as part of the applied set (atomic, hashed in History, restored by rollback and Go back, never overwritten by install.sh), guarded "Check the switcher now" with the client-limit note; "this campus has no ATEM" switch; js constants DNE |
| atem section/host/node/library (resolved)/reference (upload, dated history)/source_folder NEW; MIX_OPTIONS/CCU_PARAMS; parser; atem_watch.js constants; atem_state.js | Site setup > ATEM incl. `atem.compare`, pick-newest from the folder, upload cap/DOCTYPE/diff/tick, live refusal, the saved file as part of the applied set (atomic, hashed in History, restored by rollback and Go back, never overwritten by install.sh), guarded "Check the switcher now" with the client-limit note; "this location has no ATEM" switch; js constants DNE |
| auto_fix section/windows/after/tries/retry/pause/restart_connections/fixes/forget_seconds/log_dir/retention/header text | Site setup > Schedules (tick list and restart_connections main; numbers, folder and `keep_months` Advanced with defaults); windows derived from live services; header and "may run by itself" phrase built from site + windows; restart (AutoLog in __init__) |
| site.live_services NEW (and the former site.live_signals idea) | Site setup > Schedules (one schedule incl. overnight windows); defaults to `auto_fix.windows`, the migration writes it; "Also counts as live" shows only the built-in recording-deck signal (no conn/var/value triple; "OBS is streaming" only as a built-in kind if the Phase 1 spike finds the module variable); stale handling (30 s); no quiet time and no queue: Apply is refused while live and the draft is kept |
| restart_page section/page/page_name/jump_pos/back_pos/keys id/label/pos/fix/watch; section absent | Keys Restart tab (jump/back chips, "this campus has no Restart page" switch with its cascade; make_page builds nothing when absent) |
| restart_page section/page/page_name/jump_pos/back_pos/keys id/label/pos/fix/watch; section absent | Keys Restart tab (jump/back chips, "this location has no Restart page" switch with its cascade; make_page builds nothing when absent) |
| make_page options/steps/style, nav templates, stale texts, PURPLE, button style, action ids, notes markers | DNE; notes wording from the site (+ the page address on ALL, markers on the jump keys, one `MARKERS` constant); stale seconds editable; nav templates per version in `companion-objects/nav_templates/` (root file dropped) with the recapture recipe |
| HOLD_MS, GRID, STALE_SECONDS, NAV_LOCATIONS, EXPORT_VERSION/COMPANION_BUILD | `page_hold_ms` (read by the watchdog for "HOLD 2s"), `page_grid`, `page_stale_seconds`, `companion.export_version/build` (picks the nav template); NAV_LOCATIONS DNE (locked cells) |
| push_page/nav_keys --host defaults; "on NA Ingest" wording | read the config; site block (Phase 0) |
@@ -382,7 +382,7 @@ Every inventory item, and where the plan handles it or why it is deliberately no
|---|---|
| MacBook project folder, Gitea remote, checklist-ingest alias, memory files, gitea keychain item | DNE (dev side); scp staging (code only) + Export site bundle; `checklist-<id>` alias in the bootstrap list; no git credential on Ingest |
| NA Ingest LaunchAgent (exit timeout), staging folder, data dir, python3 3.9 (3.13 telnetlib risk), logs, auto-fix logs, state, dante-map, atem-reference.json, config backups, ssh sockets, MIDI streams, ATEM watcher, Art-Net listener, Bonjour, local CoreMIDI sessions, local probes, Spotify osascript, Companion db read | Ingest card lights incl. the python-version self-check, launchd agent state with the derived exit timeout and started.json (§B); Logs; History; Where things are; nothing copied to the staging folder by Apply |
| Companion app/version, custom variables, flash trigger, page 19, page 20, nav keys on 97 pages (gap at 96), quiet Tascam module, module folders, Companion Satellite, Stream Deck surfaces | Site setup > Companion (version, variables, pages exist / ours, page-number buttons "coloured on N of M" counted when the section is opened with the gap listed, module id per connection, version only if trivial); surfaces not shown; Satellite on the Ingest card (`watched:false`); Companion set-up by hand; `companion-objects/` for a new campus |
| Companion app/version, custom variables, flash trigger, page 19, page 20, nav keys on 97 pages (gap at 96), quiet Tascam module, module folders, Companion Satellite, Stream Deck surfaces | Site setup > Companion (version, variables, pages exist / ours, page-number buttons "coloured on N of M" counted when the section is opened with the gap listed, module id per connection, version only if trivial); surfaces not shown; Satellite on the Ingest card (`watched:false`); Companion set-up by hand; `companion-objects/` for a new location |
| every Companion connection (HyperDeck_1-6, tascam, x32, ATEM, dante, Axient_1/2, ULXD-4, PSM_1-3, ableton, Propresenter-API, BibleTV, lighting-midi, OBS-Youtube, arena, RESI_Decoder, resi-studio-cues, VX1000, UHDJr) and unwatched ones (Govee x7, DiGiCo_OSC, m32, AbleSet, tcp-HyperDeck-1..6) | Site setup > Companion live list with module id, watched-by, module-mismatch warning, "Add a key for it"; the HyperDeck job offers only bmd-hyperdeck connections; Open question Q4 |
| Resi bridge, lobby captions, caption screen, ProdCom (start method unknown), ProdDash, Spotify.app, ATEM Software Control + midiEnabled, DVS on Ingest, Church Translate disabled, Google Drive, free disk | Ingest `runs` (`disabled` kind for Translate; Drive folder probe via `atem.source_folder`) + INGEST key checks; bridge "never by itself"; captions fix with two helpers; dvs_ingest with prodcom rendered inline; prodcom/proddash without restart_ok unless ticked |
| other Ingest agents (checklist runner, backups, Itsycal, Alfred, Signiant) **and anything installed later** | Ingest `runs` with `watched:false`; the inventory probe lists every agent, login item and listening port under the collapsed "Everything found on this computer" list on the card, raw and unfiltered; no Add/Ignore, no counts on Overview |
@@ -417,4 +417,4 @@ Every inventory item, and where the plan handles it or why it is deliberately no
| service_windows + ALARMS, auto_fix window/list, poller periods, SSH identity/options, hosts table, Mac/Windows external setup, Public profile, Vista autoload, keychain, Spotify Automation, MIDI sessions local/remote, Ingest services, ATEM Software Control pref, hidden tiles, groups, restart keys, fix catalogue, network, alert_webhook, colours, cooldown/hold age, project folder, variables not persisted, full change sequence | covered by §A-§D; one schedule on the page; the one alarms sentence and the Silence alarms until midnight button (not guarded); the full change sequence collapses to: change -> Review & Apply -> done (refused while live with the draft kept; Emergency override), with the repo snapshot optional |
| History / Undo reachable from a clean state; pending work visible; vendor noise; two edit homes; four meanings of "key"; two meanings of "Settings" | History from Overview and its own menu entry, list and bodies open on the LAN; no pending work exists (a change refused while live stays a saved draft, said on Overview and in Review); raw inventory list on the card and no Overview count; fixes edited from the key, the catalogue under the "Set up once" divider; one owner screen per value with read-only links; editing code / login key / page-number buttons / connection; the page is "Status Panel", the section is "Site setup" |
| too many places; admin actions hidden under Help; three status vocabularies; contradictions about alarms; thresholds on main screens; hidden jobs; confusing tray; two watchdog homes; mixed confirmations; walkthrough behind the code | eight entries, the two set-up-once screens under a divider and readable by anyone; Help read-only, actions under Site setup > Site (Install the staged folder, Export site bundle); the one status legend printed once under the top bar's `?`; one alarms sentence; numbers under Advanced with defaults; three job buttons on Overview + More jobs; the labelled tray; watchdog buttons on Overview only; one confirmation style; the walkthrough needs no code because reads are open (the Training copy is deferred) |
| the user's four named asks: a new MIDI link (incl. a brand-new peer, or a Mac that is off), a different Spotify playlist (name follows everywhere), HyperDecks 2 and 4 only (both set to "must have a disk", generic TCP connections not offered), a new campus (own windows incl. overnight, own wording, reachable page before the LAN port is named, optional Restart page, optional ATEM) | the Overview jobs (first three, one click each) and the "New campus from this one" job (started from a site bundle you pick, exported from the source campus's page and copied over with the folder, or from any sites/<x>/ folder in the copied repo; `install.sh --site <id>` uses sites/<id>/ when present, else sites/_template/; D12) incl. bootstrap, the template's self record with `networks: []` and `companion-objects/` in the data dir; every copied value flagged "copied from <site> - check it" until touched |
| the user's four named asks: a new MIDI link (incl. a brand-new peer, or a Mac that is off), a different Spotify playlist (name follows everywhere), HyperDecks 2 and 4 only (both set to "must have a disk", generic TCP connections not offered), a new location (own windows incl. overnight, own wording, reachable page before the LAN port is named, optional Restart page, optional ATEM) | the Overview jobs (first three, one click each) and the "New location from this one" job (started from a site bundle you pick, exported from the source location's page and copied over with the folder, or from any sites/<x>/ folder in the copied repo; `install.sh --site <id>` uses sites/<id>/ when present, else sites/_template/; D12) incl. bootstrap, the template's self record with `networks: []` and `companion-objects/` in the data dir; every copied value flagged "copied from <site> - check it" until touched |
+18 -18
View File
@@ -1,12 +1,12 @@
# Status Panel settings page — the plan
One web page on the Ingest Mac that holds every setting the panel has, shows what runs on which computer, and works the same at every campus. Nobody edits `config.json` or a script by hand any more.
One web page on the Ingest Mac that holds every setting the panel has, shows what runs on which computer, and works the same at every location. Nobody edits `config.json` or a script by hand any more.
Companion files: [settings-plan-details.md](settings-plan-details.md) (every field, the data model, the apply pipeline, tests), [settings-plan-audit.md](settings-plan-audit.md) (how the plan was audited and what was cut), [settings-inventory.md](settings-inventory.md) (the 544 things the system has today, each with where it lives and how it is changed now).
## 1. What it is
The Status Panel is the Stream Deck page that is green when the room is fine and flashes red naming the problem. A watchdog program on the Ingest Mac runs it from one settings file. This plan adds a **settings page** on that same Mac, opened in any browser on the church network. Every setting is a labelled field with help: which computers exist and what runs on each, which keys are on the deck, what each key checks, what holding it does, when auto-fix may act, which Spotify playlist, switcher file, Dante devices, HyperDecks and MIDI links are in use. The page checks a change, shows in plain words what it will do, keeps a copy of every version, applies it safely, and the same page runs at every campus with that campus's own computers and gear.
The Status Panel is the Stream Deck page that is green when the room is fine and flashes red naming the problem. A watchdog program on the Ingest Mac runs it from one settings file. This plan adds a **settings page** on that same Mac, opened in any browser on the church network. Every setting is a labelled field with help: which computers exist and what runs on each, which keys are on the deck, what each key checks, what holding it does, when auto-fix may act, which Spotify playlist, switcher file, Dante devices, HyperDecks and MIDI links are in use. The page checks a change, shows in plain words what it will do, keeps a copy of every version, applies it safely, and the same page runs at every location with that location's own computers and gear.
Four words are used everywhere on it: a **key** (on the Stream Deck), a **computer** (anything we log in to, this Mac included), a **fix** (what holding a key runs) and a **connection** (Companion's link to one device: a HyperDeck, the Tascam, the switcher). The code you type to switch Editing on is the **editing code**. The file this Mac uses to log in to the other computers is the **login key**.
@@ -14,8 +14,8 @@ Four words are used everywhere on it: a **key** (on the Stream Deck), a **comput
- It runs on the Ingest Mac as a second background program beside the watchdog, installed by the same `install.sh`. Plain Python, nothing to install. It is a separate program so a bug in the page can never stop the panel, and the page keeps working while the watchdog restarts.
- Open **http://na-ingest.local:8020/** from any Mac, PC, iPad or phone on the church network. The address is printed on the cheat sheet and written into the ALL key's note in Companion, so anyone who finds the deck finds the page.
- **Anyone on the network can look** at everything: the deck, the computers, the logs, the history, the help. **Changing anything needs the editing code**: switch **Editing** on in the top bar, type the code once and your first name; the browser remembers both. The code is a setting in the campus's `config.json`, which lives in the private git repo, so everyone who has the repo has it; change it on Site setup › Site. The page never shows it to anyone who is not already editing. It is not a password for anything else. Five wrong tries lock the browser out for ten minutes.
- It edits the live settings file the watchdog reads (in `~/Library/Application Support/status-panel/`). From then on the Ingest Mac's copy is the truth for that campus; the git repo keeps a snapshot you export from the page.
- **Anyone on the network can look** at everything: the deck, the computers, the logs, the history, the help. **Changing anything needs the editing code**: switch **Editing** on in the top bar, type the code once and your first name; the browser remembers both. The code is a setting in the location's `config.json`, which lives in the private git repo, so everyone who has the repo has it; change it on Site setup › Site. The page never shows it to anyone who is not already editing. It is not a password for anything else. Five wrong tries lock the browser out for ten minutes.
- It edits the live settings file the watchdog reads (in `~/Library/Application Support/status-panel/`). From then on the Ingest Mac's copy is the truth for that location; the git repo keeps a snapshot you export from the page.
## 3. What you see
@@ -67,7 +67,7 @@ The first screen answers "is the room OK, and what do I do". In this order: the
### Keys
Two tabs, **Status page** and **Restart page**, each drawn as the 8×4 deck people hold. Every key is a chip you can drag to move, drag off the deck to hide, or click to edit. Column 0 (UP / page number / DOWN) is locked. ALL and ALARMS can be moved but not deleted; NET can be removed at a campus that does not want it. Keys with no spot of their own (AXIENT 1, AXIENT 2, ULXD, PSM 1–3) sit in a tray labelled "Shown inside the RF group (no key of their own)". Each tab header holds its page number; the Restart tab's also holds the switch "this campus has no Restart page". A yellow note says "Layout changed: Apply will re-import the Status page" when it will.
Two tabs, **Status page** and **Restart page**, each drawn as the 8×4 deck people hold. Every key is a chip you can drag to move, drag off the deck to hide, or click to edit. Column 0 (UP / page number / DOWN) is locked. ALL and ALARMS can be moved but not deleted; NET can be removed at a location that does not want it. Keys with no spot of their own (AXIENT 1, AXIENT 2, ULXD, PSM 1–3) sit in a tray labelled "Shown inside the RF group (no key of their own)". Each tab header holds its page number; the Restart tab's also holds the switch "this location has no Restart page". A yellow note says "Layout changed: Apply will re-import the Status page" when it will.
Click a key and its editor opens beside the grid. Two lines at the top answer the only two things a person needs to know: **WHAT THIS KEY WILL SAY** (every word the checks can put on it) and **HOLDING 2 s WILL:** ("switch HyperDeck_2's connection off and on, also when green"). Then only the fields that matter: the label, the group members (for a group key), the **checks** as a short list, and **When held** (which fix, and "also when the key is green"). "Add a check" asks a question first, not a type: *Is a device answering? Is a program running? Is a MIDI link up? Is a recorder OK? Is a setting right? Is Spotify playing? Is Dante complete? Is the lighting console sending?* You pick the computer or device from a live list (Companion's connections, the Dante devices, that Mac's MIDI sessions and peers, its programs) and the page builds the check. The raw check types and ids live under Advanced.
@@ -121,11 +121,11 @@ COMPUTERS - MAP [Check computers now] looked 2
Six sections, each opening on the few things a person changes:
- **Site:** site name, this Mac's name and addresses, contacts for the cheat sheet, the alert message hook. Advanced: page port, the login key (present / not, public half to copy), helper paths, the editing code, install the staged folder, export the site bundle.
- **Schedules:** when **auto-fix may act by itself** (Sunday 06:30–13:30 today) and the tick list of fixes it may run; alarms are always on. Changes to the panel wait while a HyperDeck is recording, not by the clock (a campus can add clock windows here too; NA has none). Advanced: the timing numbers (a fault must last 3 s, flapping, the 60 s cooldown, the 2 s hold).
- **Schedules:** when **auto-fix may act by itself** (Sunday 06:30–13:30 today) and the tick list of fixes it may run; alarms are always on. Changes to the panel wait while a HyperDeck is recording, not by the clock (a location can add clock windows here too; NA has none). Advanced: the timing numbers (a fault must last 3 s, flapping, the 60 s cooldown, the 2 s hold).
- **Companion:** the lights (variables exist, blink trigger, our pages exist, quiet Tascam module, ATEM module), the live list of connections with their module and which key watches each, "Add a key for it" for the ones nothing watches, the page-number buttons ("coloured on 96 of 97 pages" + Colour them now / Undo). Advanced: address, variable names, nav settings, grid, purple-after, export stamps.
- **Network & Dante:** the port and gateway the NET key watches, the Dante switches, and the **Dante device list** (the one place the DANTE key's devices are edited, with key text and per-device fix), "Check the Dante network now". Advanced: the blip rule, survey interval.
- **Spotify:** one field for the playlist (paste the link; name and song count fill in), the two waits, a light saying the watchdog may control Spotify.
- **ATEM:** the switcher address, the saved file (upload, or pick the newest from the Google Drive folder; you see what differs before it is applied), what to keep in line (audio, each camera setting), "Check the switcher now". A switch "this campus has no ATEM".
- **ATEM:** the switcher address, the saved file (upload, or pick the newest from the Google Drive folder; you see what differs before it is applied), what to keep in line (audio, each camera setting), "Check the switcher now". A switch "this location has no ATEM".
### Review & Apply
@@ -148,21 +148,21 @@ Grouped here; every single field is in [the details table](settings-plan-details
| Spotify | playlist, name, waits | Site setup → Spotify |
| ATEM | address, saved file, what to compare, node/library patterns | Site setup → ATEM |
| Site | name, this Mac's name/addresses, contacts, alert hook, port, helper paths, editing code | Site setup → Site |
| Not editable on purpose | colours, the words on keys, the 3 s/1 s/0 s debounce defaults, poll rates, the hold/ack mechanics, Companion's API paths, the shell commands the page builds — these are how the panel *works*, the same at every campus (guideline 1), and are listed in Help › Glossary and Where things are | Help |
| Not editable on purpose | colours, the words on keys, the 3 s/1 s/0 s debounce defaults, poll rates, the hold/ack mechanics, Companion's API paths, the shell commands the page builds — these are how the panel *works*, the same at every location (guideline 1), and are listed in Help › Glossary and Where things are | Help |
The four things you named, end to end: **A new MIDI link** = Add a MIDI link → pick the Mac → pick its session and peer from the live list (or type them if that Mac is off) → pick the key it goes on (MIDI if there is one, otherwise a new key) → it gains the check and the reconnect fix → Review & Apply. **A different playlist** = Change the playlist → paste the link → Apply (the key, the play fix and the key guide follow; only the watchdog restarts, and the key's note catches up at the next page re-import). **HyperDecks 2 and 4 only** = Add or remove a HyperDeck → untick 1, 3, 5, 6 → the HD keys and the REC group change (the emptied cells stay empty, or one click moves HD4 next to HD2), the page re-imports → Apply. **A new campus** = section 6.
The four things you named, end to end: **A new MIDI link** = Add a MIDI link → pick the Mac → pick its session and peer from the live list (or type them if that Mac is off) → pick the key it goes on (MIDI if there is one, otherwise a new key) → it gains the check and the reconnect fix → Review & Apply. **A different playlist** = Change the playlist → paste the link → Apply (the key, the play fix and the key guide follow; only the watchdog restarts, and the key's note catches up at the next page re-import). **HyperDecks 2 and 4 only** = Add or remove a HyperDeck → untick 1, 3, 5, 6 → the HD keys and the REC group change (the emptied cells stay empty, or one click moves HD4 next to HD2), the page re-imports → Apply. **A new location** = section 6.
## 5. Computers and what runs where
Each computer is a record the page owns: name, kind, how to log in, what runs there and whether the panel watches it. Today's eight are seeded from the inventory: NA Ingest (watchdog, settings page, Companion, Resi bridge, lobby captions and screen, ProdCom, ProdDash, Spotify, ATEM Software Control, DVS + helper, Google Drive for the switcher files, plus the other background tasks that are not the panel's), ProPresenter Mac, Tracks Mac, NA Translation, Studio B Mac Studio (the solo-mode helper, Accessibility), Lighting PC (Vista, Arena, rtpMIDI task + service, firewall, Public profile), LiveStream PC (OBS task with admin rights, wake-on-LAN), Bible TV PC (Bible app at logon, Wi-Fi power settings). The live look runs a fixed set of read-only commands on each computer (what launchd has loaded, which tasks and services exist, which programs run, is the login key accepted, is the helper installed), never during a fix, never waking a PC, with every name quoted so a typed name can never run as a command. The devices that are not computers are listed from the checks that watch them, with a note per device for where it lives.
The Setup tab generates each computer's one-time script (the Mac authorise script, the DVS helper, the Windows setup, the Studio B solo-mode agent) with that campus's key and addresses filled in. You still run them yourself (section 12); the page shows which lines are done.
The Setup tab generates each computer's one-time script (the Mac authorise script, the DVS helper, the Windows setup, the Studio B solo-mode agent) with that location's key and addresses filled in. You still run them yourself (section 12); the page shows which lines are done.
## 6. The other campuses
## 6. The other locations
Apollo Beach, Woonsocket and Southcoast each already have a Mac Studio running Companion; the page and the watchdog go on that Mac. One settings file per campus = one site block plus that campus's computers, keys, checks, fixes, windows and gear. The code never contains a site name, an address, a label, a playlist, a path or a day name; everything site-shaped is data. Differences between campuses are plain differences in that data: fewer HD keys, no Studio B, another playlist, other Dante names, an extra PC, other page numbers, a Saturday evening service that runs past midnight.
Apollo Beach, Woonsocket and Southcoast each already have a Mac Studio running Companion; the page and the watchdog go on that Mac. One settings file per location = one site block plus that location's computers, keys, checks, fixes, windows and gear. The code never contains a site name, an address, a label, a playlist, a path or a day name; everything site-shaped is data. Differences between locations are plain differences in that data: fewer HD keys, no Studio B, another playlist, other Dante names, an extra PC, other page numbers, a Saturday evening service that runs past midnight.
Setting up a new campus: install Companion and the command-line tools on its Ingest Mac, copy the folder over, run `install.sh --site <name>` once (it uses the repo's `sites/<name>/` if there is one, otherwise the empty template), do the Companion one-time steps (section 12). Then on the page: **New campus from this one** starts from a site bundle (export NA's from its page and copy it over with the folder, or pick any `sites/` folder in the copied repo) and walks you through it — keep, rename or drop each computer (dropping one drops every key, check and fix that used it and lists them), map the connection labels, Dante devices and MIDI sessions from that Companion's live lists, set the playlist, switcher, network and schedule, Review & Apply. Everything copied from NA is flagged "copied from North Attleboro — check it" until touched. The repo keeps one folder per site (`sites/na/`, `sites/<new>/`); the page's **Export site bundle** gives you the zip to drop in.
Setting up a new location: install Companion and the command-line tools on its Ingest Mac, copy the folder over, run `install.sh --site <name>` once (it uses the repo's `sites/<name>/` if there is one, otherwise the empty template), do the Companion one-time steps (section 12). Then on the page: **New location from this one** starts from a site bundle (export NA's from its page and copy it over with the folder, or pick any `sites/` folder in the copied repo) and walks you through it — keep, rename or drop each computer (dropping one drops every key, check and fix that used it and lists them), map the connection labels, Dante devices and MIDI sessions from that Companion's live lists, set the playlist, switcher, network and schedule, Review & Apply. Everything copied from NA is flagged "copied from North Attleboro — check it" until touched. The repo keeps one folder per site (`sites/na/`, `sites/<new>/`); the page's **Export site bundle** gives you the zip to drop in.
## 7. Saving a change
@@ -170,7 +170,7 @@ Setting up a new campus: install Companion and the command-line tools on its Ing
2. **Check.** On every change and again at Apply: the rules (ids, positions, windows, addresses, every fix's computer exists…), the watchdog's own loader on a temporary copy, a build of both pages in memory, and live warnings (a connection label not in Companion, a computer unreachable, a private playlist).
3. **Review.** The plain change list, warnings, anything built as a command in red, what Apply will do.
4. **Apply**, each step only after the previous one worked: keep a copy of the current version in History → write the new file in one go (and the new switcher file with it, if there is one) → wait for any fix that is running to finish → restart the watchdog (a change to key notes alone skips this) → **prove it came back** (its start stamp with the new file's fingerprint, no error, still alive after 10 s) → only then re-import the pages if the layout changed (key notes alone never trigger a re-import; the page refuses to overwrite a key someone added by hand in Companion and names its position) → recolour the page-number buttons if pages changed → rebuild "What each key does". If the watchdog does not come back, the previous version (and switcher file) is restored automatically, once, and Overview shows a red note until the next good Apply.
5. **While a HyperDeck is recording** (that is what "live" means at NA; a campus may add clock windows) Apply is refused with the reason and when it ends; the draft stays saved. The same goes for Run this fix now, Restart the watchdog, re-imports, the switcher check and program installs. An **Emergency** button states the consequence, asks you to type LIVE and a reason, and is logged. Starting a watchdog that is down is always allowed. Silencing alarms is never blocked.
5. **While a HyperDeck is recording** (that is what "live" means at NA; a location may add clock windows) Apply is refused with the reason and when it ends; the draft stays saved. The same goes for Run this fix now, Restart the watchdog, re-imports, the switcher check and program installs. An **Emergency** button states the consequence, asks you to type LIVE and a reason, and is logged. Starting a watchdog that is down is always allowed. Silencing alarms is never blocked.
6. **Going back** = History → Go back to this (or Undo the last change) through the same steps.
## 8. Safety
@@ -192,7 +192,7 @@ Help › four cards, then **What each key does** (regenerated on every Apply, so
- `schema.py`: the registry of every setting (type, default, range, help, example, which screen owns it, advanced or not). Tests keep it honest: every key the watchdog reads must be declared; every default in code must equal the schema's; every word a key can show must be in the glossary; today's config must still build today's pages exactly (apart from the key notes, which gain the page address and the markers); every one of today's 27 fixes must regenerate from its builder exactly.
- `settings/`: the server (routes for the draft, validate, apply, history, live lists, logs, probes), the probes, the apply pipeline, the script generator, the key-guide generator, and one HTML/JS page with no framework.
- Watchdog changes are additive: a start stamp, a restart that finishes the running fix, remembered acknowledgements, a "run this fix" verb, new settings read with today's values as defaults, Windows program checks that actually work (cmd.exe needs `&& echo` pairs, not `%ERRORLEVEL%`).
- `install.sh` validates the settings with the new code before touching anything, keeps the previous code for rollback, installs both programs, and never overwrites the campus's own files once the page exists.
- `install.sh` validates the settings with the new code before touching anything, keeps the previous code for rollback, installs both programs, and never overwrites the location's own files once the page exists.
- Full detail: [settings-plan-details.md](settings-plan-details.md).
## 11. Build order
@@ -207,14 +207,14 @@ Each step is deployed on its own, outside a service, with tests green, a live ch
| 3 Layout | Drag keys, add/delete keys, the Restart page, page numbers; Apply re-imports pages and recolours page-number buttons. | Move LED, add HD7, delete HD5, Apply, watch the deck change. | 2 days |
| 4 Jobs | Change the playlist, Add or remove a HyperDeck, Add a MIDI link, Add a computer, Make a PC program startable; "Add a key for it" on unwatched connections. | Untick HD1/3/5/6 and run on 2 and 4; add a MIDI link to a Mac that is off. | 2.5 days |
| 5 Setup + teaching | The Setup tab with lights and generated scripts, Where things are, Things only a person can do, Install the staged folder from the page. | Add a new PC, generate its script, run it, paste the result, watch the lights go green. | 2 days |
| 6 Other campuses | Site folders, the template, the bundle export, New campus from this one. | Build a demo campus on the MacBook with a Saturday night service and no OBS. | 1.5 days |
| 6 Other locations | Site folders, the template, the bundle export, New location from this one. | Build a demo location on the MacBook with a Saturday night service and no OBS. | 1.5 days |
Later, if wanted: a Training copy of the page where nothing is real; an "OBS is streaming" live signal (if the experiment in step 1 finds the variable).
## 12. What you still do by hand
- **A new Ingest Mac:** install Companion, `xcode-select --install`, Remote Login on, copy the folder over, run `install.sh --site <name>` once.
- **Companion, per campus:** create the custom variables `sp_state`, `sp_hb`, `sp_cmd`, `flash_tick` and the blink trigger (the page gives you the file to import, or a button if step 1 proves it safe); add pages up to the Status and Restart numbers; install the ATEM module; import the quiet Tascam module where there is a DA-6400; name the Stream Decks. Why: Companion only allows these in its own UI; a full import would wipe the variables.
- **Companion, per location:** create the custom variables `sp_state`, `sp_hb`, `sp_cmd`, `flash_tick` and the blink trigger (the page gives you the file to import, or a button if step 1 proves it safe); add pages up to the Status and Restart numbers; install the ATEM module; import the quiet Tascam module where there is a DA-6400; name the Stream Decks. Why: Companion only allows these in its own UI; a full import would wipe the variables.
- **Every other Mac:** Remote Login on; paste the generated authorise script (and the DVS helper where DVS runs) via ARD "Send UNIX Command as root"; make the Audio MIDI Setup sessions the page names; on Studio B run the generated solo-mode install and allow Accessibility on that screen. Why: root rights and permission prompts must come from a person at that Mac.
- **Every Windows PC:** run the generated setup script as administrator, paste its RESULT block into the page; BIOS wake-on-LAN; keep the Lighting PC on Public; Vista autoload; the Bible TV Wi-Fi power settings (or Ethernet). Why: system and firewall changes need your OK; BIOS has no remote path.
- **Ingest Mac:** type the Netgear login into the keychain yourself (the page shows the line); click Allow once on the Spotify prompt; keep Google Drive signed in for the switcher files.
@@ -225,7 +225,7 @@ Later, if wanted: a Training copy of the page where nothing is real; an "OBS is
1. **Who can edit:** the editing code lives in `config.json` in the private repo, so everyone with the repo has it (answered 2026-10-13).
2. **When changes must wait:** only while a HyperDeck is recording (answered 2026-10-13). No clock windows at NA; the Sunday 6:30–13:30 window is for auto-fix only.
3. **The other campuses:** Apollo Beach, Woonsocket and Southcoast, each with a Mac Studio already running Companion (answered 2026-10-13).
3. **The other locations:** Apollo Beach, Woonsocket and Southcoast, each with a Mac Studio already running Companion (answered 2026-10-13).
4. **Unwatched Companion connections** (7 Govee lights, DiGiCo_OSC, m32, AbleSet, tcp-HyperDeck-1..6): stay unwatched (answered 2026-10-13).
## 14. How this plan was audited