Commit Graph

1281 Commits

Author SHA1 Message Date
admin db52f5a4cf v0.315.0: close the log tab's <script> — the live poller was dead, and a test now says so
gates / gates (push) Failing after 49s
FOUND IN A BROWSER. The log tab's body was lifted out of the old logs.html by line range and the
range stopped one line short, so the closing </script> never came with it. Everything downstream
agreed the page was fine:

  - html/template parsed it,
  - the page rendered and looked right,
  - TestAppPage_EachTabRendersItsOwnContent found `setInterval(window.fetchLogs` exactly where it
    expected it, because the TEXT was there.

Chrome refused the whole block with "SyntaxError: Unexpected token '<'" at the `</div>` that
followed, so the live log never refreshed. A marker proves a string is present; it does not prove
the browser will execute it.

TestAppPage_ScriptTagsAreBalanced now counts <script> against </script> on all seven app-page URLs
and checks the last block is closed. Red-proved by removing the tag again: it fails naming the logs
tab, 3 opened and 2 closed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
2026-10-15 19:27:21 +02:00
admin fe0228c877 v0.315.0: style the app page's tab bar, and reuse the hero classes that already have rules
gates / gates (push) Failing after 46s
FOUND IN A BROWSER, and findable no other way. Every endpoint-level marker passed and the page was
unusable: the tab bar rendered as four bare underlined links run together, and the app logo filled a
third of the screen. The shell had been written with new class names — app-hero, app-hero-logo,
app-tabs — and only the first two of those had any CSS at all, under the names the design system
already uses.

  - the shell now reuses .app-info-hero / .app-info-logo / .app-info-hero-text, which carry the
    80px logo box, the hairline border and the 2px radius. Inventing a parallel name is what left
    the logo unsized; REUSE.md's first rule, learned again.
  - .app-tabs / .app-tab / .app-tab-active are genuinely new and are now styled to design system
    v2: 2px radius, hairline --line border, no shadow, --text-2 for an inactive tab and
    --blue-bright only for the one the household is on (blue marks where you are, not a deviation),
    the active tab sitting on the bar's own line, and a narrower gutter under 640px.
  - .after-start-card gets a blue left hairline — it is a request, not a fault, so no amber.
  - .app-faq gets its dt/dd rules.

TestAppPage_DeployedDefaultsToSettings sliced the header at `class="app-hero"`; it now slices at the
reused class and fails loudly if either marker is gone, instead of slicing on -1. The 36 app-page
parity fixtures are recaptured — and no other fixture moved, which is the evidence that the shell
change reaches only the app page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
2026-10-15 19:04:57 +02:00
admin e66d4669d6 v0.315.0: one app page with four tabs; the guide the catalog can carry; no Raspberry Pi badge
gates / gates (push) Failing after 47s
An app was six pages — details, install/settings, logs, export, the per-app backup panel and a
details card for moving data — and every "Vissza" on them went to the app LIST, so there was no way
back to the app you were looking at. It is now ONE page with four tab URLs under /apps/{slug}/,
one shared header and one set of banners.

  settings  Mukodes (Start/Restart/Stop, Stop confirms) + the cards that want something from the
            household + the install-time and optional settings. The default for an installed app,
            RENDERED at the bare URL and never redirected to.
  data      the data folders, move to another drive, the nightly copy, the 2nd-copy setting, export
  guide     tagline, screenshots, use cases, first steps, the catalog's guide, the FAQ, the docs
            link — and the WHOLE page for an app that is not installed
  logs      the log, and the only tab whose poller runs

The tabs are links, not panels: a link in an alert has to land ON a tab, and the log poller must not
run on the other three. Start/Restart/Stop left the page header, where they read as menu buttons.

The old /stacks/{name}/{deploy,logs,export,backup} GETs answer 302 — never 301, which a browser
caches beyond anyone's reach — to the tab that now holds them, query string carried through, with
name->slug resolved through the stack list rather than assumed equal. Every POST on those paths is
untouched: the backup form, the app-email toggle and the reveal endpoints keep their URLs.

A value asked AFTER the app starts is now generic (D2). The catalog marks a field `after_start: true`
and supplies its label; the ACTION is Go, in a registry keyed by slug + env var. The catalog can
never declare what runs — a declared field with no registered action renders nothing, POSTs 404 and
logs one WARN with the env var KEY, never the value. A red-proof found the second half of that guard
unpinned: deleting the "the catalog must have DECLARED this field" check left the suite green, and a
POST for an undeclared field then reached Plex and opened the setup gate.
TestAfterStart_RegistryAloneIsNotAnInvitation pins it.

