# REPORT — 2026-10-12 (night): the two download clients published, and the website follows them Operator's asks, in order: a torrent client ("no question about it"), Transmission beside it, then "proceed with the publication steps/tests". All three are done. The Usenet pair he asked for after that is filed as **R-988** and not started. ## What shipped - **`app-catalog-felhom.eu` `9081a47`** — `templates/qbittorrent/` and `templates/transmission/` with `onboarding/qbittorrent.md` and `onboarding/transmission.md` in ONE commit, plus the README tables, two `FIRST-ADMIN.md` class-1 rows and the fixtures for both venues. Then `cb4ecec` — two `REUSE.md` rows the build earned. - **This repo** — the two app cards (both language sets) with the projects' own logos, the published count 58 → 60 on every page that states it, `documentation/audits/qbittorrent-2026-10-12/` (the whole campaign), and a fix to the 2026-09-30 walk harness: a `type: path` deploy field is filled with the drive ROOT, because the controller refuses a path inside a drive (409) and the walker therefore could not install any app with a drive field. ## What was measured, and in which venue Bench LXC 9401 on demo-hp (twelve questions per app: image, telemetry, entrypoint, first admin, storage, ownership, health, memory, a real download, the config as the app rewrote it) and scratch guest 9202 **through the product** (deploy from the drill catalog, stranger and household through traefik on the app's own public name, the guarded Update with its per-app backup, both remove choices). Six defects came out of it, every one from a measurement and every one fixed before publication; they are listed with their numbers in the catalog CHANGELOG and in the audit README. The one that reads as a lesson rather than a bug: **a value seeded into a config file the app owns is only a request** — qBittorrent ignores a seeded UPnP flag at first start and rewrites a semicolon host list down to a single entry, after which the controller's own health probe is refused. Both settings now go through the app's API in `after_install`, whose marker depends on the **readback**, not on the call's status. **An apparent household lock-out was my measurement, not the app.** Six wrong passwords and the household's own request came from one machine. Re-measured from two addresses: qBittorrent bans the address that sent the wrong tries (403) while the household signs in at the same instant (204); Transmission does not ban at all. **The operator's UPnP question, answered by measurement:** with port mapping off and neither peer port published, each client completed a 276 MB torrent through its own interface. Peer traffic leaves through the household's router by NAT; the tunnel only carries the app's web page inbound. What a closed port costs is incoming peers, and both app pages say so. ## Gates - `catalog_gates.py qbittorrent transmission` — 12 of 14 OK. `image-resolvable` INCONCLUSIVE and `volume-persistence` DID-NOT-RUN: the two documented periodic ones, which need network and a container runtime (the Windows workstation has neither, and the harness refuses a host that is not a scratch host). Both were covered on the bench during the campaign — the ladder writer resolved and recorded both digests, and each app's storage layout was measured by hand there. - `catalog_gates.py --fast` (whole catalog) — all OK. - `repo_gates.py --fast` here — `instructions` and `script-tests` FAILED and `wire-contract` INCONCLUSIVE, **all three pre-existing and none of them about this work**: the instructions gate reports the deliberate divergence between `E:\git\CLAUDE.md` (the Windows-adapted copy, whose own header says not to converge them) and the versioned DooPlex one, plus five component-version literals in `app-catalog-felhom.eu/CLAUDE.md`; the script-tests failures are Windows-shaped (`os.symlink` needs a privilege this account lacks, no `sqlite3` CLI, bash-only suites). The authority for these is CI on the DooPlex-shaped runner, which re-runs the same entry point on this push. ## Teardown — three layers, verified, with the control from a different channel - **Machine (9202):** both apps removed **through the product**, `deployed: false`, both config volumes gone, no container left, the two download folders deleted from the scratch drive. The guest's standing apps are untouched. `box/teardown-newapps.json`. - **Catalog pointer:** restored from this run's own saved copy with the cache removed (R-615), and proven **not** by the controller's „nincs változás" but by sha256: `qbittorrent`, `transmission` and `grocy`'s `.felhom.yml` on the box equal the same files at the published `origin/main`, with a decoy pair that must differ and does. The config names the drill repo zero times. - **Host (demo-hp):** bench 9401 has no containers and no volumes and is stopped, as found. The drill catalog is reset to live `main`; the DooPlex clone is clean at the published commit. - **Hub:** nothing to undo — 9202 reports to no hub by its own configuration. ## Register Rows before 116, after 117, opened 1 (**R-988**, the Usenet pair), closed 0. Fixed without a row: the six defects above and the walk harness's drive-path filling. `unproven.py --summary` was not re-run — nothing in this work changes a capability claim's status.