FileBrowser never on its default password (D11 = A), real memory amounts (D10 = A), CI mail: report, register, docs
gates / gates (push) Successful in 6m53s

Closed R-1126, R-1125 and R-1129 (not a defect: a misreading of the CI log by the session that filed it); opened
R-1135..R-1137; R-1124 noted. 01 §5 [DESIGN]: the tunnel runs before the claim; FileBrowser is published only after
its default login is checked. STATUS D10-D12 decided. N100 diary: the 21-minute file-manager gap after 0.327.0.
Controller 0.327.1 is the floor since 12:06 UTC.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
admin committed 2026-10-17 14:12:02 +02:00
1 parent 30b231f447
commit f6511dc5c2
37 files changed
+1435 -11

No files matched your search

+8
View File
@@ -26,6 +26,14 @@
---
## 2026-10-17 — FileBrowser never on its default password, real memory amounts, CI mail (controller v0.327.1, catalog `1af6ea7`)
| Row | What | Closed | Evidence |
|---|---|---|---|
| **R-1125** | **23 apps' `mem_request` is below their measured typical use (R-994's second half), and the requests feed the box's install check** (P3) | CLOSED 2026-10-17 — operator decision D10 = A. Catalog `1af6ea7`: 23 `mem_request` = measured use. Read first on every box the hub knows (4, no customer): none over. **controller v0.327.0**: the refusal and the install page's memory box say the memory is held by the installed apps and to remove one or use a machine with more memory (HU/EN; 2 fixtures re-captured as `*_r1125`); the page now shows the check's own reading (`stacks.InstallMemory` — it used `/proc`'s host-wide figures). Live: an install that fits accepted on 9201; on 9202 made nearly full, refused (400) in both languages and blocked on the page with the same numbers (2,798 vs 2,698), nothing installed. No page promises the household set fits 8 GB (grep). | `audits/filebrowser-memory-ci-2026-10-17/` |
| **R-1126** | **The Cloudflare tunnel runs before the box is claimed, and no document says whether that is intended.** (P3) | CLOSED 2026-10-17 — operator decision D11 = A. **controller v0.327.1**: FileBrowser starts off `traefik-public` (own network `felhom-filebrowser`); the box checks this run's default login, then joins it to `traefik-public` by container ID; `files.<domain>` is a file route to `filebrowser:80` by name (v0.327.0 used Docker labels and timed out on demo-hp and the N100 — Traefik kept the start-time address; fixed in 0.327.1 within 25 minutes). Spike first: FileBrowser's own admin-password setting re-applies at every start (1.5.6 `cmd/user.go:50-57`, measured on 9202: the household's own password was overwritten) → not usable. Live on 9202: FileBrowser + data removed, 140 probes from outside, default login never 200 (502 until published). Box walk on all three: `files.<domain>` 200, default 401. Tunnel unchanged, by design: `01` §5 [DESIGN] paragraph. | `audits/filebrowser-memory-ci-2026-10-17/` |
| **R-1129** | **CI's failure mail has never been sent: every failed gate run ends „ALARM FAILED: RESEND_API_KEY is empty”, so the safety net four CLAUDE.md files promise („CI re-runs the entry point on every push and emails on failure”, R-168) does not exist.** (P2) | CLOSED 2026-10-17 — **NOT A DEFECT: misdiagnosed by the session that filed it.** The „ALARM FAILED: RESEND_API_KEY is empty” lines are the CI runner printing the alarm step's own source before it runs; every cited job's real output was `RESEND-ACCEPTED id=…` (job 1887 log line 207 = source, 249 = output), and the Gmail catch-all holds CI failure mails from 2026-10-16 and earlier today. Proof added anyway: a manual `workflow_dispatch` with `force_alarm` in all four repos (key length 36 seen by each); forced run felhom.eu job 1997, `RESEND-ACCEPTED` at 10:48:54Z to admin@felhom.eu, received (Gmail 10:48:55Z). The operator set the key at 12:28 CEST on this row's wrong word. | `audits/filebrowser-memory-ci-2026-10-17/` |
## 2026-10-17 — the CC secret broker `sec` and its guards (`admin/cc-secrets`)
| Row | What | Closed | Evidence |
+7 -7
View File
@@ -124,7 +124,7 @@ stopping line that lies.
| **R-494** | Install & onboarding | P4 | **NARROWED 2026-09-14 by operator ruling → [P3-LOW] the hub COULD create the tunnel at customer creation, for a domain already on Cloudflare. Not blocking: every customer has their own domain and the operator creates the tunnel per day-0 A.1 (`architecture/01-topology-and-trust.md`).** *Original finding, kept:* **[P1-HIGH] A new customer's dashboard has NO reachable address unless the operator hand-makes a Cloudflare tunnel — the link in the setup-code mail is dead.** MEASURED 2026-09-14 on a fresh install from the public ISO (drill intervention **I1**): the claim mail points at `https://felhom.drill0242.felhom.eu`; that name has **no A and no AAAA** record (`dig @1.1.1.1`, control `felhom.enkisfelhom.hu` resolves); the hub has **no tunnel- or DNS-creation code** (`hub/internal/cloudflare/` holds only geo-rule removal; `cf_tunnel_token` is a pasted, optional form field, `configs.go:1478`) — day-0 runbook A.1 makes it a manual Cloudflare-dashboard step that nothing on the customer-create page asks for; the box's own split-horizon resolver on the appliance LAN IP answered `google.com` but not the dashboard name at 13:27:39Z; the agent applied the record at **13:27:44Z** (`lanresolver: applied split-horizon record … ip=192.168.0.158`, 3 m 46 s after the controller started), so the box CAN answer the name — **but only to a device that uses the box as its DNS server, and no document, screen or mail tells a household to do that**; the router and the installer-offered DNS answer nothing. The page was reachable only at the guest's LAN address with the name forced (`curl --resolve …:443:192.168.0.158`). **A volunteer could not have done that.** **What it needs:** an operator ruling — the hub creates the tunnel and DNS at customer creation, or the product gives a household a LAN address that works with no DNS change. | **READY — rank P3-LOW; owner: CC** **Re-ranked 2026-10-03: P3→P4: operator-side automation; the operator creates the tunnel by hand per the day-0 runbook.** | — | — | CC |
| **R-504** | Install & onboarding | P4 | **[P3-LOW] `iso.felhom.eu` cannot show an index page on its own — its root returns 404, and the download page lives on the website instead.** MEASURED 2026-09-14: `https://iso.felhom.eu/` and `/index.html` → 404; only named objects answer. The host is an R2 bucket behind a custom domain; whether R2 would serve an uploaded `index.html` at `/` was **not measured** (uploading anything to the public bucket is a publication). The ISO v1.27.0 task puts the Hungarian download page at `felhom.eu/letoltes` (published with the ISO, after the operator's yes). **Remaining:** a redirect from `iso.felhom.eu/` to that page needs a Cloudflare rule the session has no credential for. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator (Cloudflare rule)** **Re-ranked 2026-10-03: P3→P4: households are sent to the website's download page; the bare address is cosmetic.** | — | — | operator |
## Apps & catalog — 21 rows (P2 1, P3 11, P4 9)
## Apps & catalog — 20 rows (P2 1, P3 10, P4 9)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
@@ -148,7 +148,6 @@ stopping line that lies.
| **R-1100** | Apps & catalog | P3 | **One sign-in for the dashboard and FileBrowser (proxy auth) — spike first.** Since controller 0.320.0 every app with a folder has „Fájlok ↗", and the box can show FileBrowser's password — but FileBrowser still asks for its OWN login the first time, so the household signs in twice. FileBrowser Quantum has a proxy-auth method (`auth.methods.proxyAuth`, header-trusted) that could take the dashboard session through traefik; nobody has measured it. Design: `architecture/02-controller-module-map.md` „Logins and folders". | OPEN — filed 2026-10-16 (task logins-folders). | — | Spike on demo-hp: proxy auth at the pinned tag (source + measured), a forwardAuth in traefik that answers only for a dashboard session, what a stranger reaching `files.<domain>` with a forged header gets, and what happens to FileBrowser's shares. | CC |
| **R-1099** | Apps & catalog | P4 | **The N100 may hold RomM games in the old upload place, now shown under a fake „roms” platform.** Until 2026-10-16 RomM's own upload wrote to the drive's `roms/roms/<platform>/`; after the mapping fix (catalog `fb18471`, R-1089) those files are at RomM's `library/roms/roms/…`. Measured on 9201: such a game showed as missing in its platform and again under a platform „roms” (`audits/romm-ghost-2026-10-16/B/b-after.txt`). Files put in with the file manager are not affected — they are now found. The N100 runs RomM (hub `/apps/romm`); CC does not log in to the lived-in box. | OPEN — filed 2026-10-16 | Operator: look at `roms/roms/` on the N100's drive in the file manager | If it holds platform folders: move them up one level into `roms/`, then run „Scan” in RomM; if it is empty, close | Operator |
| **R-1117** | Apps & catalog | P4 | **Immich's and Nextcloud's Redis keep a volume they do not need** (upstream runs both without one; queues and caches only). Deferred from R-1096 on purpose: removing a volume from the compose leaves the old volume on installed boxes, and the nightly dump / an old backup's restore for a volume the compose no longer declares is unchecked. The RDB switch (catalog `5d9450b`) already removed the full-disk danger. | DEFERRED — filed 2026-10-17 | — | Measure the dump and an old-backup restore without the volume on 9202; then the template change + an orphan-volume note | CC |
| **R-1125** | Apps & catalog | P3 | **23 apps' `mem_request` is below their measured typical use (R-994's second half), and the requests feed the box's install check** (`controller` `stacks/deploy.go:1549` `memoryVerdict`: committed requests + the new one > guest memory − 384 MB → refused). The measured values (rounded up) would raise the household set (Immich, Jellyfin, Nextcloud, Home Assistant, Vaultwarden, paperless-ngx) from 3,622 to 3,910 MB of the 3,712 MB an 8 GB box can use, so its sixth app would be refused on the smallest supported box. The website estimator is not affected (it reads the measurement). Values ready: `audits/tester1-limits-filebrowser-2026-10-17/P3/`. | WAITING-ON-OPERATOR — filed 2026-10-17 (operator: „limits now, requests wait”) | the operator's decision: raise the requests (the box's check gets truer; 8 GB no longer takes the full household set) or keep them | Apply the decision through the catalog | CC |
## App updates — 4 rows (P3 4)
@@ -210,9 +209,9 @@ stopping line that lies.
| **R-1076** | Storage & devices | P4 | **A cheap SSD reports a vendor-less WWN, so a WWN-first disk key may not be unique.** MEASURED 2026-10-15 on the N100's system SSD (AirDisk 512 GB): `ID_WWN=0x5000000123456f1f` — NAA-5 with OUI `000000`, a pattern that looks like a placeholder; its serial `QDF922W009654S30EX` looks real. The agent's wipe binding prefers `wwn-` links (A/internal/storage/durable_device.go:32). Not known whether two units share the WWN. Evidence: `audits/storage-identity-2026-10-15/B-n100.txt`. | OPEN | — | Check a second unit of the same model (or vendor data); if shared, make the agent skip OUI-000000 WWNs (the design already keys on model+serial, `architecture/16-storage-physical-identity.md` §3). | CC |
| **R-1077** | Storage & devices | P4 | **No USB enclosure that hides or fakes a disk's serial has been measured.** The storage-identity spike (2026-10-15) had none at hand and found none in earlier evidence; the design's `usb_bridge` unknown rule (`architecture/16-storage-physical-identity.md` §3) is therefore an assumption. Cheap single- and dual-bay bridges are known to report one bridge serial for any disk. Evidence: `audits/storage-identity-2026-10-15/README.md` case 4b. | OPEN | — | Buy or borrow one cheap USB enclosure (single and dual bay), run `tools/physdisk_probe.py` against it, and set the rule from what it reports. | Operator (a device) then CC |
| **R-1094** | Storage & devices | P4 | **The whole-disk format refusal tells the household to format the free part — which is refused while the other part is in use.** SEEN 2026-10-16 (controller 0.318.0): 409 „Ezen a lemezen egy használatban lévő meghajtó van, ezért a teljes lemez nem formázható. Csak a szabad részét formázhatod." — since agent 0.158.1 a part next to a mounted part can only be USED (the root wrapper trusts no „Felhom's own" claim). Evidence: `audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt`. | READY | — | Reword `err.web.meghajto_hasznalatban_formazas` (hu + en): „… nem formázható. A szabad részét használatba veheted." Next controller release; the copy gates run. | CC |
| **R-1124** | Storage & devices | P4 | **A drive decommissioned and then unplugged keeps its agent mount unit enabled on the host** (`mnt-<name>.mount`, „Managed by felhom-agent”, `WantedBy=multi-user.target`), so every later boot waits for a device that is gone, and the agent's watchdog reports it „disconnected”. Decommission retires the drive logically (agent: „logical retire, data untouched”) and releases only the guest bind; no product path releases the host mount or forgets the drive. Seen on Tester 1 at the R-1022 teardown 2026-10-17 (four units left; the boot delay is read from the unit, NOT measured). | OPEN — filed 2026-10-17 | — | Decide „forget a decommissioned drive” (unit disabled + removed when the drive is absent), with a test | CC |
| **R-1124** | Storage & devices | P4 | **A drive decommissioned and then unplugged keeps its agent mount unit enabled on the host** (`mnt-<name>.mount`, „Managed by felhom-agent”, `WantedBy=multi-user.target`), so every later boot waits for a device that is gone, and the agent's watchdog reports it „disconnected”. Decommission retires the drive logically (agent: „logical retire, data untouched”) and releases only the guest bind; no product path releases the host mount or forgets the drive. Seen on Tester 1 at the R-1022 teardown 2026-10-17 (four units left; the boot delay is read from the unit, NOT measured). | OPEN — filed 2026-10-17 **2026-10-17 (later):** on Tester 1 the four units were disabled and removed by hand (read before and after, `audits/filebrowser-memory-ci-2026-10-17/P4/`); the agent did not write them back, but it still lists the four drives and logs „enrolled drive absent by UUID — will retry” every ~20 s. The product fix (decommission releases the host mount and lets the agent forget an absent drive) is an agent change — it waits for the next vouched agent release. | — | Decide „forget a decommissioned drive” (unit disabled + removed when the drive is absent), with a test | CC |
## Security & access — 27 rows (P1 1, P2 2, P3 18, P4 6)
## Security & access — 26 rows (P1 1, P2 2, P3 17, P4 6)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
@@ -242,7 +241,6 @@ stopping line that lies.
| **R-1132** | Security & access | P3 | **demo-hp's recovery code (`R_DEMO_HP`) was printed in the same JARR record line as R-1131** (2026-10-17 08:27 UTC, the same `. ~/.config/credentials`). | WAITING-ON-OPERATOR | the operator: re-issue, or accept (a demo box) | Decide together with R-1131 | operator |
| **R-1133** | Security & access | P3 | **`~/.git-credentials` on DooPlex holds Gitea tokens in clear text** — three entries (`kisfenyo`, `Kisfenyo`, `admin`); the `admin` token has `write:repository` (and misc, package, issue, notification). Any `cat` of it prints them; the new PreToolUse guard refuses reads of that path (`read-secret-file`), but git itself must keep reading it. Out of the 2026-10-17 build's scope by its brief. | OPEN | — | Decide: move git to a credential helper that reads from `sec`, or accept the file (0600) with the guard | operator → CC |
| **R-1134** | Security & access | P3 | **Retire the old `~/.config/credentials`**: every named key is in the CC store since 2026-10-17 13:16 (23 imported; the two hyphenated names became `R_DEMO_FELHOM`, `R_DEMO_HP`). **Two open points:** (1) its line 20 is a 32-character value with NO name — the import refused it (one bad line refuses all) and CC imported the named lines from a filtered copy; only the operator knows what it is. (2) `FACEBOOK_API` and the Tuya keys, which `fb_probe.py` and the bench README name, are in neither the file nor the store. | WAITING-ON-OPERATOR | a week with no reader (from 2026-10-17), and the operator's go | 2026-10-24: check no reader (sweep + `hook.log`); operator names line 20 (or drops it); then rename the file to `.retired`, and delete only on the operator's go | operator → CC |
| **R-1126** | Security & access | P3 | **The Cloudflare tunnel runs before the box is claimed, and no document says whether that is intended.** The claim needs it: the claim mail links `https://felhom.<domain>` (`hub/internal/notify/templates.go:27`); `cloudflared` is started from the token with no claim check (`controller` `stacks/infra.go:85-90`; `01-topology-and-trust.md:119`, `:248`). Reachable before the claim: the dashboard serves only the claim page (code: 72 h life, 5 tries, 15 min lockout — `web/claim.go:22-33`), and `files.<domain>` — FileBrowser on its default login from its first start until the next base-stack tick sets a password (seconds; v0.326.0 re-checks every run). Options: (A) keep the tunnel; route FileBrowser publicly only after its default is replaced — small, no promise changes; (B) start the tunnel only after a LAN claim — the claim flow and its mail change, the household must be at home. Recommended A. From R-977. | WAITING-ON-OPERATOR — filed 2026-10-17 | the operator's choice A or B | Write the choice into `01` §5; build A (or B) | CC |
## Box system & updates — 12 rows (P2 1, P3 7, P4 4)
@@ -316,11 +314,10 @@ stopping line that lies.
| **R-990** | Business & legal | P4 | **Operator: read `documentation/audits/forum-research-2026-10-12/FELHOM.md` §5 and rule on each recommendation.** READ-ONLY research 2026-10-12: three years (#7943–#11092, 2,908 posts, 195 people, 82 beginner threads) of the public PROHARDVER! topic „Home server / házi szerver építése”, tagged and counted by person (`FINDINGS.md`, method and spot-check in `METHOD.md`; no username or post text in git). Ten ranked recommendations, none acted on; the top three: a „which machine works” page (8 of 33 beginners who name their hardware own only a Synology, a router disk or a Raspberry Pi — the installer cannot run there; the same gap is R-989's first recommendation from a different source, and the shipped-page half is R-991), „you do not choose an operating system — we do” (the biggest beginner question, 20 of 82 threads), and „bring your old office PC” as the cheap entry. Catalog gap (≥ 3 people): a DLNA server (7), an ad/DNS blocker (5), a camera recorder (5). | **WAITING-ON-OPERATOR** — filed 2026-10-12 | the operator's reading | Operator: rule on each of the ten (yes / no / later). If nothing is done: nothing changes; the research ages | operator |
| **R-1035** | Business & legal | P4 | **Did the „felhő tárhely” page earn anything? Two dated checks.** **Baseline (reported by the operator from Search Console, 2026-10-14, last 3 months):** 1 click, 48 impressions, CTR 2.1 %, average position **73.6**; „felhő tárhely” 19 impressions, „felhőtárhely” 5, „felhő alapú tárhely” 3. CC measured separately that the phrase „felhő tárhely” appeared **0 times** on the home, FAQ and backup pages — Google was showing the home page for those queries by accident. `/sajat-felho-tarhely` + `/en/own-cloud-storage` published **2026-10-14**; full baseline, price sources and the power provenance in `audits/seo-2026-10-14/BASELINE.md`. **What to measure, both times:** impressions and average position for „felhő tárhely” and „saját felhő tárhely”, plus the new page's own impressions, clicks and position. **A null result at +4 weeks means nothing on its own** — a new page on a site at position 73.6 takes weeks to months to move, and „felhő tárhely” alone is held by Microsoft, Google and the big list sites; the page aims at the two longer phrases. That is why there are two checks and not one, and why neither should be read as a verdict on the copy. **There is no Search Console connector in this project, so CC cannot read these numbers** — the operator reads them, CC records and compares. **Blocked until the operator asks for indexing** (Search Console → URL-ellenőrzés → the URL → „Indexelés kérése”): until that happens, or Google finds the page itself, both checks read zero for a reason that is not the page. **This is a slow channel and does not replace talking to people.** | **WATCHING** | operator: request indexing, then supply the Search Console read | 2026-11-11: first read (+4 weeks); 2026-12-09: second (+8 weeks), compared with the first | operator + CC |
## Process & tooling — 31 rows (P2 1, P3 9, P4 21)
## Process & tooling — 33 rows (P3 9, P4 24)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
| **R-1129** | Process & tooling | P2 | **CI's failure mail has never been sent: every failed gate run ends „ALARM FAILED: RESEND_API_KEY is empty”, so the safety net four CLAUDE.md files promise („CI re-runs the entry point on every push and emails on failure”, R-168) does not exist.** MEASURED 2026-10-17 from the CI logs: felhom-controller jobs 1887, 1990, 1991; felhom.eu 1747, 1796, 1889; app-catalog 876, 877 (back to 2026-09-22) — all `ALARM FAILED`. `.gitea/workflows/gates.yml:192-199` reads `secrets.RESEND_API_KEY`, which is empty in the runner. A `--no-verify` push or a red CI run therefore reaches nobody. Found by the R-977/R-1116 session (a red run of its own, caused by an unpushed register row). | OPEN — filed 2026-10-17 | — | Set the Actions secret `RESEND_API_KEY` in the four repos (the operator's key, or CC with the operator's word — it is a credential), then prove one mail with a deliberately red throwaway run; correct the four CLAUDE.md sentences until it works | operator |
| **R-1083** | Process & tooling | P3 | **The scratch box 9202 cannot use any feature that needs the agent: its `bootstrap.json` has no `local_api` block, so its controller never gets an agent client.** MEASURED 2026-10-15 (storage-identity build A): 9202 put on controller 0.317.0 by hand to show that a NAS share no longer hides the one-copy notice (R-1075); its `bootstrap.json` (read on the box) holds no `local_api`, so the controller has no agent to ask and keeps the old `st_dev` rule — the check could not tell old from new — 9202 was put back on 0.314.0. Every agent-coupled feature (drives, same-disk, format, network storage) is untestable on the scratch box today, and the NAS leg of build A is proven by a red-proofed unit test only. Evidence: `audits/storage-identity-buildA-2026-10-15/9202-upgrade.txt`. | OPEN | — | Give 9202 a local-API token the normal way (the agent mints it for its guest), or record in `runbooks/target-selection.md` that 9202 is controller-only; then show the NAS notice live. | CC |
| **R-1081** | Process & tooling | P4 | **Two published controller tags hold content that is not what their number says: `0.315.0` and `0.316.3`.** Both were caused by CC on 2026-10-15, and both by the same shape — a guard that was not on the path the work takes. **`0.316.3`:** the build directory's `build.sh` is a symlink into the SHARED clone's working copy, which predated the `FELHOM_REPO_DIR` override, so the override was silently ignored and the build copied that tree — which held 31 uncommitted files of another session's physical-disk storage work. The banner printed `Commit: 0225255` with no `Repo:` line. **Nobody deployed it; that was luck, not a control.** Fixed at the root in controller v0.316.4: `build.sh` now refuses `--push` from a tree that is dirty, not at `origin/main`, or not a git checkout, with four test cases red-proved. **Neither tag is re-pushed or deleted** — a version number is pushed once, and that applies to numbers CC spoiled. **No box runs either:** demo-hp 9201 is on 0.317.0, the floor is 0.314.0, and the button offers the highest tag. **`0.315.0`:** Caused by CC on 2026-10-15 while proving R-1080's own fix: the guard was added to `controller/build.sh` in the repo, but the documented release command runs `$FELHOM_ROOT/build/felhom-controller/build.sh`, which was a **separate copy taken 2026-07-18** and had no guard. Running the refusal against a real existing tag therefore rebuilt and re-pushed 0.315.0 — a fourth time — with v0.316.0's code under it (digest `8887343011d6` → `b809201841f7`). **Fixed at the root in the same session:** the build directory's script is now a symlink to the repo's, the old copy kept beside it as `build.sh.stale-copy-2026-07-18`, and the refusal was then proven to fire from the documented path. **No box is affected:** nothing runs 0.315.0 (demo-hp 9201 is on 0.316.2), the floor is 0.314.0, and the household button offers the highest tag. What remains is two tags that must never be deployed and are no longer reproducible from the registry. | **OPEN** — filed 2026-10-15; nothing to do unless someone needs one of those two images, and then the answer is the current release | — | Leave them. If an audit ever needs the real 0.315.0 or 0.316.3, build it from the matching commit under a NEW number and say so | CC |
| **R-992** | Process & tooling | P3 | **The drill-catalog route that `09` §6.5 documents cannot be followed: `admin/app-catalog-drill` is PRIVATE and no box has catalog credentials.** Measured 2026-10-12 while publishing the Usenet pair: the box's clone fails with `fatal: could not read Username for 'https://gitea.dooplex.hu'` (exit 128), the Gitea API reports the drill repo `private=true` and the live catalog `private=false`, and NEITHER the current controller.yaml on 9202 NOR any of its 30 saved copies has ever carried `git.username` or `git.token` (the controller supports both — `internal/config/config.go` GitConfig). The route worked for the campaigns of 2026-10-10 and the torrent pair earlier the same day, so the repository's visibility changed between then and now. **Worked around, not fixed:** that campaign staged its two templates in the box's own catalog cache (`audits/usenet-2026-10-12/tools/stage_in_cache.py`), which is where the sync copies a catalog change anyway, with the sync interval raised to 12h for the duration and rescan used in place of sync. The real fix is an operator decision: either a read-only catalog credential on the scratch box (a secret on a Tier-0 guest) or making the drill repository readable. Until then every new-app campaign hits this. | WAITING-ON-OPERATOR | the operator's choice between a box credential and a readable drill repo | Decide; then either set `git.username`/`git.token` on 9202 from the credentials store, or flip the drill repo, and correct `09` §6.5 either way | operator |
@@ -351,6 +348,9 @@ stopping line that lies.
| **R-1127** | Process & tooling | P4 | **The controller's and the catalog's decoy suites run only when someone starts a full gate run by hand** — neither the pre-push hook nor CI (`--fast`) runs them (too slow, or they edit real files), so a decoy that goes quiet is again seen only by chance (R-1115's shape). The agent's runs in CI. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | A scheduled full run (CI cron or the nightly), with a mail on failure | CC |
| **R-1128** | Process & tooling | P4 | **The controller's decoy suite edits real tracked files (`handler_debug.go`, `update.go`, the locale bundles, templates) and plants `.go` files, with no lock** — a full run while another session edits the controller tree can overwrite that session's edits. felhom.eu's suite took an `flock` after the 2026-10-08 clobber. Found by the R-1116 helper 2026-10-17. | OPEN — filed 2026-10-17 | — | Run the suite in a scratch copy of the tree, or take the felhom.eu-style lock | CC |
| **R-1123** | Process & tooling | P4 | **`reuse_refs_check.py` treats every git directory beside the repo as a sibling repo**, including stray clones in the workspace (`felhom.eu-media`, `felhom.eu-sizing-push`, `felhom.eu-wt-sizing`), so a citation can resolve against a stale clone and pass. Found by the R-1116 helper 2026-10-17 (it also makes the agent suite 20 s here vs 5 s in CI). | OPEN — filed 2026-10-17 | — | Search only the four known repo names (or the main clones), with a decoy | CC |
| **R-1135** | Process & tooling | P4 | **CI's failure mail links the run at the in-cluster Gitea address** (`http://gitea.gitea-system.svc.cluster.local:3000/...`), which a reader outside the cluster cannot open. Seen in the forced test mail 2026-10-17 (job 1997). | OPEN — filed 2026-10-17 | — | Use the public Gitea URL in the alarm step's link | CC |
| **R-1136** | Process & tooling | P4 | **felhom.eu CI runs take ~6.9 minutes and complete, so the 5-minute job timeout R-265 assumes does not hold there** (runs 1996, 1997; `script-tests` alone ~356 s). Found by the R-1129 proof helper 2026-10-17. | OPEN — filed 2026-10-17 | — | Measure the runner's real timeout; correct R-265's assumption or speed up `script-tests` | CC |
| **R-1137** | Process & tooling | P4 | **A CI rerun may overwrite a failed job's log** — failure mails arrived for controller commits `c02c9d83` and `29a3ce8c` while their jobs (1944, 1959) now read green. UNPROVEN (a reading, 2026-10-17). | OPEN — filed 2026-10-17 | — | Confirm with one deliberate red + rerun on a scratch repo; if true, the CI check must read the first attempt | CC |
<!-- DUE-CHECKS-BEGIN — machine-readable. Parsed by scripts/due_checks_gate.py.
One row per dated check. The R-number must have a row above. Dates are UTC.