New catalog block app_info.guide (sections + faq + checked_version), parsed, localised field by
field and rendered with the household's own address filled in. It renders only when checked_version
names the image tag its author clicked through. No template carries one yet.

The Pi and "csak x86" badges are gone; PiCompatible and the catalog key stay this release, or a box
on 0.314.0 would read "csak x86" on every app (R-1067).

template_id_gate.py now follows {{template}} includes, with a scope decoy proving the walk did not
become vacuous.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
2026-10-15 18:37:50 +02:00
admin 85f65c70d8 v0.314.0: CONTEXT and REPORT after the release (floor 0.314.0 raised by CC's token at 13:11 UTC)
gates / gates (push) Successful in 46s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 15:17:51 +02:00
admin 97c992ad44 v0.314.0: the R-1060 web test (a fake Plex that refuses the name „plex”), left out of 17863fe
gates / gates (push) Successful in 47s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 14:34:46 +02:00
admin 17863fe8bc v0.314.0: a restore puts the setup gate back as it was (R-1057); a test build moves with the floor (R-1053); Prowlarr links itself (R-1058); the box claims Plex by address (R-1060)
gates / gates (push) Successful in 47s
MinAgent 0.155.0 (unchanged). Tests red-proved by mutation (A: 10, B: 7, C: 1, C2: 2).

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 14:34:33 +02:00
admin e209a8d724 Rule file: a release needs no golden; the floor carries it after the three test boxes; golden weekly (09 §3 decision 250, operator 2026-10-15)
gates / gates (push) Successful in 44s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 11:43:16 +02:00
admin cac92a407e v0.313.0: media apps on every drive, drive events, a real restart, Plex without the race — release notes (MinAgent 0.155.0); golden next (bake → vouch → floor)
gates / gates (push) Successful in 44s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 10:48:58 +02:00
admin f327bc53a9 after_start deploy fields: asked after the start by this controller, still required for older ones (R-1028/R-1045, security review of catalog 0188430)
gates / gates (push) Successful in 47s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 10:32:51 +02:00
admin 372d6e5994 Plex (R-1045): the controller asks Plex itself whether it is claimed — after the claim and on the household's „Kész”; no template probe (an older controller would refuse the press forever)
gates / gates (push) Successful in 45s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 10:29:47 +02:00
admin 37ffa3beb5 Safe removal (R-1044), found on Tester 1 G4: the drive gate leaves a safely removed drive alone (no false RETURNED/ABSENT, no mail); presence = backing device, not the agent's state
gates / gates (push) Successful in 46s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 10:25:08 +02:00
admin a09cab124a mediawire: qBittorrent 5 answers a good login with 204 — accept it (found on Tester 1, Part G1); fake answers 204 like the app
gates / gates (push) Successful in 41s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 10:02:26 +02:00
admin f580d88a14 Media build part 2 (unreleased): drive wiring in every app (R-1024/R-1037), old-install repair (R-1047), drive events notice + real restart now/later + stream check, file browser lets go of dead/removed drives and recreates on return (R-1038), safe removal keeps the drive (R-1044), Plex claim on the running server + probe accept (R-1028/R-1045)
gates / gates (push) Successful in 45s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 09:54:49 +02:00
admin 78c894234c Media build part 1 (unreleased): real restart (R-1026), media apps on every PRESENT drive via an owned compose override (R-1023), dead-drive check from mountinfo, removal never deletes shared/:ro binds (R-1027), safety list knows userdata (R-1032), no drive question for media apps (R-1031)
gates / gates (push) Successful in 46s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 09:25:43 +02:00
admin 331be17e1e Rule file: bake first — bake → vouch → floor, never a floor with no golden (09 §3 decision 247, operator 2026-10-15)
gates / gates (push) Successful in 49s
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-15 08:18:12 +02:00
admin 8bc7ec54cd v0.312.0: every public name answers only over https; HSTS one day (R-1033, P1)
gates / gates (push) Successful in 48s
forwarded.yml: felhom-forwarded is now a chain [felhom-https-only (redirectScheme https, 301 when the trusted tunnel
says X-Forwarded-Proto: http), felhom-forwarded-headers (the clean-up + HSTS 86400, no subdomains, no preload)] plus a
priority-1 catch-all router for unknown names over http. traefik.yml unchanged; hot-loaded.
Tests red-proofed. Evidence: felhom.eu documentation/audits/https-only-2026-10-14/.
2026-10-14 22:39:58 +02:00
admin 9b95e8e09b REPORT: R-1007 — the repair after an unclean boot, proven live on demo-hp
gates / gates (push) Successful in 42s
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-14 17:52:20 +02:00
admin 3b85a0c29a v0.311.0 (before the build): the repair's commands run quietly — no household file name can reach a log or the operator event
gates / gates (push) Successful in 50s
Security review of 8d862e4: compose's shared runner logs a failed command's stdout and puts its
stderr in the error, and that error became the event's `problem`. The after_unclean_boot commands now
run through a quiet runner (nothing logged, stderr discarded) and `problem` keeps the exit code only.
TestAUB_AFailingCommandLeaksNoOutput, red-proofed.

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-14 16:58:20 +02:00
admin 8d862e4e69 v0.311.0: after a power cut, an app repairs the files the cut left empty; the household sees lost photos (R-1007)
gates / gates (push) Successful in 52s
New template block after_unclean_boot (decision 236): once per controller start that followed an
UNCLEAN host boot (crashboot's own verdict, after the 15-minute crash grace; a normal or unknown boot
never runs it), each app with the block rebuilds ONLY its zero-byte files (scan: regular files, no
symlinks, its own filesystem; ids appended to the app's own command in batches; one retry, then
reported) and its own lost-file check is read. The household sees lost files (name, date taken) on
the app page until dismissed; the operator gets app_repaired_after_crash with counts only. Skips,
with the reason, an unproven image, an unknown key, an app not running. MinAgent 0.155.0 unchanged.
Tests red-proofed (14 guards). One new parity fixture (the new card only).

Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-14 16:47:13 +02:00
admin acbbf4b305 REPORT: the machine came back by its power button; the hub ended the hold (R-998 live proof complete)
gates / gates (push) Successful in 49s
2026-10-14 00:05:58 +02:00
admin e24430cce5 REPORT: power-off (R-998) released and proven on the N100
gates / gates (push) Successful in 48s
2026-10-13 21:41:33 +02:00
admin 201f936e9a v0.310.0: „A gép kikapcsolása" — the household turns the whole machine off (R-998); honest restart text (R-999)
gates / gates (push) Successful in 48s
POST /api/server/poweroff (dashboard login, POST only, the typed word KIKAPCSOLÁS / TURN OFF)
→ agent POST /host/poweroff (MinAgent 0.155.0; hidden for an older agent). The controller refuses
during its own backup/restore/app update; the agent's reasons are shown as household sentences.
„Kiszolgáló újraindítása" becomes „A Felhom újraindítása" and says it restarts the Felhom part;
/api/server/reboot is POST only (R-983). Tests red-proofed; parity fixtures regenerated on purpose.
2026-10-13 20:17:30 +02:00
admin 1b2f74c52f v0.309.0: the default list completes groups 1 and 3 for households with no saved list (operator Q1); REPORT
gates / gates (push) Successful in 46s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 17:25:12 +02:00
admin 7626a28de3 v0.309.0: the fill warning reaches the household in its own language; the root-filesystem disk event pinned end to end (R-521 F7)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 17:11:53 +02:00
admin 402fa41e45 v0.309.0: re-capture the two notification-page parity fixtures; capture settings_notifications_groups_custom (R-388 slice 1)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 16:50:42 +02:00
admin 462196e29b v0.309.0: the notification page shows three group switches; details and cooldown under Részletek (R-388 slice 1, decision 200)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 16:50:41 +02:00
admin 68294ecb6f REPORT: v0.308.0 (the operator's answers, 2026-10-12)
gates / gates (push) Successful in 44s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 15:42:31 +02:00
admin faef8f8a91 v0.308.0 (R-554, held-back-able): recovery-info.txt points at the dashboard's Restore page and the recovery code; the first-boot setup wizard is deleted
Operator ruling 2026-10-12 (S27, 09 §3 decision 222). The operator approves the Hungarian text before
release. A box whose first ingestion failed now serves one bilingual waiting page and retries every
minute instead of the wizard. Own commit so the lead can hold it back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 15:38:28 +02:00
admin fd28d70bff v0.308.0: controller batch 2026-10-12 — clear-address warning (R-922), secret sweep over every page (R-255), read_failed (R-266), no NVMe heat band (R-333), share globe (R-577), Hungarian dates and numbers (R-562), lost-drive option pinned (R-521)
Operator rulings 2026-10-12, 09 §3 decisions 196, 204-207, 223, 227. MinAgent 0.131.0 unchanged.
R-255's sweep found one leak, fixed here: an optional-config secret_input was rendered into its
settings page; it is now revealed on demand. Hungarian parity fixtures re-captured once for R-562.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-12 15:13:59 +02:00
admin dcd89364a4 REPORT: v0.307.0 released and delivered (2026-10-10 afternoon)
gates / gates (push) Successful in 1m19s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-10 15:24:38 +02:00
admin fc6466a50a v0.307.0: after a restart the Databases table lists each database once, not every pre-restore undo copy
gates / gates (push) Successful in 1m14s
Seen on demo-hp 2026-10-10 (adventurelog x4, bookstack x4). The synthesised run skips IsUndo files; only undo copies
-> no synthesised run. Two tests, both red-proved. v0.306.0 (R-570) was built but never delivered; 0.307.0 carries it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-10 15:19:43 +02:00
admin 9e5b88146e v0.306.0: R-570 — the off-site note decides on its kind only; the pre-0.251.0 text fallback is deleted
gates / gates (push) Successful in 1m14s
Fleet condition read on each box's settings.json 2026-10-10 (offbox.last_success ~02:16Z on 0.304.0).
Red-proof: the new no-kind row of TestR553_StaleNoteDecisionSurvivesWordingChange failed against the fallback.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-10 15:08:42 +02:00
admin c255195e37 REPORT: v0.305.0 released and delivered (2026-10-10)
gates / gates (push) Successful in 1m22s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-10 11:06:55 +02:00
admin 1cb43a21a2 v0.305.0: release entry (R-921 pre-check, R-922 email_cleared); MinAgent 0.131.0
gates / gates (push) Successful in 1m4s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-10 09:55:30 +02:00
admin b3a879b50e rules: "The system poster stays true" (section 6, all five copies identical)
gates / gates (push) Successful in 1m14s
The shared rule file carries the same wording in felhom.eu, felhom-controller,
felhom-agent, app-catalog-felhom.eu and the workspace root on DooPlex --
"change all five or none" -- so this is this repo's copy of a rule added in
felhom.eu a08bd3cbd5.

A session that changes a fact listed in
architecture/felhom-system-poster.facts.md (a machine, a role, a traffic path,
a backup tier, a time, a retention, a key, a known gap) updates that file in
the same commit; fixes the poster's text if the change is text only; or adds
"System poster needs a refresh: <what changed>" to STATUS. The report names
which of the three it did.

The poster is drawn in Claude Design and nothing in the repo renders it, so
scripts/poster_facts_gate.py only WARNS when the facts outrun the drawing --
it never fails a push, because a refresh needs the operator and another tool.

Verified identical to the other four copies by diff, before and after.
2026-10-09 18:10:12 +02:00
admin ec9b997151 controller (unreleased): R-921 check-first pre-check (no stop while another tier's job is in flight); R-922 email_cleared on a household's deliberate clear
gates / gates (push) Successful in 1m0s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-09 12:57:34 +02:00
admin 13eeb484ab REPORT: v0.304.0 released, delivered, D1/D3/D4 proven live (2026-10-09)
gates / gates (push) Successful in 1m11s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-09 08:36:57 +02:00
admin d7bfdccf57 v0.304.0: the decision sheet (D1, D3, D4, D8), R-899, R-304, three layout fixes — release entry
gates / gates (push) Successful in 1m7s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-09 06:56:22 +02:00
admin 3f84f82c3d R-893: hold the app after ANY failure once the definition or a volume moved; hold persisted before the stop; run_job done says it ran, not what it found (security review)
gates / gates (push) Successful in 56s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 15:13:04 +02:00
admin d3e17e9b2e CHANGELOG/README/REUSE/REPORT: the decision sheet D1, D3, D4, D8 (unreleased)
gates / gates (push) Successful in 1m0s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin e06680b797 Operator actions in the report reply (D1, R-314/R-279/R-177, decision 185)
The hub may ask the running controller for a CLOSED list of actions,
carried in the report ACK (operator_actions) and answered on the next
report (operator_action_results): offsite_backup_now, abandon_stop,
abandon_extend (1-30 days), run_job (fill-watch, offsite-integrity,
offsite-proof, disk-health-check). Unknown action/job/argument -> refused,
nothing called. Once per id (in memory; every action is safe to repeat).

- internal/report/opactions.go: the executor; results re-sent until the
  hub stops listing the id.
- scheduler.RunNow: refuses unknown / already-running jobs; OnDemand(ctx)
  makes an operator's offsite-integrity run even when not due.
- ExtendAbandon never shortens the countdown and refuses in the hub phase;
  StopAbandon reports failure when the hub cancel failed (it said success).
- Report ACK read cap 4 KiB -> 64 KiB (an ACK over the cap dropped every
  field in it).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin 63441f0a69 R-893 slice 1: a failed off-site replay after files/volumes/version moved holds the app
Decision 192 (D8, option C). After a failed off-site database replay whose
rollback worked, but where the snapshot's definition was written or a named
volume was replaced, the app is no longer started on the mixed state:
the live definition is written back, the database service stopped, and the
app held (HoldReasonRestoreMixed) for support. The sentence (hu+en) says the
app needs help and no longer claims the data is back as it was. The operator
gets a backup_run_failures mail (leg restore-hold-mixed).

The plain case (no version change, no volume replaced) keeps today's
behaviour (TestR379_ScenarioA). Red-proofed: r893_mixed_restore_test.go.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin 740339567a R-35: an ended session cannot return after a failed save (password fingerprint in the file; a failed revoking save removes it) — security review
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin 1040cfe225 R-35 (D4): dashboard sign-ins survive the controller's own restart; disk holds only a fingerprint
Sessions are keyed by sha256(cookie) and persisted to dashboard-sessions.json
(0600, tmp+fsync+rename) in the data dir: fingerprint, expiry, CSRF token.
Loaded in NewServer; expired rows dropped at load and save. Logout and
invalidateAllSessions (password change, claim reset) write the file at once.
Corrupt/unreadable file = start with no sessions (never fatal).

Red-proof: with load/save as no-ops the restart test fails ('the old cookie
no longer signs in'); with the raw token as the key the file test fails
('the sessions file holds the cookie value').

Also: TestR650_NoBareDockerExec skips a non-.go file that vanished mid-walk
(a parallel stacks test's update-journal.json.tmp raced it in a full run).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin fcd9f09927 health check: the last six producers carry their dashboard sentence (R-79 option A, D3)
Docker unreachable, protected container down, and the four storage-path entries now carry a
bundle key beside their wire text; the wire text is unchanged byte for byte. Hungarian values of
the four storage keys equal the frozen formats (i18n_go_parity). Red-proven: a zero MsgRef on the
unavailable-path warning fails TestR79_RemainingProducersCarryTheirDashboardSentence and
TestR79_HealthBannersFollowTheHousehold (producer-driven, English household sees Hungarian).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 14:49:27 +02:00
admin 423b6d3404 Dashboard banners on a phone wrap inside the banner; the banner link takes the banner's colour
gates / gates (push) Successful in 1m5s
Seen on scratch 9202 with the R-906 build: once the real banner warnings showed (instead of an empty
overflow line), the link ran 90 px past a 390 px screen and rendered browser-default blue. Phone block:
.alert-banner wraps, .alert-message breaks long paths, .alert-link on its own line; .alert-link color: inherit.
Pinned in TestR907_PageHeaderWrapsOnAPhone (red against d5f2e47's CSS). No Hungarian string changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-08 14:41:18 +02:00
admin e37e9b50c6 Parity fixtures: re-capture stacks_full, stacks_unhealthy_stop, stacks_install_interrupted for the Apps card layout (R-909)
gates / gates (push) Successful in 1m1s
Reason: a deliberate LAYOUT change, not a translation. Deleted and re-written with
`go test -run TestI18nParity -update-i18n-golden -i18n-golden-only '^stacks_'`.
Measured: each equals its predecessor with exactly the template change applied (div.stack-title-text,
the address span.subdomain-text + title, the div.stack-tags row) — byte-for-byte, 3 of 3; the visible
text is identical. No Hungarian string changed; no other fixture moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-08 14:32:06 +02:00
admin d5f2e47ea1 Dashboard layout: Apps card header (R-909), launcher header wraps on a phone (R-907), overflow counted after the page filter (R-906)
- Apps card: title row (logo top-aligned, name, address cut with an ellipsis and full in title) over a wrapping
  .stack-tags row; the tags no longer share a space-between row with the name.
- Phone (768px block): .page-header wraps; the share button drops to its own line, text whole.
- GetBannerAlerts(page, lang): the layout's filter before the cap; baseData and /monitoring use it.
- Tests: TestStackCardHeaderLayout, TestR907_PageHeaderWrapsOnAPhone, TestR906_* (all red against 05e12921).
- No Hungarian string changed. The three stacks parity fixtures are re-captured in the next commit
  (this commit alone fails TestI18nParity on them; both are pushed together).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
2026-10-08 14:32:06 +02:00
admin 05e129267a REPORT/CONTEXT: 2026-10-08 afternoon (R-304 operator mail, R-298 side fix)
gates / gates (push) Successful in 1m0s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 10:25:55 +02:00
admin a40729a698 R-304 option C: operator mail when a household's code opens or may open an older package (once a day); R-298 side fix (no eject/format on a backup-target drive); R-717 comments
gates / gates (push) Successful in 59s
Unreleased; ships with tomorrow's release (needs the hub of the same day).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-08 10:07:03 +02:00