diff --git a/REPORT.md b/REPORT.md index 8292e48..db5715f 100644 --- a/REPORT.md +++ b/REPORT.md @@ -2,203 +2,167 @@ > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). -## Pre-travel train — R-39 heal · scripts v1.21.0 + ISOs · nav polish · (golden deferred) — 2026-07-18 +## Website refresh before the Facebook tester-recruitment post — 2026-07-18 -**Commits (this repo):** `bcdb042` scripts v1.21.0 · ROADMAP touch (R-39 diagnosis + R-33 collapse). -**Sibling commits:** `felhom-agent` `9596d5a` (v0.90.1) + `f22f70c` (report) · `felhom-controller` -`24d23b8` (v0.146.0) + `fd93020` (accordion tests). - -**Phases 1–3 shipped. Phase 4 skipped cleanly (its own "time-permitting"). Phase 5 (golden 0.146.0 -+ publish) NOT started — see the closing section.** +**Scope:** `website/` only · **Commits:** `be2fc50`, `d2fd935` (pushed to `main`, live via git-sync) +· **Source of truth for every claim:** `documentation/architecture/00-capability-map.md` (verified +2026-07-16, plus the 2026-07-18 N100 rehearsal rows). --- -## Phase 1 — R-39: diagnosis, and the brief's hypothesis refuted +### 1. Audit table — every factual claim, verdict, map row -**The conditional hub fix was NOT shipped, because its condition proved false.** The brief said to -ship a generation-bump fix "only if step 1–2 pin the mechanism to *re-mint fails to bump the -generation*". It does not: +Map references are section letters from the capability map. "—" = no map row exists, which is +itself the finding. -- `store.SetHostDesired` bumps `desired_generation` **unconditionally** — it went **2 → 3** on the - re-issue. -- `web/configs.go`'s `applyPBSDR` is **exonerated**: its "idempotent … no re-key, no second secret, - no spurious generation bump" comment at ~L618 is accurate and guarded by the - `cur != nil && cur.Namespace != ""` early return. The hub log shows mint #2 came from the - **re-issue** path, not from an Edit-tab Save. The comment-vs-behaviour contradiction the brief - expected does not exist. +#### index.html -**The real mechanism is a signal mismatch between two tiers.** The hub's re-consume signal is *a -generation bump + a poke*. The agent's re-apply trigger is *a change in the descriptor content hash* -(`felhom-agent internal/pbsdr/manager.go` ~L235): +| # | Claim (before) | Verdict | Map row / evidence | +|---|---|---|---| +| 1 | „45+ alkalmazás" | **FIX → 53** | §B *Deploy an app from the catalog* PROVEN-LIVE; real count = 53 `*.felhom.yml` in `app-catalog-felhom.eu/templates/` | +| 2 | „Felhő Felügyelő" (tech tile) | **FIX → „Vezérlőpult"** | Naming ruling; controller login page + R-11 draft both say vezérlőpult | +| 3 | „Kubernetes / Üzleti szintű rendelkezésre állás" tile | **CUT** | — (no customer-facing k8s row; also a bare availability promise) | +| 4 | og:image → `/assets/og-image.png` | **FIX (was a 404)** | File never existed; only `.svg` did. Generated 1200×630 | +| 5 | og:title / og:description (generic pitch) | **FIX** | Rewritten to one honest map-traceable sentence | +| 6 | Hero CTA „Érdekel →" | **FIX** | Retargeted to `#zart-teszt` (the post's landing intent) | +| 7 | Fényképek / dokumentumok / média a saját gépeden | **ADD** | §E Phone photo backup PROVEN-LIVE (6D); §E Documents/OCR PROVEN-LIVE (CAMPAIGN-6C 4P-1) | +| 8 | Hálózati megosztás — Windows Intéző + Mac Finder | **ADD** | §E *Files from Windows Explorer / Mac Finder (SMB server)* **PROVEN-LIVE**; Explorer leg passed 2026-07-18 | +| 9 | Kétszintű automatikus mentés (helyi + titkosított távoli) | **ADD** | §C Tier-2 PROVEN-LIVE (CAMPAIGN-6E P-TIER2); §C Offsite restic PROVEN-LIVE (6D); shares ride both tiers (R-7b, ctrl 0.145.0) | +| 10 | Helyreállítási kód, amit csak az ügyfél ismer | **ADD** | §A *Escrow ceremony … operator zero-knowledge* **PROVEN-LIVE**; wizard first live firing 2026-07-18 | +| 11 | Távoli felügyelet + automatikus frissítés | **ADD** | §G Controller self-update PROVEN-LIVE (demo); §G Publish train floor lift proven on a fresh install (5 s, unattended); §F metrics/monitoring IMPLEMENTED | +| 12 | Internetkimaradáskor a LAN-on minden működik | **ADD (plain wording)** | §E *LAN access when internet is down* **IMPLEMENTED** — allowed as a feature per the governing rule. **Caveat in §5.** | +| 13 | Visszaállítás, ha baj van | **ADD** | §C Offsite restore PROVEN-LIVE (6D); §C Guest-loss DR PBS restore PROVEN-LIVE (CAMPAIGN-2 T-P9) | +| 14 | „Zárt teszt" section + limitations + CTA | **ADD** | See §2 | -```go -if mk := m.loadMarker(); mk != nil && mk.Hash == h && (cf == nil || cf.Hash != h) { - return // idempotent: this exact descriptor already converged -} -``` +#### technologiak.html -An ep0 credential re-issue re-keys the **secret of an existing token**, so `token_id` and -`fingerprint` never change and the descriptor stays **byte-identical** — only the side-table -`host_pbs_secrets` row rotates. Same hash → converged agent short-circuits → the fresh secret is -never consumed → the box keeps presenting a revoked credential → **401 forever**. Proof in one line: -`consumed-failed.json` carries hash `a4e5424…`, **identical** to the `marker.json` written two -minutes before the re-issue. The comment at `hub/internal/web/pbsdr.go:320` asserts the reissue -refreshes the descriptor "with the NEW token_id/fingerprint" — false for this op. +| # | Claim (before) | Verdict | Map row | +|---|---|---|---| +| 15 | „Felhő Felügyelő" ×14 (title, meta desc, keywords, og+twitter desc, JSON-LD, TOC, h2, h3, body, stack layer, hedge ×2) | **FIX → vezérlőpult** | Naming ruling | +| 16 | „45+ app telepíthető" | **FIX → 53** | §B | +| 17 | **Whole Kubernetes section** (h2, „Mi az a Kubernetes?", „Mikor érdemes", k3s vs full-k8s cards) + TOC entry + multi-node hardware tier | **CUT** | — No customer-facing k8s/k3s row exists. k3s is *hub* (operator) infra, not the customer box. Also carried „a szolgáltatás nem állhat le" = an availability promise the task forbids | +| 18 | „Tailscale VPN – biztonságos távoli elérés" | **FIX → WireGuard** | §E *WireGuard base infra always-on* IMPLEMENTED; §E remote access = Cloudflare Tunnel + Traefik PROVEN-LIVE. Tailscale is not what ships | +| 19 | „RAID – adatvédelem" card | **FIX → kétszintű mentés card** | — No RAID row. Shipped model is §C tier-2 second drive + encrypted offsite. Kept the „több lemez ≠ mentés" education | +| 20 | Spec row „4-8 TB (RAID)" | **FIX → „4-8 TB"** | — | +| 21 | „Melyiket válaszd?" referencing the removed multi-node fürt | **FIX** | Consistency with #17 | +| 22 | Hardware price ranges (80k–600k Ft) | **KEEP** | Hardware cost guidance, not a service price or product claim; no map conflict. Flagged in §5 | +| 23 | Docker / Proxmox / reverse proxy / Traefik / UFW | **KEEP** | §E Remote access PROVEN-LIVE; Proxmox is the platform per `proxmox-platform.md` | -**Timeline (hub log is CEST; the hub DB is UTC — a split *within one service*):** +#### gyik.html -| CEST | Event | +| # | Claim (before) | Verdict | Map row | +|---|---|---|---| +| 24 | „Minden családtag saját fiókot kap, saját bejelentkezéssel" | **FIX (both JSON-LD + visible copies)** | §E *Multiple household users / per-person accounts* = **MISSING** (R-15). Now: apps do have per-person accounts; the **vezérlőpult has one shared household password** | +| 25 | „Nagyobb rendszereknél RAID konfiguráció **is alkalmazható**" | **KEEP** | Already conditional/on-request; not presented as a shipped product capability | +| 26 | „Jellyfin/Plex — saját Netflix" | **KEEP** | §B catalog deploy PROVEN-LIVE; browser/mobile playback is the app's own function. TV casting handled honestly in the tester block (#14) | +| 27 | Remote access, 3-2-1 backups, updates, power-on-after-outage | **KEEP** | §E, §C, §G rows all IMPLEMENTED or PROVEN-LIVE | + +#### biztonsagimentes.html + +| # | Claim (before) | Verdict | Map row | +|---|---|---|---| +| 28 | „…**azonnal** értesítést kapsz, és mi is" | **FIX** | §F *Health-degradation email* = **IMPLEMENTED**, and the map states this trigger "has never fired an email live in any doc". Softened, plus a line that the closed test is partly to harden this | +| 29 | Helyreállítási kód / zero-knowledge | **ADD** | §A escrow PROVEN-LIVE. States both sides: nobody else can read it, and without the code neither can we | +| 30 | „az egész rendszered … egy új gépre is visszaállítható" | **KEEP** | §C Guest-loss DR PROVEN-LIVE (CAMPAIGN-2 T-P9-DESTROY-RESTORE) | +| 31 | 3-2-1 rule, incremental, scheduled | **KEEP** | §C nightly dumps + tier-2 + offsite, all PROVEN-LIVE | + +#### alkalmazasok.html / kapcsolat.html + +| # | Claim (before) | Verdict | Map row | +|---|---|---|---| +| 32 | „45+" ×4 (title, meta desc, og:title, twitter:title) | **FIX → 53** | §B. Page renders 49 cards; catalog holds 53 templates | +| 33 | Contact form → `POST /api/contact` with a stale "TODO: never wired" comment | **KEEP — verified LIVE** | Probed this session: `200 {"message":"Üzeneted sikeresen elküldtük!…"}`. Backend is `manifests/contact-mailer.yaml`. No new backend built | +| 34 | Subject options | **ADD** | New „Zárt teszt — jelentkezem tesztelőnek" → mail subject `Jelentkezés — zárt teszt` | + +--- + +### 2. The „Zárt teszt" section (the post's landing target) + +Three cards + CTA: +- **Valódi használat** — the box stays with them, real data, we help with install and migration. +- **Visszajelzés** — what we want back; "I couldn't find this button" is the most valuable report. +- **Ismert korlátok** — stated plainly: **one shared household password** for the vezérlőpult + (§E multi-user MISSING, R-15); **TV-re streamelés hamarosan** (§E DLNA **MISSING**, R-6/R-8); + and "this is a test, expect to find bugs — that's the point". + +**CTA wiring:** the audit found the existing contact-mailer live, so per the task the CTA reuses it +— `/kapcsolat?tema=zart-teszt`, which preselects the new subject option (unknown `?tema=` values are +ignored with a console warning). **No mailto fallback needed, no new backend.** + +--- + +### 3. Files changed + +| File | Change | |---|---| -| 18:30:51 | `pbsdr provisioned … gen 2; secret stored consume-once` — mint #1, via the WG-registration hook, **with** a generation bump | -| 18:45:51 | agent consumes mint #1 → `converged state=applied` | -| 18:47:52 | `pbsdr credentials **re-issued** … fresh consume-once secret stored` — mint #2, `consumed_at` stayed NULL | +| `website/index.html` | meta desc, og/twitter block (+width/height/alt), hero CTA, **new „Mit tud a doboz ma?" (8 cards)**, **new „Zárt teszt" section**, 45+→53, 2 tiles retitled | +| `website/technologiak.html` | 14× naming fix, 45+→53, **Kubernetes section + TOC + multi-node tier CUT**, Tailscale→WireGuard, RAID card→two-tier backup, spec row | +| `website/gyik.html` | multi-user answer rewritten in **both** the JSON-LD and the visible accordion | +| `website/biztonsagimentes.html` | new recovery-code block; notification overclaim softened | +| `website/alkalmazasok.html` | 45+→53 ×4 (head only) | +| `website/kapcsolat.html` | new subject option + label mapping + `?tema=` preselect | +| `website/assets/og-image.png` | **NEW** — branded 1200×630 card, generated from the existing logo + v2 tokens via headless Chrome (real brand font, no external assets) | +| `website/CHANGELOG.md` | entry on top | -**A second, independent defect, found while healing.** `configs/felhom-pbs-apply`'s `reconcile` -passed `--server` to `pvesm set`; PVE treats `server` as **create-only** and rejects the whole call -even when the value is byte-identical. So *every* re-apply exited 255 — and because the agent -consumes the one-time secret **before** invoking the wrapper, each re-issue **burned a credential**. -Proven live before writing code: with `--server` → rejected; without → **rc 0**. Fixed in **agent -v0.90.1** (one argv line + red-proof `TestReconcileNeverPassesServerToPvesmSet`, verified red then -green; it handles two vacuous-pass traps — CRLF line endings, and the WHY comment quoting the very -flag under test). - -**Cost I incurred:** proving the mechanism consumed the pending secret against the still-unfixed -wrapper, so it burned. The box was already 401 before and after — no functional regression — but the -recoverable state was gone until an operator re-issue. The agent parked correctly in -`consumed-failed.json` with `NOT retrying silently`: **no burn loop**, the fail-safe worked. - -**HEALED — Viktor's re-issue click closed the chain in 9 s:** hub re-issued 20:28:44 → agent -consumed 20:28:51 → `converged state=applied` 20:28:53, with the patched wrapper. - -| Check | Before | After | -|---|---|---| -| `pvesm status` | `401 Unauthorized` / `inactive` | **`active`** | -| Direct token probe `/api2/json/version` | `401` | **`200`** | -| Real backup | none possible | **`felhom-pbs:backup/ct/9201/2026-07-18T18:31:06Z`, 9 744 319 312 B, 13m36s** | - -Encrypted under fingerprint `7e:a6:af:f7:ea:6d:3e:d9` — the **escrowed** key, the one customer zero -holds the recovery code for. The DR tier's **first real backup on the reborn box**. Nothing was -destroyed: `.pw`, `.enc` (K) and the `storage.cfg` entry verified intact (PVE rejects atomically, so -the set-only law held). - -**Left for the fleet spec, deliberately not improvised:** (a) make a fresh unconsumed secret actually -un-converge the agent; (b) fix the verify loop's read path — it reads `/etc/pve/priv/storage/.pw` -directly as non-root, a file it can only ever *write* through the root wrapper (`/etc/pve/priv` is -`0700 root:www-data`; sudoers exposes `create|reconcile|grant`, **no read verb**); (c) an auth probe -so `applied` can never mean `401`. +**No CSS, nav, footer, or design changes.** All new markup reuses existing classes +(`.why-grid`, `.why-card`, `.apps-cta`, `.cta-button`) and the existing icon sprite. --- -## Phase 2 — scripts v1.21.0 + fresh ISOs +### 4. Deploy verification (fetched from the live site) -`run_pairing()` now loops **inside** the script (30s sleep — hub-side rate unchanged) instead of -exiting non-zero per poll, so the unit sits in `activating` and systemd prints nothing on the -customer's console. Registration split into `register_appliance()` whose transient failures the loop -retries. Journal quiet but not dark: logged once on entry, then a 10-minute heartbeat; `410` still -exits non-zero on purpose. Console banner every 5 min, single accented spelling, plus the missing -reassurance („Ez a képernyő magától frissül"). +- Commits `be2fc50` + `d2fd935` pushed to `main`; git-sync deployed in ~20 s and ~45 s. +- **og tags live on `/`** — `og:title`, `og:description` (honest one-liner), `og:image`, + `og:image:width/height/alt`, `og:locale hu_HU`, `og:site_name`, `twitter:card + summary_large_image`, `twitter:title/description/image`. All verified by `curl`. +- **`og:image` no longer 404s** — `HTTP=200 content-type=image/png bytes=167598`, PNG signature + valid, **dimensions 1200×630** confirmed from the live bytes. +- **Site-wide sweep across all 6 public pages:** `Felhő Felügyelő = 0`, `k3s|kubernetes = 0`, + `45+ = 0`, og-image `200`. +- New sections live: `id="mit-tud"`, `id="zart-teszt"`, `/kapcsolat?tema=zart-teszt`, + `53`, „Hálózati megosztás", „TV-re streamelés hamarosan". +- `/kapcsolat` serves `value="zart-teszt">Zárt teszt — jelentkezem tesztelőnek<`. +- **Gates:** `python scripts/site_gates.py` green (BOM, emoji=0, nav/footer identical, analytics, + no CDN, no legacy tokens, no `