Night 2026-10-25 Parts 1–3: every named artifact still downloads; installer 1.36.1 published (operator yes) and its three refusal sentences seen live; D50 = A recorded (09 §3 262, CONTEXT, build skill); R-1284 and R-1290 closed; R-1261 rig evidence so far
gates / gates (push) Successful in 12m56s
gates / gates (push) Successful in 12m56s
This commit is contained in:
1 parent
b841192670
commit
68ee667a83
19 files changed
+378
-8
No files matched your search
@@ -16,6 +16,14 @@
|
||||
> and holds nothing of its own; this file does hold its own content, namely the standing rulings below.
|
||||
|
||||
|
||||
> **2026-10-25 (evening, attended) — D50 = A; installer 1.36.1 published.** (`09` §3 decision 262.) The registry keeps the
|
||||
> newest 5 agent versions + the MinAgent floor + the day-0 agent; the agent CI asserts exactly these
|
||||
> (`retention-policy.json` `pinned`, copied from hub state by the vouching session — CI holds no hub secret). The operator
|
||||
> also pruned controller, golden and hub images by hand; every artifact still named (manifest agent/bundle/golden, the
|
||||
> floor agent, tags v0.158.1+, controller 0.343.0/0.342.0/0.331.0, samba 1.2.0, the ISO) downloads
|
||||
> (`audits/night-2026-10-25/part1-artifacts.txt`). Installer 1.36.1 (`installer-v1.36.1` → `79ee3e33`, served sha256
|
||||
> `e18cdd17…`): the preflight words 401/404/409 again (R-1284).
|
||||
|
||||
> **2026-10-25 (attended release run) — D49 = A, D44/D45 = all picks, D46 = yes; released: hub 0.170.0, agent 0.165.0,
|
||||
> controller 0.343.0, catalog `ebbf1f4`** (`09` §3 decisions 258–261; `REPORT-release-2026-10-26.md`). **D49 = A:** a
|
||||
> restore whose app does not start keeps both copies and never pours back by itself (`07` §8.2e). **Fix A** (controller
|
||||
|
||||
@@ -49,12 +49,10 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te
|
||||
|
||||
**Day, 2026-10-23 — your do list.**
|
||||
1. Print the break-glass sheet (`documentation/runbooks/break-glass-sheet.md`, the part from „The sheet”, one A4), fill it by hand, keep it outside the home (D32; R-923, R-924). If not: after a DooPlex loss no off-site copy opens.
|
||||
2. On the hub's Hosts page: Discard appliance 49, and delete host Tester4-f967d4 (the BYO test host, removed 2026-10-25). If not: dead entries alarm.
|
||||
2. On the hub's Hosts page: Discard appliance 49. If not: a dead entry alarms.
|
||||
3. Give the homelab session R-1241, R-1242, the lists at the end of `documentation/audits/plex2shell-felhom-impact-2026-10-23/README.md` and `documentation/audits/dooplex-alarms-2026-10-24/README.md`, and an upload alarm on DooPlex's `eno1` (~100 Mbit/s line; the flood peaked at 905). If not: the next hacked app on DooPlex can read the hub's backups.
|
||||
**The rest**
|
||||
- System poster needs a refresh: the new 01:40 „release copy” arrow from DooPlex to ep0 (D33); the hub-database label already says every 6 hours. If not: the drawing misses one copy.
|
||||
- Tell CC what removed four old agent packages from Gitea on 2026-10-25 (a clean-up rule?): the agent's CI is red until the gate and the rule agree (R-1290).
|
||||
- Publish installer 1.36.1 (tag + webpage sync): a wrong passphrase then reads „passphrase REJECTED", not a doubled code (R-1284).
|
||||
- Rotate the reused homelab logins and decide the Gitea repo's visibility (R-925, P1). Since 2026-10-09.
|
||||
- Two DooPlex leftovers: `leftovers/2026-10-14/first-post/` (keep or delete); the `deny`-list edit in homelab-manifests' `.claude/settings.json` (commit or drop). Since 2026-10-14.
|
||||
- Before the first paying customer: Tandoor's permission (R-789); a lawyer for the licence list and the terms (R-802, R-813); SparkyFitness by e-mail (R-784).
|
||||
|
||||
@@ -1099,6 +1099,16 @@ its length, and both fixes cost something the household would notice — operato
|
||||
`plex: security fix CVE-2026-96652,CVE-2026-96654,CVE-2026-96655,CVE-2026-96656 taken` and ended `done` in 30.1 s
|
||||
after the update's second-drive copy and undo copy. Released as controller 0.341.0, global floor 11:24 UTC.
|
||||
|
||||
### 2026-10-25 (evening, attended) — D50: which agent packages the registry keeps
|
||||
|
||||
262. **The registry keeps the newest 5 released agent versions, plus the hub's MinAgent floor, plus the version the hub's
|
||||
day-0 manifest names; CI asserts exactly these (D50 = A).** *Operator ruling 2026-10-25 evening.* Options: A) this
|
||||
— cost: a box on a version outside the set cannot fetch its own binary again (none is, on the day); B) the newest 10,
|
||||
never pruned by hand — cost: today's four are gone, so CI stays red until ten new versions exist. Why A: it is what
|
||||
the operator prunes to, and the two pinned versions are the only old ones anything still asks for. Built: agent
|
||||
`scripts/retention-policy.json` (`generic_versions_kept` 5, `pinned`) + `check-published-versions.py`; the pins are
|
||||
copies of hub state, updated by the session that records a vouch or a new MinAgent (R-1290).
|
||||
|
||||
### 2026-10-25 (attended release run) — D49: a restore that does not start keeps both copies; D44–D46: the review picks
|
||||
|
||||
258. **A restore whose app does not start keeps the restored data AND the old copy, tells the operator, and never puts the
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Part 1 — what a box or the installer can still ask for (read only), 2026-10-25 ~19:00Z
|
||||
# The operator pruned old controller, agent and golden packages by hand on 2026-10-25 (about the last 5; 10 for the controller).
|
||||
hub manifest (hub.db + WAL copy, read only, deleted after): agent 0.165.0 e9d04a47…, bundle 8dea1f34…, golden 0.331.0 3881de62…, MinAgent 0.158.1, global floor 0.343.0
|
||||
registry now: agent 0.158.1, 0.161.0–0.165.0, 0.163.0-step1 | golden 0.311.0, 0.312.0, 0.313.0, 0.318.0, 0.329.0, 0.331.0 | controller 0.331.0, 0.341.0, 0.342.0, 0.343.0 (+ rc) | hub 0.165.0–0.170.0 | samba 1.0.0–1.2.0
|
||||
anonymous downloads (HTTP, bytes, sha256 prefix):
|
||||
felhom-agent/0.165.0/felhom-agent 200 16286780 e9d04a47ee85222c = manifest
|
||||
felhom-agent/0.165.0/felhom-config-bundle.json 200 370108 8dea1f34d77ba40a = manifest
|
||||
felhom-agent/0.158.1/felhom-agent 200 14919180 20264df64ef646a8 (the MinAgent floor)
|
||||
felhom-agent/0.158.1/felhom-config-bundle.json 200 345462 c23c3d355fe70a6f
|
||||
felhom-golden/0.331.0/golden.tar.zst 200 637197198 3881de62b0986ccb = manifest
|
||||
agent tags v0.158.1 … v0.165.0 (10): raw/tag/<t>/configs/felhom-os-apply → 200 each
|
||||
controller images (docker manifest inspect from guest 9202, no login): 0.343.0 OK, 0.342.0 OK (rollback), 0.331.0 OK (the golden's), felhom-samba:1.2.0 OK (the pinned one); control 0.340.0 MISSING (pruned) — the check can fail
|
||||
ISO iso.felhom.eu felhom-installer-1.30.0-pve9.2-1.iso 200 (1705324544 B); its manifest names only host-install-url https://felhom.eu/scripts/felhom-host-install.sh (fetched at run time — the ISO embeds no installer) → 200
|
||||
VERDICT: nothing that is still named is missing.
|
||||
@@ -0,0 +1,11 @@
|
||||
SCRIPT_VERSION="1.36.1" # the SINGLE version source (F-1): -h and the run banners follow it.
|
||||
e18cdd17823911e7d87da12fcb8d48b6827f1706a84b3168114fe19fe30aa1f1
|
||||
== a customer id that does not exist
|
||||
[ERROR] customer 'no-such-customer-cc' not found in hub (404) — create it in the hub first
|
||||
[ERROR] PRE-FLIGHT FAIL (exit 1) — fix the finding above and re-run
|
||||
== Tester4 with a wrong passphrase
|
||||
[ERROR] passphrase REJECTED (401) for customer 'Tester4'
|
||||
[ERROR] PRE-FLIGHT FAIL (exit 1) — fix the finding above and re-run
|
||||
[ERROR] the hub answered 409 on the config preflight (GET /config): this customer already has a live box, which uses its own key.
|
||||
HU: a hub 409-cel válaszolt (the config preflight (GET /config)): ennek az ügyfélnek már van élő gépe, amely a saját kulcsát használja.
|
||||
[ERROR] PRE-FLIGHT FAIL (exit 1) — fix the finding above and re-run
|
||||
@@ -0,0 +1,16 @@
|
||||
0. fresh:
|
||||
mode=0 uploadLimit=0 prefs={'up_limit': 0, 'alt_up_limit': 10240, 'scheduler_enabled': False}
|
||||
1. setUploadLimit 2500000 (normal mode):
|
||||
mode=0 uploadLimit=2499584 prefs={'up_limit': 2499584, 'alt_up_limit': 10240, 'scheduler_enabled': False}
|
||||
2. setPreferences alt_up_limit 3072000:
|
||||
mode=0 uploadLimit=2499584 prefs={'up_limit': 2499584, 'alt_up_limit': 3072000, 'scheduler_enabled': False}
|
||||
3. toggleSpeedLimitsMode (to alt):
|
||||
mode=1 uploadLimit=3072000 prefs={'up_limit': 2499584, 'alt_up_limit': 3072000, 'scheduler_enabled': False}
|
||||
4. setUploadLimit 1024 in ALT mode:
|
||||
mode=1 uploadLimit=1024 prefs={'up_limit': 2499584, 'alt_up_limit': 1024, 'scheduler_enabled': False}
|
||||
5. setPreferences up_limit 5120000 in ALT mode:
|
||||
mode=1 uploadLimit=1024 prefs={'up_limit': 5120000, 'alt_up_limit': 1024, 'scheduler_enabled': False}
|
||||
6. toggle back to normal:
|
||||
mode=0 uploadLimit=5120000 prefs={'up_limit': 5120000, 'alt_up_limit': 1024, 'scheduler_enabled': False}
|
||||
7. setPreferences up_limit 0:
|
||||
mode=0 uploadLimit=0 prefs={'up_limit': 0, 'alt_up_limit': 1024, 'scheduler_enabled': False}
|
||||
@@ -0,0 +1,4 @@
|
||||
# D50 decoys against the OLD gate (check-published-versions.py at 6b6ba0c), 2026-10-25
|
||||
FAIL: published: GENUINE (D50): a pinned version older than the window is asserted and downloads: rc=0 expected 0; missing ['verifying: 0.8.0']
|
||||
FAIL: published: FACT (D50): a pinned version older than the window whose package 404s: rc=0 expected 1 - LIVE HOLE; missing ['FAIL v0.8.0', 'binary NOT downloadable']
|
||||
FAIL: published: FACT (D50): a pin that names a version with no tag: rc=0 expected 1 - LIVE HOLE; missing ['FAIL pinned day0_agent=0.150.9', 'no git tag']
|
||||
@@ -0,0 +1,22 @@
|
||||
# R-1261 red-proofs: each fix switched off in turn (controller working tree, 2026-10-25)
|
||||
## 1. hold only the first running app
|
||||
=== RUN TestR1261_EverySeederIsHeldAndEveryLimitComesBack
|
||||
linehold_r1261_test.go:90: during the test qbittorrent={Bytes:1024 Alt:false Enabled:false KBps:0} transmission={Bytes:0 Alt:false Enabled:true KBps:500} — every seeder must be at the test value
|
||||
--- FAIL: TestR1261_EverySeederIsHeldAndEveryLimitComesBack (0.00s)
|
||||
FAIL
|
||||
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/upwatch 0.007s
|
||||
## 2. no installed check
|
||||
=== RUN TestR1261_ARecordOfAnAppRemovedWhileHeldIsDropped
|
||||
linehold_r1261_test.go:121: the record of a removed app must be dropped, got &{App:qbittorrent Prev:{Bytes:2499584 Alt:false Enabled:false KBps:0} Held:{Bytes:1024 Alt:false Enabled:false KBps:0} At:}
|
||||
--- FAIL: TestR1261_ARecordOfAnAppRemovedWhileHeldIsDropped (0.00s)
|
||||
FAIL
|
||||
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/upwatch 0.007s
|
||||
## 3. the release reads the current mode's slot
|
||||
=== RUN TestR1261_ASpeedModeSwitchDuringTheTestNeverLeavesTheTestValue
|
||||
=== RUN TestR1261_ASpeedModeSwitchDuringTheTestNeverLeavesTheTestValue/hold_in_alt_mode=false
|
||||
linehold_r1261_test.go:168: after the test up_limit=1024 alt_up_limit=3072000, want 2499584 and 3072000 — never the 1 KiB/s test value
|
||||
=== RUN TestR1261_ASpeedModeSwitchDuringTheTestNeverLeavesTheTestValue/hold_in_alt_mode=true
|
||||
linehold_r1261_test.go:168: after the test up_limit=2499584 alt_up_limit=1024, want 2499584 and 3072000 — never the 1 KiB/s test value
|
||||
--- FAIL: TestR1261_ASpeedModeSwitchDuringTheTestNeverLeavesTheTestValue (0.01s)
|
||||
FAIL
|
||||
FAIL gitea.dooplex.hu/admin/felhom-controller/internal/upwatch 0.012s
|
||||
@@ -0,0 +1,8 @@
|
||||
20:43:20 [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH', 'QBT_ADMIN_PASSWORD']
|
||||
20:43:20 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
|
||||
20:43:35 [1] deployed, controller state=running, pinned={'qbittorrent': 'qbittorrentofficial/qbittorrent-nox:5.2.4-1'}
|
||||
qbittorrent deployed True running
|
||||
20:43:35 [1] required fields filled beyond DOMAIN/SUBDOMAIN: ['HDD_PATH', 'TR_ADMIN_PASSWORD']
|
||||
20:43:35 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
|
||||
20:43:55 [1] deployed, controller state=running, pinned={'transmission': 'lscr.io/linuxserver/transmission:version-4.1.3-r0'}
|
||||
transmission deployed True running
|
||||
@@ -0,0 +1,2 @@
|
||||
init 200 {'data': {'phase': 'formatting', 'started': True}, 'ok': True}
|
||||
status {'data': {'device': '/dev/sdb', 'durable_id': '', 'error': '', 'opsign': '', 'phase': 'done', 'reason': '', 'started_at': '2026-10-25T19:42:47.597592227Z', 'updated_at': '2026-10-25T19:42:49.836540017Z', 'where': '/mnt/felhom-drives/adat'}, 'ok': True}
|
||||
Whitespace-only changes.
@@ -0,0 +1,163 @@
|
||||
|
||||
[0;32m[INFO][0m felhom-host-install v1.36.1 — mode=byo customer=Tester4 vmid=9201
|
||||
|
||||
[0;34m[STEP][0m 1/8 pre-flight
|
||||
[0;32m[INFO][0m pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
|
||||
[0;32m[INFO][0m node: pf-test (explicit)
|
||||
[0;32m[INFO][0m agent config: /etc/felhom-agent/agent.json
|
||||
[0;32m[INFO][0m agent: not installed yet — will be fetched + installed in step 5/8
|
||||
[0;32m[INFO][0m local-lvm free: ~10 GiB
|
||||
[1;33m[WARN][0m local-lvm free ~10 GiB is below the recommended 120 GiB — the install continues; proceed only if you sized the grows deliberately
|
||||
[0;32m[INFO][0m free RAM: ~4383 MiB
|
||||
[0;32m[INFO][0m existing guests on this host: 0 (pct+qm)
|
||||
[0;32m[INFO][0m archive storage 'local' present
|
||||
[0;32m[INFO][0m acl storages all present or pre-positioned: local local-lvm
|
||||
[0;32m[INFO][0m dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
|
||||
[0;32m[INFO][0m host DNS (:53): free
|
||||
[0;32m[INFO][0m hub reachable (https://hub.felhom.eu)
|
||||
[0;32m[OK][0m customer 'Tester4' exists + passphrase valid
|
||||
[0;32m[INFO][0m golden: none local — will fetch + verify from Gitea in step 7/8
|
||||
pf-test
|
||||
|
||||
[0;34m[STEP][0m BYO disclosure — installing Felhom on a host the operator does NOT own will create:
|
||||
pveum: roles FelhomAgentBase/FelhomAgentGuest/FelhomAgentStore + user felhom-agent@pve + token felhom-agent@pve!agent
|
||||
+ scoped ACL grants (Base@/, Guest@/pool/felhom, Store@[local local-lvm]) + the 'felhom' pool
|
||||
agent: service user felhom-agent + /usr/local/bin/felhom-agent (+ .bak-* backups; A/B slots via the guarded self-update)
|
||||
+ /etc/systemd/system/felhom-agent.service (+ felhom-agent-rollback.service + start-limit drop-in)
|
||||
+ /etc/sudoers.d/felhom-agent + state dir /var/lib/felhom-agent + config /etc/felhom-agent/agent.json (0600)
|
||||
host: /usr/local/sbin/felhom-mkfs-guarded + /usr/local/sbin/felhom-selfupdate-guarded
|
||||
+ /usr/local/sbin/felhom-pbs-apply (PBS-DR apply wrapper — DR capability is baked
|
||||
on every install; ACTIVATION stays a hub flag, off = zero effect on this host)
|
||||
+ felhom-mgmt-watchdog service+timer+script + /etc/tmpfiles.d/felhom-privsep.conf
|
||||
+ /usr/local/sbin/felhom-priv-apply + the guest-hook snippet under /var/lib/vz/snippets/
|
||||
(both from the agent's config bundle)
|
||||
+ the 'sudo' and 'age' packages if absent + install state dir /var/lib/felhom-install
|
||||
wg: an OUTBOUND WireGuard tunnel to the Felhom hub (wg_tunnel.enabled=true — base
|
||||
infrastructure like the cloudflared tunnel; hands-free peer registration; the
|
||||
operator can disable it per-customer hub-side on request)
|
||||
guest: the provisioned Felhom LXC (vmid 9201, capped 3 cores / 4096 MiB) + its volumes
|
||||
+ the golden vzdump imported onto storage 'local'
|
||||
reuse: a golden already on 'local' is used only if its sha256 or its controller version
|
||||
matches the hub's vouched golden; otherwise the vouched one is fetched (a --golden you name is refused)
|
||||
update: operator-signed self-update authority: felhom-op-1
|
||||
NOT touched in byo mode: root@pam (no break-glass), host DNS (:53), OOB sshd.
|
||||
|
||||
Type this host's short hostname (pf-test) to acknowledge the byo install: [0;32m[OK][0m byo install acknowledged for host pf-test
|
||||
[0;32m[OK][0m pre-flight passed
|
||||
[0;34m[STEP][0m 2/8 Proxmox API token
|
||||
[0;32m[OK][0m token minted (secret captured, not logged)
|
||||
[0;32m[OK][0m scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm])
|
||||
[0;36m[SKIP][0m old broad role FelhomAgent already absent
|
||||
[0;34m[STEP][0m 3/8 compute volume grows
|
||||
[0;32m[INFO][0m auto-computed from a 10 GiB thin pool (16 §7: 50/100/130 GiB)
|
||||
[0;32m[INFO][0m grows: rootfs +0G (->32G), data +26G (->50G, ONE volume)
|
||||
[0;34m[STEP][0m 4/8 host enrollment (POST /host-enroll)
|
||||
[0;32m[OK][0m host MINTED (first enroll)
|
||||
[0;32m[INFO][0m host_id: Tester4-84bbe7 (api_key captured, not logged)
|
||||
[0;36m[SKIP][0m break-glass (step 4b) SKIPPED (byo: the host owner manages break-glass; root@pam untouched, nothing vaulted)
|
||||
[0;34m[STEP][0m 5/8 agent install (fetch + verify + install)
|
||||
[0;36m[SKIP][0m apt repo alignment skipped (byo — the owner manages repos)
|
||||
[1;33m[WARN][0m no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[0;32m[INFO][0m manifest: agent v0.165.0 (sha e9d04a47ee85222c…), golden v0.331.0
|
||||
[0;32m[INFO][0m fetching agent binary v0.165.0 from Gitea …
|
||||
[0;32m[OK][0m verified sha256 e9d04a47ee85222c… matches the hub manifest
|
||||
[0;32m[OK][0m installed /usr/local/bin/felhom-agent (felhom-agent 0.165.0)
|
||||
[0;32m[INFO][0m installing the 'sudo' package (required for the non-root agent model) …
|
||||
[0;32m[OK][0m sudo installed (Sudo version 1.9.16p2)
|
||||
[0;32m[INFO][0m installing the 'age' package (escrow ceremony identity-wrap dependency) …
|
||||
[0;32m[OK][0m age installed (1.2.1)
|
||||
[0;32m[OK][0m created service user felhom-agent
|
||||
[0;32m[OK][0m added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
|
||||
[0;32m[OK][0m verified sha256 8dea1f34d77ba40a… matches the hub manifest
|
||||
os-apply: BUNDLE /etc/ssh/sshd_config.d/10-felhom-root-key-only.conf skipped: a BYO host keeps its own settings (D43)
|
||||
os-apply: BUNDLE START agent=0.165.0 sha=8dea1f34d77ba40a authority=installer files=32 write=26 same=1 kept=0 skipped=5
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-mkfs-guarded (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-selfupdate-guarded (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-pbs-apply (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-backup-target-apply (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-vzdump-partial-clean (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-thin-check (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-internal-place (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-crash-guard (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-priv-apply (new)
|
||||
os-apply: BUNDLE WROTE /var/lib/vz/snippets/felhom-guest-hook.sh (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-shared-parent.sh (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-shared-parent.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard-check.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard-check.timer (new)
|
||||
os-apply: BUNDLE WROTE /etc/felhom/crash-guard.conf (new)
|
||||
os-apply: BUNDLE WROTE /etc/grub.d/01_felhom_oneshot (new)
|
||||
os-apply: BUNDLE WROTE /etc/grub.d/42_felhom_oneshot (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent-rollback.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent.service.d/felhom-agent-limits.conf (new)
|
||||
os-apply: BUNDLE WROTE /usr/local/sbin/felhom-mgmt-watchdog (new)
|
||||
os-apply: BUNDLE WROTE /etc/tmpfiles.d/felhom-privsep.conf (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-mgmt-watchdog.service (new)
|
||||
os-apply: BUNDLE WROTE /etc/systemd/system/felhom-mgmt-watchdog.timer (new)
|
||||
os-apply: BUNDLE WROTE /etc/sudoers.d/felhom-agent (new)
|
||||
os-apply: BUNDLE DONE agent=0.165.0 written=26 same=1 self-check=ok signers-created=False
|
||||
[0;32m[OK][0m installed every root-owned file from config bundle v0.165.0 (sha 8dea1f34d77ba40a…; checked, previous copies kept)
|
||||
[0;36m[SKIP][0m OOB (felhom-sshd) off (byo, or appliance --no-oob) — the bundle skipped its files
|
||||
[0;34m[STEP][0m 5b/8 internal data place (Belső tárhely)
|
||||
[0;36m[SKIP][0m byo: the host owner's thin pool is not ours to divide — no internal place
|
||||
[0;34m[STEP][0m 6/8 agent config + service
|
||||
[1;33m[WARN][0m backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
|
||||
[1;33m[WARN][0m It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
|
||||
[0;32m[INFO][0m node=pf-test local_api=192.168.0.150:8443 tls_fp=65:D5:C9:E7:A0:4C…
|
||||
[0;32m[OK][0m wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
|
||||
[0;32m[OK][0m byo config asserts passed (lan_resolver.enable / oob.enabled off; deployment_mode=byo; wg_tunnel intentionally ON — base infrastructure)
|
||||
[0;32m[OK][0m agent --selftest (read-only) passed
|
||||
[0;32m[OK][0m felhom-agent service active (non-root felhom-agent reads the config OK)
|
||||
[0;32m[OK][0m wrote /etc/felhom/os-trust.json + operator-signers (felhom-op-1) — the root-owned slow-lane anchors
|
||||
[0;34m[STEP][0m 7/8 golden archive
|
||||
[1;33m[WARN][0m no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
|
||||
[0;32m[INFO][0m fetching golden v0.331.0 from Gitea → /var/lib/vz/dump/vzdump-lxc-9100-2026_10_25-20_25_22.tar.zst
|
||||
[0;32m[OK][0m verified sha256 3881de62b0986ccb… matches the hub manifest
|
||||
[0;32m[OK][0m golden imported + verified: local:backup/vzdump-lxc-9100-2026_10_25-20_25_22.tar.zst
|
||||
[0;34m[STEP][0m 8/8 provision guest 9201
|
||||
[0;36m[SKIP][0m pool felhom already exists
|
||||
=== felhom-agent 0.165.0 selftest=provision (vmid=9201 customer=Tester4 hostname=tester4) ===
|
||||
--- front half: bring-up (provision) local:backup/vzdump-lxc-9100-2026_10_25-20_25_22.tar.zst → vmid 9201 ---
|
||||
time=2026-10-25T20:26:42.227+01:00 level=INFO msg="bring-up: pool membership re-asserted" vmid=9201 pool=felhom
|
||||
[OK] front half: vmid 9201 up (boot+running) in 1m9s; MAC=BC:24:11:09:4B:78
|
||||
--- back half: mint per-guest token + populate bootstrap config mount ---
|
||||
time=2026-10-25T20:26:46.965+01:00 level=INFO msg="provision: back-half complete" vmid=9201 mount=mp9 guest_path=/etc/felhom-bootstrap endpoint=192.168.0.150:8443
|
||||
[OK] back half: bootstrap mount mp9 → /etc/felhom-bootstrap on vmid 9201 (host dir /var/lib/felhom-agent/guests/9201/bootstrap)
|
||||
local-api endpoint 192.168.0.150:8443 · leaf fp 2096006172416bcd1bfe974a512763dcd920be6f0c4127f9e0de83ebe83810a9 · token: minted (not printed)
|
||||
=== selftest=provision OK — guest 9201 provisioned + bootstrap-mounted (KEPT) ===
|
||||
next: reboot the guest → the golden's baked controller-bootstrap unit deploys the controller,
|
||||
which PULLS its controller.yaml from the hub (retrieval passphrase) and merges in this local_api.
|
||||
[0;32m[OK][0m provision completed
|
||||
[0;32m[INFO][0m rebooting guest 9201 so the baked controller-bootstrap unit picks up the mount
|
||||
[0;34m[STEP][0m verify
|
||||
[0;32m[OK][0m pct status: running
|
||||
[0;32m[OK][0m onboot: 1
|
||||
mp0: local-lvm:vm-9201-disk-1,mp=/var/lib/felhom,backup=1,size=50G
|
||||
mp8: /mnt/felhom-drives,mp=/mnt/felhom-drives
|
||||
rootfs: local-lvm:vm-9201-disk-0,size=32G
|
||||
[0;32m[OK][0m pool: guest 9201 is a member of felhom
|
||||
[0;32m[OK][0m acl: FelhomAgentBase@/ present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/pool/felhom present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentStore@/storage/local present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentStore@/storage/local-lvm present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990000 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990001 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990002 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990003 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990004 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990005 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990006 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990007 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990008 present (user+token)
|
||||
[0;32m[OK][0m acl: FelhomAgentGuest@/vms/990009 present (user+token)
|
||||
[0;32m[OK][0m authz signers: 2 (operator-signed self-update armed)
|
||||
[0;32m[OK][0m controller: Up 6 seconds (healthy) (after ~0s)
|
||||
[0;32m[INFO][0m controller image: gitea.dooplex.hu/admin/felhom-controller:0.343.0
|
||||
[1;33m[WARN][0m cloudflared not visible yet
|
||||
[0;32m[INFO][0m (confirm in the hub UI that host Tester4-84bbe7 reports guest 9201)
|
||||
|
||||
[0;32m[OK][0m Day-0 provision SUCCESS — vmid=9201 host_id=Tester4-84bbe7 customer=Tester4 golden=local:backup/vzdump-lxc-9100-2026_10_25-20_25_22.tar.zst
|
||||
INSTALL_RC=0
|
||||
Connection to 192.168.0.150 closed.
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
"""mktorrent.py <file> <announce-url> <out.torrent> — a single-file, PRIVATE (no DHT/PEX) v1 torrent, 4 MiB pieces.
|
||||
The night's R-1261 rig only; stdlib only."""
|
||||
import hashlib, os, sys
|
||||
|
||||
def benc(x):
|
||||
if isinstance(x, int):
|
||||
return b"i%de" % x
|
||||
if isinstance(x, bytes):
|
||||
return b"%d:%s" % (len(x), x)
|
||||
if isinstance(x, str):
|
||||
return benc(x.encode())
|
||||
if isinstance(x, list):
|
||||
return b"l" + b"".join(benc(i) for i in x) + b"e"
|
||||
if isinstance(x, dict):
|
||||
return b"d" + b"".join(benc(k) + benc(v) for k, v in sorted(x.items())) + b"e"
|
||||
raise TypeError(type(x))
|
||||
|
||||
path, announce, out = sys.argv[1:4]
|
||||
plen = 4 << 20
|
||||
pieces = []
|
||||
with open(path, "rb") as f:
|
||||
while True:
|
||||
b = f.read(plen)
|
||||
if not b:
|
||||
break
|
||||
pieces.append(hashlib.sha1(b).digest())
|
||||
info = {"name": os.path.basename(path), "length": os.path.getsize(path), "piece length": plen,
|
||||
"pieces": b"".join(pieces), "private": 1}
|
||||
open(out, "wb").write(benc({"announce": announce, "info": info, "created by": "felhom CC rig 2026-10-25"}))
|
||||
print(out, hashlib.sha1(benc(info)).hexdigest())
|
||||
@@ -0,0 +1,32 @@
|
||||
"""rigw.py — the box walk (catalog-sweep-2026-10-24/tools/box_walk.py) pointed at the night's rig: nested VM 9372 on
|
||||
demo-hp (Proxmox host 192.168.0.150, BYO install, customer Tester4), guest 9201 at 192.168.0.138, domain tester4.test.
|
||||
Import this instead of box_walk; it sets the target before box_walk reads it, then points the ssh at the rig host."""
|
||||
import os, sys
|
||||
os.environ.setdefault("TARGET", "sweep")
|
||||
os.environ.setdefault("BASE", "https://192.168.0.138")
|
||||
os.environ.setdefault("DOMAIN", "tester4.test")
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../catalog-sweep-2026-10-24/tools"))
|
||||
import box_walk as w # noqa: E402
|
||||
w._T["ssh"] = "root@192.168.0.150"
|
||||
w._T["hp"] = "rig-9372"
|
||||
|
||||
|
||||
def _login():
|
||||
"""box_walk.login, but the token is read from /settings: on this fresh box „/" redirects to /launcher, which
|
||||
carries no csrf meta (measured 2026-10-25)."""
|
||||
import re
|
||||
pw = open(f"{w.SC}/.ctlpw").read().strip()
|
||||
w.sh(["curl", "-sk", "-D", f"{w.SC}/hdr{os.getpid()}.txt", "-o", "/dev/null", "-H", w.HOSTHDR,
|
||||
"-X", "POST", "--data-urlencode", f"password={pw}", f"{w.BASE}/login"])
|
||||
m = re.search(r"felhom_session=[A-Za-z0-9._-]+", open(f"{w.SC}/hdr{os.getpid()}.txt").read(), re.I)
|
||||
if not m:
|
||||
sys.exit("login failed: no session cookie")
|
||||
open(f"{w.SC}/sess{os.getpid()}.txt", "w").write(m.group(0))
|
||||
r = w.sh(["curl", "-sk", "-H", w.HOSTHDR, "-H", f"Cookie: {m.group(0)}", f"{w.BASE}/settings"])
|
||||
c = re.search(r'<meta name="csrf-token" content="([^"]+)"', r.stdout or "")
|
||||
if not c:
|
||||
sys.exit("login failed: no csrf token on /settings")
|
||||
open(f"{w.SC}/csrf{os.getpid()}.txt", "w").write(c.group(1))
|
||||
|
||||
|
||||
w.login = _login
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
"""tracker.py [port] — a minimal HTTP BitTorrent tracker for the night's R-1261 rig (stdlib only). It records every
|
||||
peer that announces (by source address and the announced port) and answers the others in compact form."""
|
||||
import http.server, socket, struct, sys, time, urllib.parse
|
||||
|
||||
PEERS = {} # info_hash -> {(ip, port): last_seen}
|
||||
|
||||
def benc(d):
|
||||
out = b"d"
|
||||
for k in sorted(d):
|
||||
v = d[k]
|
||||
out += b"%d:%s" % (len(k), k.encode())
|
||||
out += (b"i%de" % v) if isinstance(v, int) else (b"%d:%s" % (len(v), v))
|
||||
return out + b"e"
|
||||
|
||||
class H(http.server.BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
u = urllib.parse.urlsplit(self.path)
|
||||
q = urllib.parse.parse_qs(u.query, keep_blank_values=True, encoding="latin-1")
|
||||
ih = q.get("info_hash", [""])[0].encode("latin-1")
|
||||
port = int(q.get("port", ["0"])[0] or 0)
|
||||
ip = self.client_address[0]
|
||||
now = time.time()
|
||||
peers = PEERS.setdefault(ih, {})
|
||||
if q.get("event", [""])[0] == "stopped":
|
||||
peers.pop((ip, port), None)
|
||||
else:
|
||||
peers[(ip, port)] = now
|
||||
others = [p for p, t in peers.items() if p != (ip, port) and now - t < 600]
|
||||
compact = b"".join(socket.inet_aton(a) + struct.pack(">H", pt) for a, pt in others)
|
||||
body = benc({"interval": 30, "peers": compact})
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", "text/plain")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
sys.stdout.write("%s announce %s:%d -> %d peer(s)\n" % (time.strftime("%H:%M:%S"), ip, port, len(others)))
|
||||
sys.stdout.flush()
|
||||
|
||||
def log_message(self, *a):
|
||||
pass
|
||||
|
||||
http.server.ThreadingHTTPServer(("0.0.0.0", int(sys.argv[1]) if len(sys.argv) > 1 else 6969), H).serve_forever()
|
||||
@@ -26,6 +26,13 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-25 (evening) — installer 1.36.1 published; D50 (full text of the rows: `git show b8411926:documentation/backlog/OPEN-ITEMS.md`)
|
||||
|
||||
| Row | What | Closed | Evidence |
|
||||
|---|---|---|---|
|
||||
| **R-1284** | **The installer's preflight never words a refusal: `http_code` printed the status twice („401401"), so the 401 („passphrase REJECTED"), 404 („customer not found") and 409 (R-1167's live-box sentence) branches never matched — every refusal read „unexpected hub status 401401".** (P3) | CLOSED 2026-10-25 evening — **installer 1.36.1 published on the operator's yes:** tag `installer-v1.36.1` → `79ee3e33` (CI 2336 ✓), both git-sync refs in `manifests/webpage.yaml` (`b8411926`), ArgoCD sync of `Deployment/felhom-webpage` alone; `https://felhom.eu/scripts/felhom-host-install.sh` serves `SCRIPT_VERSION="1.36.1"`, sha256 `e18cdd17…` = the tag's file. Seen live on a throwaway Proxmox VM (demo-hp VM 9372): a wrong customer id → „customer … not found in hub (404)", a wrong passphrase → „passphrase REJECTED (401)", the right passphrase on a customer with a live box → „the hub answered 409 … already has a live box" — **R-1167's sentence, which could not show before 1.36.1, now shows.** | `audits/night-2026-10-25/` |
|
||||
| **R-1290** | **The agent's CI is red since 2026-10-25 ~18:00Z: the registry no longer serves agent 0.159.0, 0.159.1, 0.159.2 and 0.160.0, while the `published` gate asserts the newest 10 released versions are downloadable (`felhom-agent/scripts/retention-policy.json`, „what the registry keeps").** (P3) | CLOSED 2026-10-25 evening — **D50 = A** (operator; `09` §3 decision 262): agent `feaaa0e` (CI 2339 ✓) — `retention-policy.json` keeps the newest 5 + `pinned` (MinAgent 0.158.1, day-0 0.165.0); `check-published-versions.py` asserts exactly those (a pin with no tag fails); three decoys, two of them LIVE HOLES on the old gate. Every artifact still named downloads (`audits/night-2026-10-25/part1-artifacts.txt`). | `audits/night-2026-10-25/` |
|
||||
|
||||
## 2026-10-25 — the attended release run (full text of the rows: R-1265, R-1266 `git show 9647f1d1:documentation/backlog/OPEN-ITEMS.md`; the release closures `git show 36ef8dcd:documentation/backlog/OPEN-ITEMS.md`)
|
||||
|
||||
| Row | What | Closed | Evidence |
|
||||
|
||||
@@ -113,7 +113,7 @@ match what the reader sees is how an instrument stops being believed (R-421). It
|
||||
**nothing was proven on the day this line was drawn** and a stopping line that moves a status is a
|
||||
stopping line that lies.
|
||||
|
||||
## Install & onboarding — 8 rows (P3 6, P4 2)
|
||||
## Install & onboarding — 7 rows (P3 5, P4 2)
|
||||
|
||||
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
@@ -123,7 +123,6 @@ stopping line that lies.
|
||||
| **R-1273** | Install & onboarding | P3 | **An install that fails on the image registry's rate limit tells the household only „exit code 1”.** Catalog sweep 2026-10-24, code-server 16:01:37: `lscr.io … toomanyrequests` → the product cleaned up right (R-649) but the event and the card say „Alkalmazás telepítése nem sikerült: Code-Server — exit code 1”; nothing says the download server is busy and a later try works. The same install went through later (`audits/catalog-sweep-2026-10-24/code-server/`). | OPEN | — | Recognise `toomanyrequests` (and a pull timeout) in the deploy error and say „the app's download server is busy — try again in an hour”; a test with the stderr line | CC |
|
||||
| **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 |
|
||||
| **R-1284** | Install & onboarding | P3 | **The installer's preflight never words a refusal: `http_code` printed the status twice („401401"), so the 401 („passphrase REJECTED"), 404 („customer not found") and 409 (R-1167's live-box sentence) branches never matched — every refusal read „unexpected hub status 401401".** Seen live 2026-10-25 on the BYO test VM (attended release run) with installer 1.36.0: a wrong id read `404404`, a wrong passphrase `401401`. R-1167 was CLOSED 2026-10-20 on a publish whose 409 sentence could not show. With `-f`, curl prints `-w` and exits 22 on a 4xx, and the fallback curl printed the code again (line 1833 already worked around it by keeping the last 3 characters). | OPEN — **fixed on main, NOT published:** installer 1.36.1 (`http_code`: one curl without `-f`, never failing); `test_http_code_prints_one_status_on_a_refusal`, seen failing on the old helper (`audits/release-2026-10-26/redproof/installer-http-code-doubled.txt`). | the publish is a DooPlex change (tag + webpage git-sync pins + the webpage sync) — the operator's | publish installer 1.36.1 (cut `installer-v1.36.1`, bump both `--ref` in `manifests/webpage.yaml`, sync the webpage alone); then a preflight with a wrong passphrase reads „passphrase REJECTED (401)"; then close | operator |
|
||||
|
||||
## Apps & catalog — 16 rows (P3 6, P4 10)
|
||||
|
||||
@@ -353,7 +352,7 @@ 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 — 33 rows (P3 8, P4 25)
|
||||
## Process & tooling — 32 rows (P3 7, P4 25)
|
||||
|
||||
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
@@ -389,7 +388,6 @@ stopping line that lies.
|
||||
| **R-1236** | Process & tooling | P3 | **Gitea (the code and the registry) is OOM-killed at its 1 GiB limit — 4 restarts in 17 days, the last at 06:41:10 UTC on 2026-10-23, six seconds after the global floor moved three boxes to a new controller image.** Read 2026-10-23 (`kubectl get pod`: `lastState.terminated.reason OOMKilled`, exit 137; kernel: „git invoked oom-killer”; limit `memory: 1Gi`, request 256Mi; 620 Mi in use at rest). During a restart a box update, an agent package fetch, a CI clone or a push fails. Not changed: DooPlex's configuration is the operator's. | OPEN | the operator's yes (a DooPlex change) | Operator: raise the limit (e.g. 2 GiB; DooPlex has the RAM) — CC's pick; or keep it and accept a restart in release hours | operator |
|
||||
| **R-1264** | Process & tooling | P4 | **Skills tooling (review round 2, DOC-B U7/S22):** the grandfathered skill has no size cap — felhom-build-deploy is 240 lines while R-394 recorded 179 (`scripts/check_skills.py:45-47,98-101`); a NEW skill folder (`skills/felhom-web-design`) is not live until `install_skills.py` runs again (not run: no DooPlex change in this unattended run). | OPEN | — | cap the grandfathered entry at its current size; run install_skills.py in an attended session | CC |
|
||||
| **R-1277** | Process & tooling | P4 | **The catalog's box fixtures drifted from the apps they test** — fixed only in the sweep's copy (`audits/catalog-sweep-2026-10-24/tools/upgrade_fixtures_box.py`, marked SWEEP COPY): OpenGist 1.15 signs up at `/-/register`; Calibre-Web's admin is the generated ADMIN_USER; Mealie's after_install replaces the factory password (the seed raced it); Papra 26.6 needs an Origin header; Rallly 4.15 closed password sign-up (no fixture possible by password); Vaultwarden 1.37.4 answers 404 on `POST /identity/accounts/register` (the fixture was written on 1.36; the admin invite works, the invited sign-up has no route — the newer clients' register/finish flow);the read-back through a family gate needs a fresh cookie after the setup gate opens (Grimmory stayed inconclusive). New fixtures for Homebox, Immich, Komga, Jellyfin, Ghost, Radarr, Sonarr in `tools/sweep_fixtures.py`; `box_walk.py` gained a `sweep` target. | OPEN | — | Port them into `app-catalog-felhom.eu/scripts/` with the bench tests | CC |
|
||||
| **R-1290** | Process & tooling | P3 | **The agent's CI is red since 2026-10-25 ~18:00Z: the registry no longer serves agent 0.159.0, 0.159.1, 0.159.2 and 0.160.0, while the `published` gate asserts the newest 10 released versions are downloadable (`felhom-agent/scripts/retention-policy.json`, „what the registry keeps").** Measured 2026-10-25 (attended release run): CI job 2326 (`4697f8a`, after the 0.165.0 upload) green; job 2334 (`6b6ba0c`, docs only) red on those four (HTTP 404); the registry lists 7 versions — 0.158.1, 0.161.0–0.165.0 and a test build `0.163.0-step1`. Our scripts delete only the version they re-upload (`publish-agent.sh:77`), so the prune is outside the repos (a Gitea package clean-up rule or a hand prune on DooPlex — not CC's to change). No box needs those versions (all run 0.165.0; MinAgent 0.158.1 is served), but every agent push now mails a CI failure and hides a real one. | OPEN | the operator (DooPlex's Gitea) | the operator: name what pruned on 2026-10-25 and its keep rule; then CC sets `generic_versions_kept` to that rule (or bounds the gate on the hub's MinAgent, R-287's follow-up) in one commit, and CI is green again by hash | operator |
|
||||
|
||||
<!-- 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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## 2026-10-25 — installer 1.36.1: the preflight words a refusal again (committed, NOT published)
|
||||
## 2026-10-25 — installer 1.36.1: the preflight words a refusal again — PUBLISHED 2026-10-25 evening on the operator's yes (`installer-v1.36.1` → `79ee3e33`, served sha256 `e18cdd17…`; the three refusal sentences seen live)
|
||||
|
||||
- **`felhom-host-install.sh` `http_code`** printed the status twice on a 4xx (`curl -f` prints `-w` and exits 22, and the
|
||||
`|| curl …` fallback printed it again: „401401"), so the preflight's 401 („passphrase REJECTED"), 404 („customer not
|
||||
|
||||
@@ -99,6 +99,9 @@ Runs as the NON-ROOT `felhom-agent` user: `/usr/local/bin/felhom-agent --config
|
||||
> `configs/` changed also `-op agent_config_update -agent-version <ver> -bundle-sha256 <bundle sha>` (root files ride
|
||||
> only the signed bundle). Picked up in 4–15 min; observables: `signedjobs: signed op COMPLETED`, `selfupdate: update
|
||||
> committed`, `osupdate: config bundle INSTALLED` + the capability probe. Measured on three boxes 2026-10-13.
|
||||
> **After the operator's vouch (or a floor that declares a new MinAgent):** set `pinned.day0_agent` (or
|
||||
> `pinned.hub_min_agent`) in `felhom-agent/scripts/retention-policy.json` in the same session — the agent CI asserts the
|
||||
> newest 5 versions plus those two pins, because it cannot read the hub (D50 = A, `09` §3 decision 262, R-1290).
|
||||
|
||||
```bash
|
||||
# build LOCALLY (pull first!)
|
||||
|
||||
Reference in new issue
Block a user