diff --git a/dankclaw/Caddyfile b/dankclaw/Caddyfile
index 5a32c37..4d05768 100644
--- a/dankclaw/Caddyfile
+++ b/dankclaw/Caddyfile
@@ -337,6 +337,15 @@ http://:8017 {
try_files /docs.html
file_server
}
+ # /whoami echoes the outpost-injected identity headers so the page
+ # can gate the admin button client-side (the /admin* 403 above stays
+ # the real gate; this only decides what is shown). The outpost strips
+ # client-supplied X-Authentik-* before injecting, so this is spoof-proof.
+ handle /whoami {
+ templates
+ header Content-Type application/json
+ respond "{\"user\":\"{header.X-Authentik-Username}\",\"groups\":\"{header.X-Authentik-Groups}\"}"
+ }
@data path /services.json /status.json /app.js /style.css /deployed.js /img/* /sfx/*
handle @data {
file_server
diff --git a/serverAppConfigs-docs/Infrastructure/Homepage.md b/serverAppConfigs-docs/Infrastructure/Homepage.md
index 0ee4888..c58e8d6 100644
--- a/serverAppConfigs-docs/Infrastructure/Homepage.md
+++ b/serverAppConfigs-docs/Infrastructure/Homepage.md
@@ -87,6 +87,34 @@ from the dankcloud SSO; SearXNG is obfuscated, not anonymous (upstream
API keys tie to Frank). The user docs `/docs#models` section carries the
same renames, api-id mapping, supervision and compaction notes.
+**Icons, card polish, admin identity gate (2026-10-08, later wave):** every
+app card now carries hex-clipped art beside its name (`services.json` `art`
+field, files under `img/apps/`): 19 brand marks tinted amber from the
+Simple Icons CDN plus 19 hand-improvised monogram SVGs (amber hex + VT323
+initials) for apps with no mark — Copyparty, Marreta, Hermes (+dashboard),
+node-exporter, Gluetun, OpenWebUI, Calibre-Web, RomM, Seerr, Loki, Alloy,
+Alertmanager, Valkey, Prowlarr, Readarr, Lidarr, Tautulli, ComfyUI. Model
+cards render in the order zealot → dragoon → archon (registry order is the
+contract; `homepage_config.bats` pins it). Dragoon and zealot share one
+common uncensored legal warning (adult content, harmful/hateful/illegal
+descriptions, "sensitive offensive cybersecurity topics", severe legal
+risk, "don't ruin this server for everybody"), rendered as the hover
+label; archon's ask-Frank rule is a bordered red `.mi-perm` callout.
+SearXNG's obfuscation-not-anonymity note moved out of its description into
+a card-level `warn` (`.svc-warn` hover label) and the same hover treatment
+in the docs. Gitea's note now documents self-service signup — no need to
+ask Frank. Footer: docs / admin / account settings are bordered glowing
+`.foot-btn` buttons; **the admin button is identity-gated** — Caddy's
+`/whoami` echoes the outpost-injected `X-Authentik-Username`/`X-Authentik-Groups`
+headers (the outpost strips client-supplied copies, so the echo is
+spoof-proof), and `app.js` shows the button only to `homepage-admins`
+members. The `/admin*` 403 stays the real gate; the e2e specs pin both
+sides (standard user: hidden + 403; admin: visible). Docs were swept for
+naming consistency: Protoss names primary everywhere, bracketed api ids
+at the model headings, and a note that a future switchover renames the
+ids themselves (OpenWebUI picker + raw API + models.yml all move together
+— not done yet).
+
## Design decision — 2026-08-22
The live up/down check runs server-side. A checker on Dankclaw probes each backend and writes a same-origin `status.json`. The page fetches only that file and renders the badges. The browser never calls a backend directly. The checker runs as a systemd timer every 3 minutes.
@@ -182,7 +210,9 @@ shared/homepage/
├── style.css # full theme; a toggle strips to bare HTML
├── app.js # loads status.json once, renders the panels
├── services.json # service config (user + admin)
-├── img/ # screenshots served at /img (docs page; deployed with the page)
+├── img/ # served at /img: docs screenshots, unit portraits
+│ ├── apps/ # (unit-*.jpg) and app card icons (apps/*.svg)
+├── sfx/ # StarCraft unit voice .ogg files served at /sfx
└── fonts/ # optional self-hosted fonts (deployed with the page; VT323 comes from the Google Fonts CDN, this dir is absent)
```
diff --git a/shared/homepage/admin.html b/shared/homepage/admin.html
index f79c122..1c7e89e 100644
--- a/shared/homepage/admin.html
+++ b/shared/homepage/admin.html
@@ -19,7 +19,7 @@
diff --git a/shared/homepage/app.js b/shared/homepage/app.js
index 471eb85..3f46793 100644
--- a/shared/homepage/app.js
+++ b/shared/homepage/app.js
@@ -92,6 +92,7 @@ function miCard(svc, state) {
if (m.use) parts.push('
Use: ' + esc(m.use) + '
');
if (m.voice) parts.push(voiceBtn(m.voice.text, m.voice.sfx));
if (m.supervision) parts.push('
';
return panel;
}
@@ -197,9 +202,24 @@ function fillDeployed() {
if (el && window.DEPLOYED_AT) el.textContent = window.DEPLOYED_AT;
}
+// Show the admin button only to members of the authentik homepage-admins
+// group (the same group the /admin* server gate enforces). The data comes
+// from Caddy's /whoami, which echoes the outpost-injected identity headers.
+function gateAdminLink() {
+ const link = document.getElementById('admin-link');
+ if (!link) return;
+ fetch('/whoami', { headers: { accept: 'application/json' } })
+ .then(function (r) { return r.ok ? r.json() : null; })
+ .then(function (me) {
+ if (me && /homepage-admins/i.test(me.groups || '')) link.hidden = false;
+ })
+ .catch(function () {});
+}
+
function main() {
applyBare();
fillDeployed();
+ gateAdminLink();
Promise.all([load('services.json'), load('status.json')])
.then(function (pair) { renderPanels(pair[0], pair[1]); })
.catch(function (e) {
diff --git a/shared/homepage/docs.html b/shared/homepage/docs.html
index b0efe55..5640e2c 100644
--- a/shared/homepage/docs.html
+++ b/shared/homepage/docs.html
@@ -55,26 +55,9 @@
The homepage "Model Information" panel shows whether each one is up right now —
and plays the unit's voice if you click its quoted line.
-
frank-dragoon — deep reasoning (api id: frank-large)
-
-
Model: Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) on the Strix Halo iGPU — an abliterated (censorship-removed) edition that thinks before answering.
-
Equivalent: Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier intelligence).
-
Capacity: 200k-token context, two submissions at a time; sees images.
-
Inputs: text, image.
-
Best for: complex agentic tasks, programming, system administration, and "claw"-style personal agents.
-
Supervision: safe for autonomous, low-supervision use.
-
Warning:⚠ legal note — hover to read
-
-
-
frank-archon — the big one (api id: frank-primary)
-
-
Model: Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) on twin AMD R9700s with more than 200 GB of system RAM — the biggest brain on the network and the fastest runtime.
-
Equivalent: Claude Opus 4.8 / OpenAI-Terra (Summer 2026 frontier intelligence).
-
Capacity: 200k-token context, two submissions at a time; sees images.
-
Inputs: text, image.
-
Best for: software engineering, system administration, and instruction tasks. Please ask Frank before use — he uses this one primarily.
-
Supervision: safe for autonomous, low-supervision use.
-
+
Naming: the Open WebUI picker and the raw API show the
+ endpoint api ids in brackets below. The Protoss names are the family
+ names; a future switchover will rename the ids to match.
frank-zealot — the fast utility model (api id: frank-secondary)
@@ -85,15 +68,34 @@
Best for: code editor autocomplete, agentic search, RAG, research subagents, translation, roleplay, and summarization — any small task that doesn't need much intelligence, and anything with a picture. This is the model Open WebUI offers to family accounts.
Compaction: if your agent harness supports setting a compaction model, set this one. A compaction job severely slows the bigger models for far longer than it slows this one.
Supervision: requires tight human supervision.
-
Warning:⚠ legal note — hover to read
+
Warning:⚠ Uncensored model — hover to read
+
+
+
frank-dragoon — deep reasoning (api id: frank-large)
+
+
Model: Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) on the Strix Halo iGPU — an abliterated (censorship-removed) edition that thinks before answering.
+
Equivalent: Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier intelligence).
+
Capacity: 200k-token context, two submissions at a time; sees images.
+
Inputs: text, image.
+
Best for: complex agentic tasks, programming, system administration, and "claw"-style personal agents.
+
Supervision: safe for autonomous, low-supervision use.
+
Warning:⚠ Uncensored model — hover to read
+
+
frank-archon — the big one (api id: frank-primary)
+
+
Model: Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) on twin AMD R9700s with more than 200 GB of system RAM — the biggest brain on the network and the fastest runtime.
+
Equivalent: Claude Opus 4.8 / OpenAI-Terra (Summer 2026 frontier intelligence).
+
Capacity: 200k-token context, two submissions at a time; sees images.
+
Inputs: text, image.
+
Best for: software engineering, system administration, and instruction tasks. ⚠ Ask Frank for permission before use — this is his primary model; he uses it more than anything else on the fleet.
Which one to pick? Small utility work, autocomplete, RAG,
- search, and screenshots: frank-zealot. Complex agentic work,
programming, and personal agents: frank-dragoon. Software
engineering, sysadmin, and instruction tasks: frank-archon (ask
- Frank first). The names in brackets are the ids the API and Open WebUI
- use; the family names are the Protoss ones.
+ Frank first). The ids in brackets are what the Open WebUI picker and the
+ raw API show today; the Protoss names are the family names, and the switchover
+ will rename the ids to match.
@@ -182,7 +184,7 @@
Books:Calibre-Web — the e-book library, with its own login.