# CLAUDE.md ## What this is **AVWatch** is a Python CLI that monitors firmware/software updates across the Waters Church live-production AV fleet. For each item it answers *"a new version exists, is it safe to install or should we wait?"* and makes a **Go / Wait / Avoid** call. It does this by finding the current release, searching Reddit, GitHub and the web for people reporting breakage, and applying a conservative soak policy. The design principle: **a dead device on Sunday morning costs far more than running one release behind.** The update has to prove it is safe, and waiting is the default. It also never guesses a version it can't verify. Anything it can't verify goes to a "check by hand" list rather than getting an invented answer. README.md is the full user guide. This file is orientation for working on the code. ## Layout | Path | Purpose | |---|---| | `avwatch/cli.py` | Entry point. Commands: `doctor`, `list`, `scan`, `digest`, `report`, `set-installed`, `mark`, `history`, `test-email`, `worksheet` | | `avwatch/config.py` | Loads `config.toml`. All secrets are read from env vars here, **never** from the file | | `avwatch/inventory.py`, `models.py` | Loads/merges `inventory*.yaml`; item model | | `avwatch/coupling.py` | Version-coupling graph (`must_match`, `must_be_at_least`, `host_of`, …); mirrors edges, detects live mismatches | | `avwatch/scanner.py`, `versions.py` | Orchestrates lookups; version comparison | | `avwatch/sources/` | Version sources: `blackmagic` (support JSON), `github_releases`, `generic` (HTML regex), `websearch` (Claude + web search, must cite a source) | | `avwatch/risk/` | `collectors` (Reddit/GitHub/DDG evidence), `heuristics` (rule-based score), `llm` (Claude verdict), `classify` | | `avwatch/report/` | HTML dashboard + email digest (`templates/*.jinja`) | | `avwatch/store.py` | SQLite state in `data/avwatch.sqlite3` (versions seen, verdicts, `mark` decision history) | | `avwatch/http.py` | Cached HTTP client (`data/cache/`) | | `scripts/` | `install_tasks.ps1` (Task Scheduler: scans Tue/Thu/Sat 06:00, digest Mon 07:00), `run_avwatch.ps1`, `set_api_key.ps1` | | `tests/` | `test_core.py`, `test_coupling.py` (unittest) | ## Commands ```bash python -m pip install -r requirements.txt python -m unittest discover -s tests # 65 tests, all passing as of 2026-09-24 python -m avwatch doctor --network python -m avwatch scan --no-llm # no API spend ``` ## Secrets and config - Credentials come **only** from env vars: `ANTHROPIC_API_KEY`, `AVWATCH_SMTP_PASSWORD`, `AVWATCH_GITHUB_TOKEN`, `AVWATCH_REDDIT_CLIENT_ID`, `AVWATCH_REDDIT_CLIENT_SECRET`. Keep it that way. Don't add a secret field that gets read from `config.toml`. - `config.toml` is gitignored because it can hold recipient addresses and usernames. `config.example.toml` is the committed template. - `data/`, `reports/` and `logs/` are runtime output and gitignored. This means **the SQLite decision history is not in git.** Back it up separately if it matters. - Community post text is untrusted input to the LLM. Keep the prompt-injection guarding in `risk/llm.py` intact. ## Where it stands (2026-09-24) - v1.0.0. Core pipeline, coupling checks, dashboard, email digest and scheduled tasks are built. Reports from 2026-09-08 and 2026-09-09 show real runs. - `inventory.yaml` has **88 items, but only 3 have `installed:` filled in.** Until more do, AVWatch can report "a newer version exists" but not "you are behind", and coupling mismatches can't be checked. - The README describes `inventory-expansion.yaml` (116 items) and `inventory-optional.yaml` (57 items), but **neither file exists in this folder.** Either they were deleted (the README says that's supported) or they were never saved. The README counts (259 total, 130 unconfirmed, cost estimates) are out of date until this is sorted out. - The five `VERIFY` entries the README lists (DQ Rack, Quantum 225, DBOX+, AJA, Netgear Dante switch) no longer carry a `VERIFY` marker in `inventory.yaml`. Check whether they were resolved or just lost the marker. ## Next steps 1. Record installed versions with `python -m avwatch worksheet` and `set-installed`, starting with the coupled clusters (ATEM trio, Shure RF, DiGiCo pair, Netgear Dante switch). 2. Resolve the missing expansion/optional inventory files, then update the README counts. 3. Set `AVWATCH_REDDIT_CLIENT_ID`/`SECRET` (the best evidence source) and `AVWATCH_GITHUB_TOKEN`. 4. Confirm the scheduled tasks are registered and the Monday digest mails correctly (`python -m avwatch digest --dry-run`). 5. Decide whether `data/avwatch.sqlite3` needs a backup. ## Repository Backed up to Gitea: `http://10.3.8.90:3000/chris/AV-Watch` (private, branch `main`). Git credentials are in Windows Credential Manager, not in this repo.