18 pages cut their per-endpoint shape, payload, port and window claims and
link [[frank-archon]] / [[frank-dragoon]] / [[frank-zealot]] instead. Several
of the cut claims had already drifted -- the stack page still described the
kingjones ROCmFP4 era on ROCmFPX, OpenWebUI carried the 27B/3-slot bench
narrative, Hermes named a retired max_model_len and the old service name, and
the OMP harness page's live-window block had drifted off frank-zealot's real
262,144 (it is now labelled a dated worked example whose authority is the
endpoint page).
Two facts gain a single owner instead of two: the up{job=~"frank-.*"} scope
lives in Infrastructure/Prometheus.md, and the blackbox/Anubis probe form in
Architecture/Stale Signal Audit.md, each cited from the other page.
Voice Packs and Frank TTS carried live-state claims that contradicted the
engine page's 2026-10-18 deploy record (nothing listening on 7772/8880, model
dir absent); they now point at the pages that own host state.
26 KiB
type, description, tags, timestamp
| type | description | tags | timestamp | ||
|---|---|---|---|---|---|
| reference | A password-protected web site on Dankclaw lists the services that are up, with a short description of each and a link to both the service and its usage documentation. |
|
2026-09-21 |
Homepage
A password-protected web site on Dankclaw lists the services that are up, with a short description of each and a link to both the service and its usage documentation.
Served by: Caddy, file_server + forward_auth (Authentik SSO) — Docs: this page
Status — deployed to production (2026-08-23), on the naked domain since 2026-08-24
The homepage is live on Dankclaw. ./scripts/deploy.sh dankclaw copies the static assets to /srv/homepage/, installs the status checker (systemd timer, every 3 min, writes status.json), writes deployed.js (the last master deployment datetime), renders the Caddyfile (the shared basicauth hash from the host .env), reloads Caddy, and checks health. The Caddyfile auth uses a route block with forward_auth (see Auth); the caddy container mounts the host's /srv/homepage (not the repo source) so the generated files serve.
Moved to the naked domain (2026-08-24): the homepage now serves franksdank.cloud and www.franksdank.cloud. The old names dankclaw.franksdank.cloud and dankserver.franksdank.cloud redirect to it. Authentication moved from per-page basicauth to Authentik forward_auth (see Authentik).
Docs page shipped (2026-09-17): /docs serves a static user documentation
page (shared/homepage/docs.html) — access walkthrough, the running-model
guide, media how-tos, and troubleshooting. Per-service /docs/<svc>/ pages
remain a separate thread. The three LLM cards (frank-dragoon, frank-medium,
frank-zealot) moved from admin-only to the user page with live model
descriptions and a docs link to /docs#models.
Sections + WIP split (2026-09-21): both pages now group their panels
under section headings rendered by shared renderSection()/renderPanel()
components in app.js. The user page orders AI, Web Apps, Media Library
Apps; the admin page orders Media Library Apps, Observability, AI,
Infrastructure. The WIP badge split into WIP: OPEN (work in progress)
and WIP: CLOSED (work finished by decision — e.g. a card that is
deliberately unprobeable) via the wip value ("open" / "closed").
Tautulli (Plex statistics, 192.168.0.235:8181) joined the admin page's
Media Library Apps section.
Amber CRT theme + API docs (2026-10-07): the palette moved from green
phosphor to amber CRT-AMBIOS (--fg #ffb000 on --bg #0a0600), and the font
stack now leads with VT323 loaded from the Google Fonts CDN (the deploy
also ships shared/homepage/img/ beside the page, so /img/* serves the docs
screenshots — the post-auth listener serves files only through the @data
path allowlist, so new top-level assets must be added there (the @home
catch-all answers anything else with index.html, i.e. a PNG arrives as
200 text/html and renders broken; pinned in homepage_caddy.bats — this
exact bug bit the screenshots on 2026-10-08). The docs page gained a full
(/docs#api-access): per-user OpenWebUI API keys (User menu → Settings →
Account → API keys), the base URL https://ai.franksdank.cloud/api/v1, and
copy-paste configs for Opencode (~/.config/opencode/opencode.json) and
Pi (~/.pi/agent/models.json) pointing at frank-zealot. Shipped
together with the OpenWebUI side: features.api_keys=true for regular users
and the restored frank-zealot model row + public read access grant
without which the picker showed "No results found" for every family account
(see OpenWebUI).
Capability equivalence notes (2026-10-08): each fleet card (and the
/docs#models section) carries a details.equiv line — frank-dragoon
"equivalent to Claude Sonnet 5 / OpenAI-Luna (Summer 2026 frontier
intelligence)", frank-archon "equivalent to Claude Opus 4.8 / OpenAI-Terra
(same era)", frank-zealot "equivalent to last year's frontier level
(2025)". Rendered by descHTML() as .desc-equiv (head color, italic);
pinned in homepage_config.bats.
Protoss rename + Model Information component (2026-10-08): the model
cards became the StarCraft trio — frank-dragoon → frank-dragoon
(iGPU), frank-archon → frank-archon (Dankserver), frank-zealot
→ frank-zealot (3090). The endpoint/API ids did NOT change in this wave; only the
family-facing names. The three cards fused into one Model Information
component (app.js renderModelInfo(), .model-info/.mi-* styles):
Protoss unit art (/img/unit-<unit>.jpg, hex-clipped), per-unit accent
colours (Dragoon gold, Archon cyan, Zealot blue), smaller type (15px vs
19px body), and clickable unit-voice lines that play the original
StarCraft .ogg quotations from /sfx/ (fetched from
starcraft.fandom.com via its MediaWiki API; the quote→file mapping lives
in the model.sfx/model.voice.sfx fields). New services.json
per-model fields: unit, tagline, sfx[], voice, supervision
(dragoon/archon autonomous-safe, zealot tight-supervision), and warn
(uncensored legal note, rendered as a hover tooltip, not wall text).
A compaction-model recommendation for frank-zealot rides in its use
text. The Caddy @data allowlist grew /sfx/*; deploy_homepage copies
sfx/. A wip: "down" badge state ("WIP: DOWN", red) was added; Seerr,
Calibre-Web, RomM, and Jellyfin are WIP: DOWN with their Open links
removed. Card notes added: Copyparty holds every other media app's
content (including the WIP ones); Gitea and Plex need logins separate
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).
Icons v2, clickable tiles, header nav (2026-10-08, third wave): five
icons replaced on request — Copyparty gets an improvised amber folder,
Marreta a crumbling wall (bricks + red crack), Calibre-Web a book,
OpenWebUI its official logo (openwebui.com/logo.png), Seerr the official
seerr.dev/os_logo_filled.svg. Tiles with an open link are now clickable
whole (.panel.clickable, hover lift + glow; clicks on inner links pass
through). Any panel whose live state is DOWN gets a red gradient wash +
slow pulsing glow (.panel.down, and .mi-card:has(.badge.down) for
model cards). docs/admin/account-settings moved from the footer to the
header (nav.top-links). The zealot compaction advice moved out of the
Use paragraph into a bordered glowing model.compaction callout
(.mi-comp), pinned by the component seam test.
Protoss theme, brand-color icons, portraits (2026-10-08, fourth wave):
the full-page angular treatment: chamfered 14 px-cut panels and model
cards, hex-lattice + amber-glow backdrop (body::after), scanline
overlay (body::before), diamond-glyph section titles with gradient
underlines, the gradient MODEL INFORMATION gateway, a blinking cursor
beside the title, amber scrollbars, cyan text selection, cyan hover glow
on clickable tiles, and a red pulsing glow on down tiles/cards (the
data-state="down" attribute applyStatus now sets). Icons recut to
official brand colors (Simple Icons CDN): SearXNG, Gitea, Plex, Jellyfin,
Sonarr, Radarr, Lidarr, Readarr, qBittorrent, Prowlarr, Seerr, OpenWebUI,
Calibre-Web (amber glyph on amber tile). Handcrafted monograms carry
per-app colors: Copyparty gold, Marreta brick, Grafana orange, Loki
indigo, Neo4j network, Alloy violet, Promtail pink, Alertmanager red,
Prometheus orange, Node Exporter teal, cAdvisor sky, Guake yellow,
Authentik blue, Seer green radar, RomM a purple GameBoy. New per-service
fields: art_bg (art backdrop — OpenWebUI's dark logo needs #f5f5f5),
warn on OpenWebUI (searches ride the Seerr→SearXNG path),
model.compaction (the amber "set this as compaction model" callout
frank-zealot carries). frank-dragoon's card portrait is the SC2 unit
portrait (fandom wiki Dragoon_portrait.jpg, webp→jpeg). The whole
effect layer is stripped under data-bare="1" (the e2e bare page).
Unit: tests/homepage_config.bats (referenced art files exist, model
blocks well-formed, deployer ships the img/ tree).
Docs reorder + model source links (2026-10-08, fifth wave): the docs
page section order is now getting-in → troubleshooting → media → chat →
models → api-access (non-AI first, AI last). The *arr stack (Prowlarr,
Sonarr, Radarr, Lidarr, Readarr, qBittorrent) is out of the family docs
entirely — admin tooling; Seerr is presented as the front door for
requests. Each fleet model gained a Hugging Face source link: card field
model.hf rendered as the cyan model on huggingface ↗ line under the
role, and the docs Model: bullets link the checkpoint names — which
checkpoint each endpoint runs is payload state on
frank-dragoon, frank-archon and frank-zealot.
Navy Protoss console, maximal cornering, font swap (2026-10-08, sixth
wave): the amber CRT palette is retired. The page is now deep space
navy (#050d16) with warp-blue/psychic-cyan accents (--proto-blue #3fa9ff, --proto-cyan #7fe7ff) — StarCraft Protoss console colours.
Cornering went maximal: every panel, model card, badge, button, callout
and the MODEL INFORMATION gateway are octagon-cut (all four corners
chamfered, 18–24 px), and panels/model cards gained a second inset
octagonal frame line (::before) — a double-bevel gateway look. Section
titles are chamfered plates with the diamond glyph inside the plate.
Fonts: body is Share Tech Mono (legible retro terminal), headings
are Rajdhani 600 (the StarCraft UI face) — VT323 is retired; all
three pages load the pair from Google Fonts. Four tiles that had
reverted to initials got pictograms: Calibre-Web an open book (orange),
RomM a purple GameBoy, Copyparty a blue folder with upload arrow,
Marreta a crumbling brick wall with a red crack (img/apps/app-*.svg).
frank-dragoon's card accent is phase-crystal teal (#5fe0d0), matching
the new palette. Bare mode strips the frames, octagon cuts and fonts.
Simplified console (2026-10-08, seventh wave): "too busy — clean up
and simplify/solidify." The sixth-wave effect stack was stripped to
essentials. Removed: the scanline overlay (body::before), the hex
lattice + twin radial backdrop (one quiet pylon glow above the horizon
remains), the panel/model-card inner frame lines, all ambient text
glows (body, title, model names, callouts), the blinking title cursor,
the gradient section-title plates (headings are plain Rajdhani with a
hollow diamond glyph + steel underline), the gradient border-image
header rule (solid 2px warp-blue), the pulsing down-state animation
(down tiles and cards now show a STATIC red border + tint), and the
button/hover glows. Kept: octagon-cut panels (softer 14 px), unit-color
model cards, the pictograms, and the fonts. Motion is reserved for
state — the only animation left is the speaking-voice pulse. The result
is flat navy panels on crisp 1px borders: same Protoss direction, half
the pixels.
Model ids official (2026-10-08): the card ids frank-zealot,
frank-dragoon, frank-archon are now the harness's official model ids
in models.yml/config.yml (see OMP Harness); the
systemd services keep the frank-archon/frank-dragoon/
frank-zealot names. Homepage, docs page and harness now agree on
one name per model.
Api ids renamed on the wire (2026-10-09): the promise in
docs.html is kept — the served model ids are now frank-zealot,
frank-dragoon, frank-archon, so the docs page no longer carries
api id: annotations, and the curl/opencode/Pi examples send
frank-zealot. The systemd services keep the old names. docs.html
names the fleet trio once each; homepage_config.bats pins the card
ids, which did not change.
Console polish (2026-10-08, eighth wave): five fixes — octagon
clip-paths replaced with border-radius (the clipped corners read as
gaps in the 1px border); section-title diamonds moved from absolute
positioning to a fixed-width inline glyph (aligned, wrap-safe); closed
WIP items grey out (dim type, desaturated art, muted border via
:has(.badge.wip-closed)); the Dragoon tagline is one spliced track
(sfx/dragoon-tagline.ogg — loudnorm-matched, silence-trimmed, 350 ms
beat; the two SC2 source oggs are trashed); privacy notes became
<details> disclosure chips ("⚠ privacy note ▸") pinned to the
bottom of each box (margin-top:auto in a flex-column panel/card) —
collapsed by default, tap-to-expand, the touch-safe replacement for the
unreachable hover tooltips. The panel click-to-open handler ignores
.svc-warn taps so the chip never navigates. Same chips on the docs
page (privacy + uncensored-model warnings). The API-access section was
reblessed against the live Open WebUI 0.6 UI: steps now match the real
Show/copy/rotate flow and img/openwebui-api-keys.png is a fresh
screenshot (old shot trashed). The troubleshooting DNS bullet dropped
its Pi-hole specifics — family members off the LAN cannot use
house-DNS advice; the bullet now just says the names resolve on the
home network.
Archon card runs the fleet's own model (2026-10-08): the
frank-archon homepage card and docs Model bullet swapped the FP8-era
base-model link for our own HF publication, and the capacity line for the
endpoint's own concurrency figure; the payload, its publication and the slot
count all live on frank-archon.
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.
The site has two pages. The root lists user-facing services only, with no host labels. An /admin/ subpage lists the admin and infrastructure services behind a separate password for the operator. Gitea is a user service. Hermes is an admin service. A "how it is built" page for visitors is deferred (Q6).
The client-side probe design is blocked in this topology. The page origin is https://franksdank.cloud. The service URLs are https://<name>.franksdank.cloud. That is cross-origin and auth-gated. Both fail a browser fetch.
Intended direction: move to client-side probing. Serve every service as a same-origin https path under franksdank.cloud. Add a health endpoint and CORS headers to each backend. Then the page probes each service directly. Keep this note until that shift is complete.
Structure
The site has two pages. The root page lists the user services. The /admin/ page lists the admin and infrastructure services. The optional /how/ page is deferred (Q6).
graph TD
subgraph site["franksdank.cloud + www (Caddy)"]
ROOT["/ user services<br/>(shared password)"]
ADMIN["/admin/ admin services<br/>(operator password)"]
HOW["/how/ how it is built<br/>(deferred)"]
STATUS["/status.json"]
end
TIMER["systemd timer<br/>every 3 minutes"]
CHECKER["checker script<br/>probes each backend"]
BACKENDS["backends on both hosts"]
TIMER --> CHECKER
CHECKER -->|writes| STATUS
STATUS -->|polled| ROOT
STATUS -->|polled| ADMIN
CHECKER -->|probes| BACKENDS
Status model
Each service shows one of three states.
stateDiagram-v2
[*] --> Up
[*] --> Down
[*] --> WipOpen: wip = "open"
[*] --> WipClosed: wip = "closed"
Up --> Down: probe fails
Down --> Up: probe succeeds
WipOpen --> Up: work completes
WipClosed --> Up: card becomes probeable
- Up — the probe reached the backend.
- Down — the probe failed (connection refused or timeout).
- WIP: Open — work is in progress. The checker does not probe it.
- WIP: Closed — the work is closed by decision (for example a card that is deliberately unprobeable, with the reason in its description). The checker does not probe it.
Checker
The checker runs on Dankclaw as a systemd timer. Every run probes each backend directly, then writes status.json. It probes the backend host:port, not the Caddy site. A Caddy 502 or 401 cannot tell up from down. The probe method is per service (tcp or http). The timeout is 5 s. The page reads status.json once on load. It does not auto-refresh.
flowchart TD
A[timer fires] --> B[read service config]
B --> C{for each service}
C -->|wip| D[mark WIP]
C -->|probe| E[probe: tcp or http]
E -->|connected| F[mark Up]
E -->|refused / timeout| G[mark Down]
D --> H[write status.json]
F --> H
G --> H
Service classification
User services (root page), in section order:
- AI — OpenWebUI, and the three LLM fleet cards (frank-dragoon, frank-archon, frank-zealot — status + docs link, no Open link).
- Web Apps — SearXNG, Gitea, Copyparty, Marreta.
- Media Library Apps — Calibre-Web, RomM, Plex, Jellyfin, Seerr.
Admin services (/admin/), in section order:
- Media Library Apps — the *arr stack (Prowlarr, Sonarr, Radarr, Lidarr, Readarr), qBittorrent, and Tautulli — live on FrankBook-Pro and Dankserver, operator-only: no vhosts (Tautulli included), direct IP:port access only. See FrankBook-Pro.
- Observability — Grafana, Prometheus, Loki, node-exporter, alloy, alertmanager.
- AI — Hermes, ComfyUI.
- Infrastructure — Caddy, dnsmasq, Gluetun, and the low-level backends (mariadb, valkey, Postgres). The backends show status only. They get a link only where a UI is meaningful.
Layout
shared/homepage/
├── index.html # root page (user services)
├── admin.html # admin + infrastructure services
├── docs.html # user documentation page, served at /docs (2026-09-17)
├── 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/ # 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)
status.json is generated at runtime in /srv/homepage/. It is not committed.
Rendering
The page renders sections of TUI-style panels — one panel per service,
grouped under a section heading. Each panel shows the state badge, the name,
the description, and the Open and Docs links. Section and panel are
shared components (renderSection() / renderPanel() in app.js); each
page's section order is fixed by SECTION_ORDER. A summary line at the top
counts the states. The footer shows the last master deployment datetime (Q43).
The page reads status.json once on load. It does not auto-refresh (Q41).
Styling is toggleable (Q27). The default is the full terminal theme. A toggle strips the page to bare, unstyled HTML (motherfuckingwebsite.com style). The page does not alter the user's cursor (Q28).
Auth
Caddy wraps the site with forward_auth (Authentik SSO). A single Authentik
session covers the whole site: the user page, the /admin/ page, and the
shared data + assets. The browser's Authentik cookie is reused for the data
fetches, so no per-page credential is needed. See Authentik for
the provider, the outpost, and the first-time setup.
The Caddyfile pattern (one of the forward_auth vhosts):
franksdank.cloud www.franksdank.cloud {
root * /srv/homepage
route {
# 1. The outpost path is proxied to Authentik (login UI + session).
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
# 2. forward_auth checks the session before serving the page.
forward_auth authentik-server:9000 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name
trusted_proxies private_ranges
}
# 3. The pages, in file order. 'handle' preserves order; a top-level
# 'rewrite' would be sorted first and break the path matchers.
handle /admin* {
try_files /admin.html
file_server
}
@data path /services.json /status.json /app.js /style.css /deployed.js
handle @data {
file_server
}
handle {
try_files /index.html
file_server
}
}
}
A handle inline matcher is a single token; the multi-path @data match is a
named matcher. The caddy container mounts the host's /srv/homepage (where the
deploy writes the static files and the checker writes status.json), not the
repo's shared/homepage. A compose change needs a container recreate (podman compose up -d caddy), not a reload. The Caddyfile syntax is documented in the
agent knowledge base (~/.pi/agent/docs/caddy/caddyfile.md).
Service entry format
{
"name": "SearXNG",
"category": "user",
"section": "Web Apps",
"description": "Privacy-respecting metasearch engine.",
"url": "http://search.franksdank.cloud",
"docs": "/docs/searxng/",
"probe": "127.0.0.1:8081",
"method": "http",
"wip": false,
"showLink": true
}
category—useroradmin. Selects the page.section— the heading the panel renders under. Must be one of the page'sSECTION_ORDERentries (user: AI, Web Apps, Media Library Apps; admin: Media Library Apps, Observability, AI, Infrastructure), or the panel is silently dropped from the page.url— the "Open" link (the Caddy site).docs— the per-service docs page (/docs/<svc>/).probe— the backendhost:portthe checker probes.method—tcporhttp. The probe type for this service (Q10).wip—false, or"open"/"closed". When set, the badge shows WIP: OPEN or WIP: CLOSED and the checker skips the probe.
A card must be probeable from the monitor's host, or it must be wip. The
checker runs on Dankclaw, so its reach is: that host's own loopback, its own
container names, and LAN addresses that are actually published. A card whose
probe is a container-internal port of another host can never turn green — it
reports a red dot for a healthy service, which is how the board stops being
worth reading (the same lesson as the Prometheus jobs that scrape HTML pages).
Three cards were exactly that until 2026-09-16 — mariadb
(192.168.0.235:3306), valkey and Postgres (127.0.0.1:6379/:5432) — all
probing unpublished database ports. Publishing a database on the LAN to make a
badge green is not a trade this fleet makes, so they are wip with the reason in
their description, and the app that fronts each database carries the status
(Glutun, a WireGuard UDP service, was the pre-existing example of the same
call).
showLink— when false, the panel shows status only (no "Open" link).
Deployment and testing
The deploy is git-driven. Master always reflects the currently deployed state (Q33). deploy.sh copies the assets to /srv/homepage/, installs the checker timer, renders the Caddyfile (both hashes), and reloads Caddy. It stamps the deployment datetime the footer shows (Q43).
The build is full TDD (Q36–Q38). Tests exist before the code: the checker (a fake up port, a down port, a WIP service, and the JSON schema), the pages and config (the services.json schema, caddy validate, the status.json reference), and the auth check (the forward_auth block and the renderable basicauth placeholder).
Per-service docs (separate workstream)
Each service gets a docs page at /docs/<svc>/ (Q30). The content is a how-to for a regular user — no maintenance details (Q29). The pages are password-protected by the same auth as the homepage section they belong to (Q31). They are built as each service goes active (Q32). The docs link on a service points to its page. The existing reference docs in serverAppConfigs-docs/ are not linked from the homepage. They may contain secrets (Q22).
See Also
- Homepage Design Grilling — the decision log
- Caddy — the proxy that serves it
- Dankclaw Stack, Dankserver Stack — the services it lists