--- name: stale-signal-and-hollow-gate-audit description: "Audit a repo for signals that cannot be correct — vacuous test assertions after a file is retired, permanently-red health probes, and prose claims invalidated by your own changes; includes the linter-validation-before-acting discipline and Obsidian link-resolution rules." --- # Stale-signal and hollow-gate audit Use when you want assurance rather than a feature: "is anything in this repo quietly lying?" The productive question is **which signal here cannot possibly be correct?** Every pass on serverAppConfig (2026-09-16) found real defects this way — including one in the rule file agents read first. ## 1. Vacuous assertions (highest severity — the gate is already dead) A seam that greps a file passes *by absence* once the file is retired, because `grep` exits 2 on a missing path and `!` inverts it. ```bash # Find assertions anchored on files that may not exist grep -rn 'grep.*"\$REPO_ROOT/[^"]*"' tests/*.bats | head -50 [ -f "$path" ] || echo "MISSING: a seam may be grepping this" ``` Fix shape — one place asserts the invariant, each local site keeps a live check: ```bats @test "no compose file competes with the quadlet units" { local cf="$REPO_ROOT//compose.yaml" [ ! -f "$cf" ] || { echo "$cf is back: every container is unit-managed"; return 1; } } # at the per-service site: still fails if the entry returns local cf="$REPO_ROOT//compose.yaml" [ ! -f "$cf" ] || ! grep -qE '^\s+:' "$cf" ``` **Always teeth-test**: recreate the offending file (`printf 'services:\n :\n image: x\n' > `), run the seams, confirm they go RED, then move the file to trash. A re-armed check that was never seen failing is still unverified. ## 2. Permanently-red probes For each monitored target ask: *can this probe succeed from the monitor's vantage point?* Failure classes seen: container-internal ports probed from another host (`192.168.0.235:3306`, `127.0.0.1:6379` on a published-port-only netavark host), and "probe" jobs that scrape `/` (HTML → `unsupported Content-Type`) or a `/metrics` that is disabled (Gitea 404). - A card/job that can never be up must be **fixed or explicitly marked not-probed** (`wip: true` on homepage cards) — never left red. - The right probe for "is this HTTP service answering?" is the **blackbox exporter** (`/probe?target=…&module=…`), which also gives guarded vhosts a real uptime signal since Prometheus cannot solve an Anubis challenge. - Cheap check on a homepage board: read the deployed `status.json` and triage every `state != up` entry against reality (container running? port published?). ## 3. Prose claims invalidated by your own change After retiring a file or adding a feature, grep for **every** reference, not just code: ```bash grep -rn "" --include="*" . | grep -v '^./.git/' grep -rn "no \|none —\|unconfigured" --include="*.md" --include="*.container" --include="*.yml" . ``` This is what catches the ones that bite: a rule file (AGENTS.md) told agents ComfyUI runs CPU-only long after it was restored with GPU access; a unit said "there are no alerting rules" hours after five were added; a docs page documented three scrape jobs as working when they could never report up. **Clean cutover includes prose.** ## 4. Validate the linter before acting on it A checker's output is a hypothesis about another tool's semantics. Modelling Obsidian with naive text matching produced 45 "broken links" of which 3 were real — the rest were case-sensitivity (`[[qBittorrent]]` → `qbittorrent.md`), path-qualified resolution (`[[folder/Note]]` resolves by path suffix, not stem), and `%20` URL-encoding in markdown links. Fix the checker first; re-derive the report; only then edit documents. In this repo the result lives in `scripts/check-vault-links.py` with those three rules in its docstring, gated by the `no unresolved links in the docs vault` seam. ## Reporting shape Report per finding: the surface, why the signal *could not* have been correct, the fix, and how you proved the fix has teeth (red/green evidence). Flag any regression you introduced yourself in the same breath — one was found this way (a tightened bind killed a reverse-proxied vhost while every gate stayed green, because the spec covering that hostname did not exist).