# AUDIT — can this check be fooled by a label? The decoy sweep (2026-09-01, R-421) **Question asked of every gate:** *could I satisfy this with a convincing label instead of the real thing?* Answered by construction — a decoy is written, the gate is run, and the verdict recorded. **No row's last column was answered from reading.** ## The survey **29 distinct scripts, 35 registrations** (`reuse-refs`, `instructions`, `observations` are one script each, registered in three runners). This matches the task's count of 29. | gate | runner(s) | meant to prove | actually matches | shape | decoy passed **before**? | |---|---|---|---|---|---| | emoji | ctrl | no emoji in UI copy | codepoints, in `listdir` scope | 1 | **YES** | | native-confirm | ctrl | no OS-modal dialogs | JS call regex, `listdir` scope | 1 | **YES** | | app-row-dedup | ctrl | one row markup | regex + `'…' not in src`, `listdir` | 1, 2 | **YES** (×2) | | template-id | ctrl | JS ids resolve | id sets, `listdir` scope | 1 | **YES** | | secret-markup | ctrl | no secret in markup | template actions, `listdir` | 1 | **YES** | | retrieval-promise | ctrl | promises are registered | stems, `listdir` scope | 1 | **YES** | | hub-confirm | eu | no OS-modal dialogs | JS call regex, `listdir` scope | 1 | **YES** | | manifest-bearer | eu | no bearer literals | 64-hex regex, `listdir` scope | 1 | **YES** | | observations | eu, ctrl, agent | a finding is filed | `FILED:` anywhere in the body | 2 | **YES** (R-419) | | debug-routes | ctrl | controls resolve | raw text, comments included | 2, 3 | **YES** | | closed-register | eu | closed rows are closed | verdict cell — **but skipped unparseable rows** | 2 | **YES** | | site | eu | pages are well-formed | a 7-entry `PAGES` list | 1 | **YES → R-423** | | one-register | eu | open work is registered | the state cell; `idea` escapes | 2 | **YES → R-424** | | offbox-rename | ctrl | branding is retired | a fixed 3-entry `FILES` list | 1 | **YES → R-425** | | reuse-refs | eu, ctrl, agent | citations resolve | paths — only 7 extensions | 1 | **YES → R-422** | | mojibake | ctrl | no double-encoded UTF-8 | bytes, via `os.walk` | 5 | NO — **control** | | docker-v | ctrl | `-v` mounts are safe | argv, via `os.walk` | 5 | NO | | image-pins | catalog | no floating tags | real `image:` refs | 5 | NO | | golden-currency | eu | a golden was baked | `GOLDEN_SHA256` in the bake log | 5 | NO (R-410 fixed) | | golden-notice | ctrl | ditto, other direction | imports the gate above | 5 | NO | | instructions | eu, ctrl, agent | instruction files stay sane | effective text | 5 | NO | | hub-copy | eu | retired names are gone | `os.walk` over hub/internal | 5 | NO | | release-complete | agent | a release is complete | git tag + ancestry + HTTP HEAD | 5 | NO | | hostinstall | eu | installer invariants | — | ? | **UNKNOWN** | | wire-contract | eu | emitted fields decode | — | ? | **UNKNOWN** | | due-checks | eu | dated checks fire | — | ? | **UNKNOWN** | | published | agent | versions are published | — | ? | **UNKNOWN** | | image-resolvable | catalog | images exist | `docker manifest inspect` | 5 | **UNKNOWN** | | volume-persistence | catalog | data survives | runs containers, diffs | 5 | **UNKNOWN** | **19 sound · 4 holes left open with rows · 6 unknown.** Ten holes were fixed in this session. ## The one cause behind eight of them Eight gates decided their **scope** with `os.listdir`, one directory level. No template or manifest subdirectory exists today, so every one was green **and correct** — and would have stayed green the moment anyone added `templates/partials/`, which is an ordinary act. `mojibake` and `docker-v` already used `os.walk`, caught the identical planted file, and are the **control that proves the cause was the listing and not the decoy.** ## Holes left open, with rows | row | gate | why not fixed here | |---|---|---| | **R-422** | reuse-refs | `PATH_RE` matches 7 extensions; a rotted `.md` citation is invisible. Widening it needs a false-positive pass over 4 repos. | | **R-423** | site | `PAGES` is a hardcoded list of 7. Fix is to glob `website/*.html`, which needs the per-page exemptions rethought. | | **R-424** | one-register | a defect parked under state `idea` escapes. Declared in the gate's own docstring as residual hole 1. | | **R-425** | offbox-rename | fixed 3-entry `FILES` list; a new offbox file is unscanned. | | **R-426** | — | owns the meta-gate's 20-name exemption list. | Each is asserted **as it behaves today** where a test could hold it, so the day it is fixed the assertion fails and is updated deliberately. A hole nothing asserts is a hole nobody remembers. ## Decoys withdrawn as illegitimate — mine, and named §2.1 sets the standard: a decoy nobody would write proves nothing. These were withdrawn rather than counted, because counting them would have manufactured findings. 1. **image-pins / `x-image: nginx:latest`** — `x-` fields are inert in Compose. The label had no fact behind it *either way*. Replaced with a positive control (a real untagged `image:` line → convicted). 2. **release-complete / a non-version heading on top of CHANGELOG.md** — `HEAD_RE.search` scans the whole file, so the real release is still found and named `v0.130.0`. The gate is sound. 3. **app-row-dedup / one commented-out partial call** — `dashboard.html` has **two**; replacing one left the other live. The gate was right and my decoy was half-built. 4. **one-register / a 3-column decoy row** — it convicted for a *structural* reason, not the one under test. Rebuilt at the real 5-column shape, and the hole then reproduced. 5. **template-id, secret-markup, retrieval-promise, hub-copy / wrong content** — my first planted files carried nothing those gates hunt for, so "passed" meant nothing. Rebuilt with real triggers.