answers 2026-10-12 Part A: the 38 rulings recorded (09 §3 196-233), 17 rows closed (128 -> 112), R-933 filed
gates / gates (push) Successful in 6m41s
gates / gates (push) Successful in 6m41s
- 09 §3: the decision sheet S1-S38, the operator's words quoted where they differ (S1, S2, S8, S32, S37) - closed: R-831 R-870 R-698 R-327 R-230 R-719 R-352 R-526 R-770 R-771 R-913 R-290 R-209a R-769 R-616 R-884, and R-243 (dated check: the mail fired 2026-10-11 16:13:51Z, hub log agrees) - R-698: the known limit written in 07 §6.6; new row R-933 (mirror supported catalog images, P3) - R-327: capability-map row BUILT; stands claim re-titled and moved to built; page re-rendered - R-913: the customer Cloudflare token recipe in day0-install A.1; 01 §7 points at it - R-884: read only - ArgoCD Synced, live Deployment equals git - R-887 dated check NOT met (4 lost jobs 10-10/11); re-dated 2026-10-19 after the S21 change - 22 open rows carry their ruling; STATUS: the sheet is ANSWERED Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -222,7 +222,9 @@ app. Controller down → the gated app answers an error, never the app. Measured
|
||||
customer added later would be reachable). Cloudflare unreachable → the save fails and the old token stays. The token
|
||||
is never logged. **Limit:** `/zones` lists what the token can READ; a hand-built token with Zone:Read on one zone and
|
||||
DNS:Edit on all zones would pass — the token wizard's single „Specific zone" scope does not build that, and a
|
||||
customer token cannot read its own policies. Tokens saved before this check are checked the first time each config
|
||||
customer token cannot read its own policies. **The guard for the write side is the recipe, not a check** (operator
|
||||
ruling 2026-10-12, S31, `09` §3 decision 226): the operator mints every customer token from the one recipe in
|
||||
`runbooks/day0-install.md` A.1, and the hub checks nothing more. Tokens saved before this check are checked the first time each config
|
||||
is saved with a new token or domain.
|
||||
- **Tunnel placement: INSIDE the guest** (corrected 2026-10-01, R-754 — the operator's brief of that evening: the build is
|
||||
right, correct the document). `cloudflared` is a container the CONTROLLER renders and keeps up (`internal/infra`,
|
||||
|
||||
@@ -875,7 +875,11 @@ requires a database dump written after the conversion whose recorded engine is t
|
||||
|
||||
**[FACT] The limit — the image is not in the backup (R-698).** A unit stores image NAMES and digests; the
|
||||
image is re-pulled on restore. A version its maker has deleted cannot start. Measured 2026-09-26: the 42 ladder
|
||||
digests all resolve today (`audits/version-travel-2026-09-26/A7/`). Options are in R-698; nothing is decided.
|
||||
digests all resolve today (`audits/version-travel-2026-09-26/A7/`). **Accepted as a known limit — operator ruling
|
||||
2026-10-12 (S8, `09` §3 decision 203; R-698 closed).** What a household meets: a restore whose version the maker has
|
||||
deleted stops at the image pull, the app stays as it was, and the household uses another copy or a newer version.
|
||||
The operator's follow-up — *„will need to mirror the apps we support later, just to be sure"* — is **R-933**: mirror
|
||||
the images of every catalog app we support into our own registry, before scale. Until it is built, this limit holds.
|
||||
**Since decision 53 (`09` §3, 2026-09-30 evening):** a box keeps only the image each app service runs and the one before
|
||||
it; older images of the app are deleted. A restore that needs an older version re-pulls it — as before; the limit
|
||||
above is unchanged, and kept data (decision 40) is not touched by the image clean-up.
|
||||
|
||||
@@ -915,6 +915,70 @@ its length, and both fixes cost something the household would notice — operato
|
||||
127. **The agent's three by-design abilities (`03` §3.1) stay for now**; revisited before the first paying customer.
|
||||
*Operator ruling 2026-10-05.* (R-861)
|
||||
|
||||
### 2026-10-12 (13:50) — the decision sheet S1–S38 answered (recorded before the work; the „build the 38 answers" brief)
|
||||
|
||||
The sheet: `STATUS.md` „The decision sheet (2026-10-10 afternoon)". Each line names the sheet number and the row. Where the
|
||||
operator's words differ from the sheet's pick, his words are quoted and they win. *Operator rulings 2026-10-12 13:50.*
|
||||
|
||||
196. **S1 — R-922: the hub's registered customer address stays; only the box's notification address can be cleared.**
|
||||
*„the customer can only delete their email address in the controller, from the notification address. If they do that,
|
||||
they won't get any more notifications (maybe a warning popup?). However in the HUB each customer needs an email
|
||||
address, and the user can't delete that, so the HUB can reach the user if needed (accounting, or any other reason)."*
|
||||
So: a warning before the household clears its notification address (controller), and the privacy-notice draft says
|
||||
why the registered address is kept.
|
||||
197. **S2 — R-831: the Hetzner storage token stays valid (option A, accept).** The sheet's pick was „rotate"; the operator
|
||||
chose A. Row closed as accepted.
|
||||
198. **S3 — R-870: Tester 1's two leaked Cloudflare tokens are accepted;** they are rotated when Tester 1 is retired.
|
||||
199. **S4 — R-242: a hub alarm when the newest baked golden is not vouched,** before the first external install.
|
||||
200. **S5 — R-388: the household notification settings are redesigned to „only what you can act on" — designed now,
|
||||
built in slices later.**
|
||||
201. **S6 — R-244: the hub removes a deleted customer's id from shared app-log issue rows, and sweeps once** (the count
|
||||
is shown before the sweep).
|
||||
202. **S7 — R-264: CC owns the six owed hub readers (decided 2026-08-12) and builds them when the queue is idle.**
|
||||
203. **S8 — R-698: a restore of a version whose image the maker deleted cannot start — accepted as a known limit**
|
||||
(`07` §6.6), row closed. *„Will need to mirror the apps we support later, just to be sure"* → new row R-933 (P3):
|
||||
mirror the images of every catalog app we support to our own registry, before scale.
|
||||
204. **S9 — R-255: one test renders every dashboard page with planted secrets and fails if any shows.**
|
||||
205. **S10 — R-266: „disk reading failed" is carried to the hub,** so it is not read as an empty disk (hub + controller).
|
||||
206. **S11 — R-333: no heat band for NVMe;** the drive's own critical warning still alarms.
|
||||
207. **S12 — R-577: guest share pages get the language globe** (the visitor's own cookie).
|
||||
208. **S13 — R-327: the code-naming arc is „built" in the capability map;** CC rewrites the title. Row closed.
|
||||
209. **S14 — R-230: dated history entries in the memory index may keep version numbers;** (a) closed, the pilot (c)
|
||||
dropped. Row closed.
|
||||
210. **S15 — R-719: the expired self-bind link's „Új linket kérek" shape is accepted.** Row closed.
|
||||
211. **S16 — R-352: hot data in the guest, bulk data on a drive, is by design.** Row closed.
|
||||
212. **S17 — R-526: no „release only the PBS token" operation on ep0** — the R-511 adopt path already reuses the kept
|
||||
token. Row closed.
|
||||
213. **S18 — R-213: „see what a restore would change" is designed after the first customers.** Row stays open, P4.
|
||||
214. **S19 — R-288: one session restructures the capability map** — one status line per capability with a dated pointer
|
||||
to its evidence. Documentation only.
|
||||
215. **S20 — R-231: DooPlex's backup scripts (`/opt/backup/scripts`) go into a repo with an install script;** the
|
||||
operator is present for the install.
|
||||
216. **S21 — R-887: raise the act-runner's fetch timeout and rate-limit the public Gitea pages the crawler walks**
|
||||
(DooPlex; each change after the operator's yes in chat).
|
||||
217. **S22 — R-886: `fsGroup: 65534` for Alertmanager;** a silence must be proven to survive a pod restart.
|
||||
218. **S23 — R-211: the Prometheus config-reloader sidecar** (DooPlex, after the operator's yes in chat).
|
||||
219. **S24 — R-770: no Invidious.** Row closed.
|
||||
220. **S25 — R-771: no moonlight-web.** Row closed.
|
||||
221. **S26 — R-782: Glance goes behind the family gate,** like Grimmory.
|
||||
222. **S27 — R-554: `recovery-info.txt` points at the dashboard's Restore page and the recovery code; then the obsolete
|
||||
setup wizard is deleted.** The operator approves the Hungarian text before it ships.
|
||||
223. **S28 — R-562: Hungarian dates and numbers in Hungarian (decimal comma, `2026. 10. 10. 15:04`), ISO-like in English.**
|
||||
224. **S29 — R-250: the off-site setup scan prefers IPv4 and waits longer, and its error says „safe to press again".**
|
||||
225. **S30 — R-246: the hub's `stale_at` column is retired.**
|
||||
226. **S31 — R-913: the operator mints every customer Cloudflare token from one recipe; the hub checks nothing more**
|
||||
(option a). The recipe: `runbooks/day0-install.md` A.1. Row closed.
|
||||
227. **S32 — R-521: one mail per lost drive to the household, in its language — *„if there is a notification option in the
|
||||
controller settings, and enabled"*.** So the mail goes only when the household's own notification settings carry
|
||||
that option and it is switched on (hub + controller).
|
||||
228. **S33 — R-402: one line on the hub's host page: „Last full check: OK/FAILED, depth N, date".**
|
||||
229. **S34 — R-290: folded into R-288** (the map restructure cites an evidence file for every green row). Row closed.
|
||||
230. **S35 — R-209a: accepted until a planned reboot;** the next planned DooPlex reboot checks the SSD2 move. Row closed.
|
||||
231. **S36 — R-769: no Pinchflat.** Row closed.
|
||||
232. **S37 — R-884: *„Fixes, can be closed"*** — CC reads the ArgoCD state for Prometheus once, read only; Synced → close
|
||||
with the evidence, drift → one line for the operator and the row stays.
|
||||
233. **S38 — R-616: the Gitea admin token the catalog clone exposed was rotated (in the R-925 work).** Row closed.
|
||||
|
||||
### 2026-10-10 — operator ruling: the kernel approval rule (recorded before the work; the release brief)
|
||||
|
||||
195. **„Approve kernel set" offers the NEWEST kernel version that EVERY ring-0 box has booted healthily at least once
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -126,16 +126,18 @@ claims:
|
||||
- id: claim.code-naming
|
||||
band: journey
|
||||
stage: 2
|
||||
title: "The same word is used for two different secrets across three surfaces; the email points at a page a rebuilt machine does not show"
|
||||
status: partial
|
||||
note: "Warning card. Cost a real code on 2026-08-09."
|
||||
title: "Each of the two secrets has one name on every surface, and the re-enrol mail points at a page a rebuilt machine shows"
|
||||
status: built
|
||||
note: "Shipped (controller v0.211.0, hub v0.104.0/v0.105.0); no customer has typed the passphrase yet. Operator ruling 2026-10-12 (S13). The old defect cost a real code on 2026-08-09."
|
||||
sources:
|
||||
- register: "R-282"
|
||||
- register: "R-283"
|
||||
- register: "R-295"
|
||||
- register: "R-323"
|
||||
- register: "R-327"
|
||||
verified:
|
||||
date: 2026-08-09
|
||||
verdict: confirmed
|
||||
depth: source-read
|
||||
date: 2026-10-12
|
||||
verdict: upgraded
|
||||
depth: register+map
|
||||
- id: use.catalog
|
||||
band: journey
|
||||
stage: 3
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# R-243 dated check, read 2026-10-12 ~12:05Z
|
||||
channel 1 (operator mailbox, Gmail connector): thread 1a12bbe0e6599a61, from monitoring@felhom.eu to admin@felhom.eu,
|
||||
2026-10-11T16:13:51Z, subject "[Felhom] ⚠️ Tester-2: offsite_escrow_pending",
|
||||
"Customer Tester-2: off-site backup is ON but has not run for 168h0m0s since the box first ..."
|
||||
channel 2 (the running hub pod, kubectl logs deploy/hub --since=30h):
|
||||
2026/10/11 18:13:51 [INFO] Operator email sent for Tester-2/offsite_escrow_pending
|
||||
Expected: first sweep after 2026-10-11 ~16:06Z (anchor = Tester 2's first report). Fired 16:13:51Z.
|
||||
@@ -0,0 +1,10 @@
|
||||
# R-884 read-back, 2026-10-12 (read only)
|
||||
Mon Oct 12 11:56:40 UTC 2026
|
||||
## channel 1: ArgoCD Application monitoring
|
||||
sync=Synced health=Healthy rev=eeb009f790f8495d72434aa3500f8e1de391c6a0 reconciledAt=2026-10-12T11:52:32Z
|
||||
resources 29 not Synced: []
|
||||
prometheus Deployment: ['Synced']
|
||||
## channel 2: the live Deployment vs git (homelab-manifests eeb009f, mon-system/monitoring.yaml)
|
||||
git image prom/prometheus:v3.15.0, live image prom/prometheus:v3.15.0
|
||||
live args ["--config.file=/etc/prometheus/prometheus.yml","--storage.tsdb.path=/prometheus","--storage.tsdb.retention.time=60d","--storage.tsdb.retention.size=19GB","--web.enable-lifecycle","--web.enable-admin-api"]
|
||||
git args identical (6 flags, compared by script 2026-10-12 11:55Z)
|
||||
@@ -26,6 +26,30 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-12 (afternoon) — the operator's 38 answers (sheet S1–S38): the rows that need no code
|
||||
|
||||
The full text of the rows below: `git show 25ab47eeaa:documentation/backlog/OPEN-ITEMS.md`. Evidence: `documentation/audits/answers-2026-10-12/` unless a row names another place.
|
||||
|
||||
| Row | What | Closed | Evidence |
|
||||
|---|---|---|---|
|
||||
| **R-243** | **A box in the R-241 state silently stops backing up off-site, and NO ALARM OF ANY KIND FIRES.** (P2) | CLOSED 2026-10-12 — **the alarm fired on time.** The `offsite_escrow_pending` mail for Tester-2 reached the operator mailbox 2026-10-11 16:13:51Z (the first sweep after the 7-day line, ~16:06Z); the running hub logged „Operator email sent for Tester-2/offsite_escrow_pending" at the same second. Two channels. | hub v0.144.0+ (`b119301c`); `r243-escrow-pending-mail.txt` |
|
||||
| **R-831** | **The Hetzner storage API token (`HETZNER_TOKEN`, the storage project's token in `Secret/storagebox`) was printed into the 2026-10-03 session transcript** (P3) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S2, `09` §3 decision 197): **A — accept.** The Hetzner storage token stays valid. | the ruling |
|
||||
| **R-870** | **Tester 1's two Cloudflare credentials — the zone API token (`infrastructure.cf_api_token`) and the tunnel token (`infrastructure.cf_tunnel_token`) of the hub's `customer_configs` row `tester-1` — were printed into the 2026-10-04 night session's transcript** (P3) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S3, `09` §3 decision 198): **accepted**; rotate when Tester 1 is retired. | the ruling |
|
||||
| **R-698** | **[P3-LOW] A backup stores the image's NAME, not the image — a restore of a version its maker has deleted cannot start.** (P3) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S8, `09` §3 decision 203): **accepted as a known limit**, written in `07` §6.6. The operator's follow-up (mirror the images of every supported catalog app) is the new row R-933. | `architecture/07-backup-architecture.md` §6.6 |
|
||||
| **R-327** | **The standing picture still describes a defect that has been fixed twice over.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S13, `09` §3 decision 208): **„built"**: a capability-map row added (status BUILT), the standing-picture claim `claim.code-naming` re-titled as a capability and moved to `built`, the page re-rendered. | `00-capability-map.md`, `where-felhom-stands.yaml`/`.html` |
|
||||
| **R-230** | **Three instruction/memory follow-ups deliberately left by the part-2 session (2026-08-06), each needing a decision rather than an implementation.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S14, `09` §3 decision 209): (a) **ruled: dated history entries in the memory index may keep version numbers**; (b) was closed 2026-08-06; (c) **the pilot is dropped**. | the ruling |
|
||||
| **R-719** | **[P2-MEDIUM] A customer who already exists never gets a fresh self-bind link when their new box registers: the last link expires in 7 days and nothing re-sends it.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S15, `09` §3 decision 210): **the „Új linket kérek" shape is accepted.** | the ruling; the shape shipped earlier (row text) |
|
||||
| **R-352** | **Four screens state something untrue about where an app's data goes, and the configured default is consulted by nothing that places data.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S16, `09` §3 decision 211): **by design**: hot data in the guest, bulk on a drive. The visibility fix shipped; R-368 fixed the comment. | the ruling |
|
||||
| **R-526** | **[P3-LOW] A host delete cannot release only the customer's ep0 PBS token: the endpoint's one removal op destroys every backup group too.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S17, `09` §3 decision 212): **no** — the R-511 adopt path already reuses the kept token. | the ruling |
|
||||
| **R-770** | **[P3-LOW] Invidious — fit check only; the recommendation is not to build it.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S24, `09` §3 decision 219): **no Invidious.** | the ruling |
|
||||
| **R-771** | **[P3-LOW] moonlight-web — fit check only; not buildable through an HTTP-only tunnel at usable latency.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S25, `09` §3 decision 220): **no moonlight-web.** | the ruling |
|
||||
| **R-913** | **The Cloudflare token check (R-138, decision 190) reads what a token can SEE, not what it can WRITE.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S31, `09` §3 decision 226): **(a)** — the operator mints every customer token from one recipe; the hub checks nothing more. Recipe written: `runbooks/day0-install.md` A.1; `01` §7 points at it. | `runbooks/day0-install.md` A.1 (recipe read from the hub and controller Cloudflare calls 2026-10-12) |
|
||||
| **R-290** | **Most capability-map rows that back a green dot cite no evidence document at all — measured, 20 of 28 probed.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S34, `09` §3 decision 229): **folded into R-288** (the map restructure cites an evidence file for every green row). | R-288 |
|
||||
| **R-209a** | **The SSD2 move has NOT survived a reboot, so by this project's own standard it is not fully validated** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S35, `09` §3 decision 230): **accepted until a planned reboot**; the next planned DooPlex reboot checks the SSD2 move (the mechanism is proven). | the ruling |
|
||||
| **R-769** | **[P3-LOW] Pinchflat is not built: upstream is paused (no release in 2026, last push 2025-12-16) and its last release has no image tag.** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S36, `09` §3 decision 231): **no Pinchflat.** | the ruling |
|
||||
| **R-616** | **[P3-LOW] The catalog credentials are stored in PLAINTEXT in the box's catalog clone and are printed by an ordinary `git remote -v`.** (P3) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S38, `09` §3 decision 233): **the Gitea admin token the clone exposed was rotated** (operator's word, the R-925 work). The leak itself was fixed and read on every box 2026-10-10. | the operator's word 2026-10-12; `audits/register-shrink-2026-10-10/` (the 2026-10-10 clone read) |
|
||||
| **R-884** | **ArgoCD app `monitoring` shows `Deployment/prometheus` OutOfSync** (P4) | CLOSED 2026-10-12 — operator ruling 2026-10-12 (S37, `09` §3 decision 232): *„Fixes, can be closed"* — read once, read only: ArgoCD app `monitoring` Synced/Healthy, 29 resources, none OutOfSync, `Deployment/prometheus` Synced; the live Deployment's image and six args equal git (homelab-manifests `eeb009f`). Two channels. | `r884-prometheus-sync.txt` |
|
||||
|
||||
## 2026-10-10 (afternoon) — the register-shrink session: delivered rows read back, small fixes, the decision sheet
|
||||
|
||||
The full text of the rows below: `git show 7413e0dfab:documentation/backlog/OPEN-ITEMS.md`. Evidence: `documentation/audits/register-shrink-2026-10-10/` unless a row names another place.
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -54,8 +54,23 @@ Tunnels):
|
||||
everything — cloudflared logs `No ingress rules were defined` (R-505). Make sure the domain is on
|
||||
Cloudflare (nameservers active).
|
||||
|
||||
Also have ready (optional but recommended): a **Cloudflare API token** with Zone edit rights for the
|
||||
customer's zone — the hub uses it for geo-restriction management.
|
||||
Also have ready (optional but recommended): a **Cloudflare API token** for the customer's zone — the hub and the
|
||||
box use it for geo-restriction management.
|
||||
|
||||
**The customer token recipe — the ONLY way a customer token is minted** (operator ruling 2026-10-12, S31, `09` §3
|
||||
decision 226; R-913). The hub's save check sees what a token can READ, not what it can WRITE (`01` §7), so the guard
|
||||
is this recipe. Cloudflare → My Profile → API Tokens → Create Token → **Create Custom Token**:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Token name | `felhom-<customer-id>` |
|
||||
| Permissions | `Zone` · `Zone` · **Read** — and `Zone` · `Zone WAF` · **Edit** (nothing else: no DNS, no Account permission) |
|
||||
| Zone Resources | **Include** · **Specific zone** · the customer's domain (never „All zones", never an account) |
|
||||
| Client IP filtering, TTL | leave empty |
|
||||
|
||||
Why these two: the hub and the controller call only `GET /zones?name=…` and the zone's `rulesets` (read 2026-10-12:
|
||||
`hub/internal/cloudflare/unblock.go`, `felhom-controller/controller/internal/cloudflare/{zone,waf}.go`). Paste the token
|
||||
once into the customer's config; the hub then checks it sees exactly that one zone. Never reuse a token across customers.
|
||||
|
||||
**„No TLS Verify" on the public hostname (R-510, 2026-09-15).** The route sends traffic to
|
||||
`https://traefik`, and traefik answers the name `traefik` with its own default certificate. Tick
|
||||
|
||||
Reference in New Issue
Block a user