Files
felhom-controller/REPORT.md
T

5.8 KiB

REPORT — Launcher polish: monogram reveal-on-failure + placeholder on every icon surface (v0.163.1)

Date: 2026-07-24 · Repo: felhom-controller · Target: v0.163.1 · No agent coupling; MinAgent unchanged.

1. Baseline used

  • felhom-controller main @ 7a53cb4, version v0.163.0matched exactly (clean tree, HEAD == origin/main, CHANGELOG top = v0.163.0). No drift.

2. Files modified

Templates / CSS

  • controller/internal/web/templates/launcher.html — both tile branches' onerror final step now adds this.parentElement.classList.add('launch-tile--noimg').
  • controller/internal/web/templates/style.css.launch-mono { display: none; inset:0; … } + .launch-tile--noimg .launch-mono { display: flex; } (monogram = failure-only).
  • controller/internal/web/templates/backups_apps.html — the allowlisted aligned row's icon now uses the canonical data-fallback="/static/app-placeholder.svg" + 3-step chain; header comment updated.
  • controller/internal/web/templates/stacks.htmldata-fallback always present: {{if $im}}/static/infra-logo.svg{{else}}/static/app-placeholder.svg{{end}}.
  • controller/internal/web/templates/app_info.html — hero logo aligned to the 3-step chain + placeholder; screenshots untouched (still onerror="this.style.display='none'").
  • controller/internal/web/templates/deploy.html — deploy logo aligned; kept its .LogoURL/.LogoPNGURL data source.

Tests

  • controller/internal/web/launcher_polish_test.go — NEW (5 test functions).

Docs: CHANGELOG.md (v0.163.1), CONTEXT.md (rule recorded), REPORT.md (this file).

Gate script: app_row_dedup_gate.py does NOT pin the onerror chain (only app-row-icon presence + forbidden structures), so no gate-script edit was needed; all three gates stay green.

3. Commits pushed to main

  • 2c80868 — templates + CSS + tests + CHANGELOG + CONTEXT.
  • <REPORT commit> — this REPORT.md.

4. Tests + red-proofs

Five new tests, all green. 2 red-proofs applied → observed FAIL → restored → re-green:

# Group Mutation Test Observed FAIL
A launcher removed classList.add('launch-tile--noimg') from both onerror else branches TestLauncher_MonogramRevealOnFailure reveal-hook count 0 (want 2) — the monogram would never re-appear for a logo-less tile
B placeholder reverted backups_apps.html to the old 2-step onerror chain TestBackupsApps_IconPlaceholder canonical 3-step chain absent → logo-less row dead-ends hidden

New test functions (5): TestLauncher_MonogramRevealOnFailure (Group A), TestBackupsApps_IconPlaceholder, TestStacks_IconPlaceholderAndInfra, TestAppInfo_HeroPlaceholder_ScreenshotsUntouched, TestDeploy_LogoPlaceholder (Group B).

Two test-only fixes made while writing them (not code bugs): the reveal class legitimately appears inside the onerror JS string, so Group A asserts its count == 2 (both are classList.add hooks, none in a class= attribute); and {{.LogoPNGURL}} is JS-escaped (\/…) inside onerror, so the deploy test asserts the slash-free filename docmost-logo.png.

5. Test count & suite

  • go build ./... && go vet ./... && go test ./...all green, 0 FAIL/panic.
  • Gates green: app_row_dedup_gate.py, template_id_gate.py, emoji_gate.py.
  • Web package: +5 test functions vs v0.163.0.

6. Deployed version + verification

  • Built + pushed gitea.dooplex.hu/admin/felhom-controller:0.163.1 (145M) from the clean pushed tree (2c80868, HEAD == origin/main); deployed to guest 9201 via the bootstrap flow.
  • Live: docker ps…felhom-controller:0.163.1 Up (healthy); log → controller_started (info) — Controller elindult (0.163.1) + settle-gate: GO … we are 0.163.1.

7. Live validation

Method: endpoint-level, authenticated (real session cookie via POST /login; browser automation unavailable on DooPlex), curl inside the felhom-controller container on guest 9201. The 9201 box now has 5 launcher apps incl. Docmost (which has no logo asset — the exact reported case).

  1. Launcher monogram (check 1). On the live /launcher: launch-tile--noimg appears 5 times, all 5 inside onerror classList.add(...) hooks, 0 in any class= attribute — i.e. no tile statically carries the reveal class, so no white letter bleeds through a loaded transparent glyph. 5 tiles / 5 monogram spans (4 operational + 1 stopped — both branches exercised live). Served style.css carries .launch-mono { display: none; inset:0; … } and .launch-tile--noimg .launch-mono { display: flex; }.
  2. Placeholder on Biztonsági mentés → Alkalmazások (check 2). The live /backups/apps page's Docmost row now carries data-fallback="/static/app-placeholder.svg" and the canonical 3-step chain (4 rows total with the placeholder default) — the reported hidden-icon dead-end is gone.
  3. No regression on Alkalmazások (check 3). The live /stacks page: all 56 stack-logo-lg imgs still render with a fallback — 52 default to /static/app-placeholder.svg, 4 infra cards keep /static/infra-logo.svg. Every card keeps its logo source; no logo vanished.

8. Observations (not acted on)

  • The four aligned copies (backups_apps aligned row, stacks, app_info hero, deploy) share the same onerror grammar but differ in class/size/data-source, so consolidating them into one partial is a possible future cleanup — deliberately NOT done here (backups_apps is gate-exempted because it owns its collapse toggle; the task scoped this to chain-grammar alignment only).
  • The launcher now has a live stopped tile (a greyed app on 9201), so the stopped-branch reveal hook is exercised on real data, not only in the render test.