hub v0.47.0: CHANGELOG + README tab/host-lifecycle/offsite docs + REUSE map + manifest bump to 0.47.0
CONTEXT.md: v0.47.0 arc entry (resolves the 146d165 swept-WIP flag) + the
multi-endpoint-allocation deferral + pre-GitOps stale-template note.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Vvz1NCu22p8dGkRCpeX9re
This commit is contained in:
@@ -1,5 +1,55 @@
|
||||
# Felhom Hub — Changelog
|
||||
|
||||
## v0.47.0 — UI reorganization: customer tabs, Host tab, stale-host removal, offsite multi-endpoint UI, button contrast (2026-07-11)
|
||||
|
||||
Five hub-side deliverables; no agent/controller/protocol changes. Baseline `8e1a3f0`
|
||||
(v0.46.0); commits `9f29bf3` → `ae950e5` → `146d165`(swept WIP) → `068427a` → `0daddcd`.
|
||||
|
||||
- **CSS button contrast** (`templates/style.css`): `.data-table td a` → `:not(.btn)` (base +
|
||||
hover) — `<a class="btn">` inside data-table cells (host-detail Diagnostics View/Download,
|
||||
customer log-tail buttons) rendered blue-bright on blue-bright, i.e. invisible. Plain table
|
||||
links keep the bright-link style; `.btn` itself untouched, no `!important`.
|
||||
- **Customer page tabs** (`templates/customer_unified.html`, `style.css`): the ~18 stacked
|
||||
sections split into 8 client-side hash tabs (`#tab=` overview / applications / setup /
|
||||
settings / backup / events / notifications / host) + a sticky summary strip (name, status,
|
||||
controller version, last report, containers chip). Graceful degradation is load-bearing:
|
||||
panels hide only under a JS-added `body.js-tabs` class — no JS = every section visible, all
|
||||
existing render tests pass unmodified. Events tab carries a red error-count badge (reuses
|
||||
the already-fetched `CountEventsBySeverity` data — no new query). The auto-refresh reload
|
||||
preserves the hash → the active tab survives. No handler/data-model change for the tabs.
|
||||
- **Host tab + shared sub-template** (`templates/host_detail_body.html`, `web/hosts.go`,
|
||||
`web/configs.go`, `store.ListHostsByCustomer`): the host-detail body extracted into a
|
||||
`{{define "host_detail_body"}}` rendered by BOTH `/hosts/{id}` (chrome + call) and the new
|
||||
per-customer Host tab (a LIST by design — 1 host today, N for a later HA cluster; empty
|
||||
state otherwise). `handleHostDetail`'s data assembly extracted into `hostDetailData`.
|
||||
- **Stale host removal** (`store.CountHostArtifacts`/`DeleteHost`, `web/hosts.go` handlers,
|
||||
routes above the `/hosts/` catch-all): `GET /hosts/{id}/delete-impact` (counts/booleans
|
||||
ONLY) + `POST /hosts/{id}/delete` behind a type-to-confirm dialog (global-floor pattern).
|
||||
Gates: ONLINE host → 409 always (no override — a live agent would 401 forever; enroll is
|
||||
passphrase-gated mint-once); confirm mismatch → 400; escrow present without the explicit
|
||||
checkbox → 409 with the tx never started (`ErrHostEscrowPresent`, fail-safe-to-refuse).
|
||||
One transaction cascades guests, host_reports, signed_jobs, host_recovery,
|
||||
host_pbs_secrets, host-scoped log bundles (`scope_id == host_id` ONLY — customer-scoped
|
||||
bundles survive), the bound wg peer (inside the tx — no stranded peer on crash), escrow
|
||||
(only when acked), then the host row. The wgsync 5-min declarative push converges the
|
||||
endpoint afterwards — no reconciler change. Danger-zone card renders only when deletable,
|
||||
so the hosts-list zero-`<button>` pin and the detail-page 2-button pin stay green unmodified.
|
||||
- **Offsite multi-endpoint UI** (`store/wg.go` `ListWGEndpoints`/`DeleteWGEndpoint`,
|
||||
`web/offsite.go`, `templates/offsite.html`): `/offsite` lists ALL `wg_endpoints` rows as
|
||||
cards + add/edit/delete forms (posture change from S2 read-only — operator decision).
|
||||
Validation → 400 stores nothing; subnet edit / endpoint delete refused 409 while peers sit
|
||||
in the (current) subnet; pubkey change gets a type-to-confirm noting pull-based
|
||||
convergence. Peer table gains an Endpoint column (first id-ordered subnet match, em dash
|
||||
when none). **Allocation, reconciler push and desired-state merge stay lowest-endpoint-id**
|
||||
(`GetWGEndpoint` untouched; the page states the deferral) — per-endpoint allocation
|
||||
(`wg_peers.endpoint_id` migration) is a future arc.
|
||||
- **Tests**: +21 new/amended across web+store: tab render (no-JS completeness, badge, banner-
|
||||
above-tabs), Host tab shared-body/empty/isolation, delete cascade + refusal non-effects +
|
||||
impact shape + danger-card gating, offsite cards/column/validation/guards. Five companion
|
||||
red-proofs ran and FAILED as required (online gate, escrow ack, bundle scope, endpoint
|
||||
delete guard, subnet-change guard). Note: commit `146d165` (parallel session) swept the
|
||||
Part-4 WIP mid-red-proof — `068427a` restored the escrow-ack line.
|
||||
|
||||
## v0.46.0 — observability pass: per-box log pulls, bundle custody, TTL + secret gate (2026-07-11)
|
||||
|
||||
Hub third of the cross-repo observability task (agent v0.83.0 + controller v0.116.0): remote,
|
||||
|
||||
Reference in New Issue
Block a user