Pulling at session start and the commit/push reminder now run as hooks in Desktop\Claude\.claude (outside the repo). Claude only does them by hand in sessions opened elsewhere.
5.8 KiB
CLAUDE.md
Every session: stay in sync with Gitea
This repo is backed up to http://10.3.8.90:3000/chris/AV-Watch (private, branch
main). The Git login is in Windows Credential Manager, not in this repo.
For sessions opened in C:\Users\Live Stream\Desktop\Claude, hooks do the syncing
(.claude\settings.json and .claude\hooks\avwatch-sync.ps1 in that folder,
outside this repo):
- At session start a hook runs
git pull --ff-onlyand adds the result to your context as "AVWatch SessionStart hook: ...". Don't pull again. If it says the pull was skipped, mention that in your first reply, and don't stash, reset, rebase or merge to get past it unless asked. - After each reply a hook shows the user a one-line note while anything is uncommitted or unpushed, so don't add a reminder of your own. Only commit or push when asked.
In a session opened anywhere else the hooks don't run, so do both by hand: pull before the first request, and end any reply that leaves work uncommitted or unpushed with a one-line reminder and an offer to commit and push.
# 'never' makes a bad token fail fast instead of opening a login window
$env:GCM_INTERACTIVE = 'never'; git pull --ff-only
If git isn't found, use C:\Program Files\Git\cmd\git.exe.
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
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 fromconfig.toml. config.tomlis gitignored because it can hold recipient addresses and usernames.config.example.tomlis the committed template.data/,reports/andlogs/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.pyintact.
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.yamlhas 88 items, but only 3 haveinstalled: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) andinventory-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
VERIFYentries the README lists (DQ Rack, Quantum 225, DBOX+, AJA, Netgear Dante switch) no longer carry aVERIFYmarker ininventory.yaml. Check whether they were resolved or just lost the marker.
Next steps
- Record installed versions with
python -m avwatch worksheetandset-installed, starting with the coupled clusters (ATEM trio, Shure RF, DiGiCo pair, Netgear Dante switch). - Resolve the missing expansion/optional inventory files, then update the README counts.
- Set
AVWATCH_REDDIT_CLIENT_ID/SECRET(the best evidence source) andAVWATCH_GITHUB_TOKEN. - Confirm the scheduled tasks are registered and the Monday digest mails correctly
(
python -m avwatch digest --dry-run). - Decide whether
data/avwatch.sqlite3needs a backup.