D
B
Black Manta INTERFACE SPEC
00

Interface specification

This ecosystem has no palette upstream. The living guide is generated from BLACK_MANTA_DESIGN.md, which is authoritative for interface behaviour, not colour.

Why no swatches
Tokens are only emitted for values the source document actually states. Inventing a palette here would make this site a second source of truth, so the contract is rendered instead.
Stack (locked)
FastAPI · HTMX · Alpine.js · Tailwind
from DESIGN §3
Profiles
local-lite · server-heavy
single codebase, capability probe
Modules
17
each degrades full → read-only → hidden
Auth
session + TOTP · OIDC SSO
never runs as root
Distribution
PyInstaller single binary
per-OS installers
01

Profiles

The two deployment shapes the interface has to survive.

local-lite
Windows / WSL2, macOS, desktop Linux · 127.0.0.1 · sqlite · no public TLS · firewall read-only or limited
server-heavy
Linux + systemd · 0.0.0.0:443 · letsencrypt · ufw/nftables enforce · sqlite → postgres · monitoring 30d
02

Module map

Every route in the suite, as declared by the source document.

Module table not found in the source document.

03

Terminal surface

xterm.js + PTY/ConPTY/WSL behind a full audit trail.

Audit-first
Every privileged action logs who / when / what / args / result. The interface must make that visible, not implicit.
04

Security model

Privilege
dedicated app user
minimal sudo allowlist helper
Session
auth + TOTP
CSRF / CSP / rate limits baked in
Idempotency
plan → apply → verify
re-runnable from wizard, API or CLI
05

Interface atoms

Atoms are inherited from the shared system shell and recoloured per ecosystem.

Button variants 5 variants
html
<button class="ax-btn ax-btn-primary">Primary</button>
<button class="ax-btn ax-btn-secondary">Secondary</button>
<button class="ax-btn ax-btn-outline">Outline</button>
<button class="ax-btn ax-btn-ghost">Ghost</button>
<button class="ax-btn ax-btn-danger">Danger</button>
Button sizes sm · md · lg
html
<button class="ax-btn ax-btn-primary ax-btn-sm">Small</button>
<button class="ax-btn ax-btn-primary">Medium</button>
<button class="ax-btn ax-btn-primary ax-btn-lg">Large</button>
Button states default · hover · focus · disabled
Text input & search
html
<input class="ax-input" placeholder="Search tokens...">
Checkbox, radio, switch
html
<label class="ax-checkbox"><input type="checkbox" checked> Enable token sync</label>
Badges & status
Neutral Accent Operational Degraded Offline Pill
html
<span class="ax-badge ax-badge-accent">Accent</span>
<span class="ax-badge ax-badge-success"><span class="ax-status-dot active"></span> Operational</span>
Links, keys & inline code
Anchor link with accent underline
Shortcuts ⌘K ESC --ax-accent
06

Interface molecules

Search field molecule
⌘K
html
<div class="ds-search-molecule">…</div>
Stat card molecule
98/100
Accessibility
24
Tokens
6
Variants
Feature card molecule
◆
Token pipeline
One normalized document feeds CSS, docs and the asset index.
◇
Derived ramp
Missing roles are computed from accent, ink and paper — and badged as derived.
Callouts & notes
Note
Derived values are marked so authored intent stays distinguishable.
Tip
Click any swatch to copy its value.
Warning
Contrast below 4.5:1 fails AA for body copy.
Tabs & chips molecule
Dark Reborn 3D Rose / Amber MU3
Table molecule
TokenValueStatus
--ax-accentbrand accentauthored
--ax-surface-2derived rampderived
Toast molecule
✓ Copied #FF6901 to clipboard
07

Interface organisms

Header organism brand mark · nav · ecosystem switcher · command palette
DBlack Manta
Overview Style Guide Assets Docs
⌘K
Hero organism
Living style guide

Black Manta

Dynamic server-admin suite · authoritative interface design

Terminal organism
build
$npm run build
▸ registry 4 ecosystems
▸ tokens 3 token documents
▸ assets 148 files
✓ dist generated in 0.4s
Matrix organism
SurfaceToken setTypographyAssets
Webfulldisplay + monosvg + png
Desktopfulldisplay + monoicns + png
CLImono onlymono—
08

Full authoritative document

Rendered verbatim from the source markdown.

#Black Manta — Dynamic Server-Admin Suite: Authoritative Design

Status: AUTHORITATIVE (v1.0 — initial design, 2026-09-15) Scope: local-lite on Windows / WSL, macOS, Linux ↔ server-heavy on Linux. Stack (locked): Backend FastAPI + HTMX + Alpine.js + Tailwind CSS · DB SQLite ↔ Postgres · Redis optional. Constraint: Write code files only under docs/ for this step. No implementation yet. Do not run as root.

#1. Goals & Non-Goals

#1.1 Goals

  1. One app, two profiles: run as a lightweight local admin GUI (local-lite) on a dev laptop (Windows/WSL, macOS, Linux) and as a full server-admin suite (server-heavy) on Linux servers.
  2. Dynamic capability model: every module probes the host OS / available providers at startup and degrades gracefully (full → read-only → hidden), driven by profiles + feature flags.
  3. No-SSH-required daily ops: overview, terminal, files, users, services, firewall, backups, files, TLS, logs,

behind a dark HTMX + Alpine.js UI and a FastAPI backend with OIDC SSO.

  1. Single-binary distribution: PyInstaller one-file binary per OS + thin OS installers (systemd unit / launchd plist / Windows service + shortcuts).
  2. Secure by default: never run as root; dedicated app user + minimal sudo-allowlist helper; session auth + TOTP; full audit log; CSRF/CSP/rate-limits baked in.
  3. Zero-to-managed in < 10 min: guided setup wizard (domain, TLS, ports, auth+TOTP, DB, firewall, backups, monitoring) that converges a fresh host to a managed state idempotently.

#1.2 Non-Goals (v1)

  • Not a config-management replacement (no Ansible/Puppet parity, no fleet orchestration — single-host focus; multi-host is future).
  • Not a full SIEM / APM (basic metrics + logs + alerts only; export to Prometheus/Loki where needed).
  • Not a container orchestrator (manage local Docker/Podman only, no Swarm/K8s scheduler).
  • Not a secrets vault HA cluster (single-host encrypted store + env/file sync; HashiCorp Vault interop later).

#1.3 Design principles

  • Provider abstraction over if platform == spaghetti. Each OS concern is a Provider interface with per-OS backends.
  • HTMX-first UI: server-rendered Jinja fragments + HTMX swaps + Alpine.js islands; JSON API only where the terminal/uploads/polling need it.
  • SQLite default, Postgres when serious: same SQLAlchemy models + Alembic migrations run on both.
  • Idempotent actions: every mutating operation is plan → apply → verify, re-runnable from wizard, API, or CLI.
  • Audit everything: every privileged or mutating action logs who/when/what/args/result.

#2. Profiles & Feature Flags

#2.1 Profiles

ProfileWhereWhat it isDefaults
local-liteWindows (native + WSL2), macOS, desktop LinuxPersonal admin console on 127.0.0.1; no public TLS, no LE, no public firewall editing; safe local opsauth.local_only=true, tls.mode=local-selfsigned-or-http, firewall.mode=read-only (Win/macOS) or limited (Linux desktop), jobs.scheduler=apscheduler-in-process, db=sqlite, redis=off, monitoring.retention=24h
server-heavyLinux server (systemd; Debian/Ubuntu primary, RHEL-family best-effort)Full suite on 0.0.0.0:443/80(+custom) behind TLS; LE, UFW/nftables, backups, monitoring retention, Postgres optionauth.totp_required=true, tls.mode=letsencrypt, firewall.mode=enforce, jobs.scheduler=systemd-or-apscheduler, db=sqlite→postgres, redis=optional-on, monitoring.retention=30d

Profile selection: --profile local|server CLI flag → persisted in config.toml ([profile] name=...) → overridable per-module by feature flags. Auto-detect suggests a profile at first run (Windows/macOS → local; Linux with systemd + CAP_SYS_ADMIN/server hints → ask server vs local).

#2.2 Feature-flag registry (config.toml [features] + env BLACK_MANTA_FEATURE_*)

toml
[features]
overview=true; terminal=true; files=true; users=true; services=true
network=true; firewall=true; packages=true; jobs=true; tls=true
backups=true; logs=true; monitoring=true; containers=true
databases=true; sites=true; secrets=true

# capability modifiers
[features.modes]
firewall="enforce|limited|read-only|off"   # local-lite Win/macOS defaults read-only
services_manager="auto"                    # auto | systemd | launchd | winsvc | wsl-passthrough | off
package_manager="auto"                     # auto | apt | dnf | brew | winget | off
terminal="on|off"                          # kill-switch for hardened servers
containers="docker|podman|off"
monitoring_retention="24h|7d|30d"

Resolution order per request: env override > config.toml > profile default > provider capability probe. UI hides disabled modules; API returns 403 FEATURE_DISABLED. A /api/capabilities endpoint exposes the resolved matrix so HTMX nav renders dynamically.

#2.3 Runtime capability probe

On boot (and on-demand "Re-probe" button) CapabilityService runs:

os → distro → init (systemd/launchd/service.msc) → fw (ufw/nft/pf/netsh) →
pkg (apt/dnf/brew/winget) → runtime (docker/podman) → le (certbot binary/webroot) →
pty (posix/conpty/wsl) → systemd-creds/keychain availability

Result cached in SQLite (capabilities table) + surfaced in Overview → "Host capabilities" card.


#3. Tech Stack (Locked)

  • Backend: FastAPI (async where I/O-bound; sync subprocess wrappers in anyio.to_thread).
  • Frontend: Jinja2 server templates + HTMX partial swaps + Alpine.js islands + Tailwind CSS (CDN in dev, compiled+vendored in binary).
  • Terminal frontend: xterm.js (+ xterm-addon-fit, xterm-addon-web-links); no Guacamole/extra deps.
  • DB: SQLAlchemy 2.0 + Alembic; SQLite (WAL) default, Postgres via DATABASE_URL for server-heavy. No raw SQL in routes — service layer only.
  • Cache/queue: Redis optional (session spillover, pub/sub for log tail + metrics fan-out, rate-limit backend). Absence → in-process asyncio queues + SQLite-backed locks. Feature-detect at boot.
  • Auth: session cookies (itsdangerous signed) + pyotp TOTP + argon2-cph password hashes. No JWT for browser sessions (JSON API tokens only for CLI, future).
  • Privileged helper: single black-manta-helper binary/script invoked via passwordless sudo allowlist (exact argv whitelist in /etc/sudoers.d/black-manta). Never run the app itself as root/Administrator.
  • Packaging: PyInstaller --onefile per OS (see §8).

Directory sketch (future, informative — not created in this step):

app/            # fastapi factory, routes, services, providers/
templates/      # jinja + htmx fragments
static/         # tailwind build, alpine, xterm
alembic/        # migrations (sqlite+postgres compatible)
black-manta-helper # privileged allowlist wrapper
config.toml     # profile + features + wizard outputs

#4. OS Provider Matrix

All OS interactions go through Provider ABCs. Routes/services never call subprocess/os directly.

ConcernInterfaceLinux (server-heavy ★)Linux desktopmacOSWindows nativeWSL2 path
ServicesServiceProvider list/start/stop/restart/enable/logs★ systemd (systemctl, journal)systemd --user + systemlaunchd (launchctl, plist in ~/Library/LaunchAgents + /Library/LaunchDaemons read-only)winsvc (sc.exe / PowerShell Get-Service), read-only for system svcs by defaultWSL passthrough: query wsl.exe systemctl from Win side; full control inside WSL distro itself
FirewallFirewallProvider status/rules/allow/deny★ UFW primary, nftables fallback/directUFW limited (no lockout guardrails relaxed)pf read-only default (pfctl -s), apply = edit /etc/pf.conf + reload via helper onlyDefender Firewall via netsh advfirewall read-only default; apply behind explicit flagManage inside WSL (UFW/nft) separately from Windows host FW
PackagesPackageProvider search/install/update/list★ apt (Debian/Ubuntu), dnf best-effortsame as serverbrewwingetWSL distro's apt/dnf; Win side winget listed separately
UsersUserProvider list/create/disable/ssh-keys★ useradd/usermod, /etc/passwd UID≥1000 filtersamedscl read + create (helper)net user / PowerShell LocalUser, read-only defaultWSL /etc/passwd
Jobs/CronJobProvider★ systemd timers preferred, cron fallbackcron + APSchedulerlaunchd plists + cronTask Scheduler read-only v1 (schtasks /Query)cron inside WSL
NetworkNetworkProvider addrs/ports/listenersip + sssameifconfig + netstat/-pipconfig + Get-NetTCPConnectionboth namespaces shown, labeled
TLS/LETlsProvider★ certbot webroot (see §10 context)self-signed local CAself-signed local CAself-signed (certmgr)certbot inside WSL/Linux only
PTYPtyProviderposix fork+execsameposix (login shell)ConPTY (Win10+) via pywinpty, else WSL bridgewsl.exe bridge from Win app
Secrets storeSecretBackendfile+SQLite (0600) + systemd-creds optfile+SQLiteKeychain (read/write user scope)DPAPI/CredMan user scopefile+SQLite inside WSL

Rules:

  1. auto resolves per probe; admin can pin (services_manager=systemd etc.) to fail fast instead of silently degrading.
  2. Destructive cross-OS actions (firewall apply on Win/macOS, service stop on services.msc system set) require typing the target name (confirm-gate) + audit entry.
  3. WSL is always labeled: UI shows WIN vs WSL:Ubuntu badges; actions explicitly target one side.

#5. Module Army (17 Modules)

Common module contract: GET /<mod> page + GET /api/<mod>/ fragments/JSON + POST /api/<mod>/ mutations (HTMX or JSON) + capability gate + audit hook. All list views HTMX-paginated; all mutations return an HTMX toast fragment + HX-Trigger: audit,refresh.

#5.1 Overview (/, always on)

Host card (OS, kernel, uptime, load), capability matrix, resource sparklines (CPU/RAM/disk), attention list (failed systemd units, expiring certs, updates pending, firewall off on server profile → red banner), quick links. Poll via HTMX hx-trigger="every 5s" → /api/overview/stats (Redis pub/sub if present, else direct).

#5.2 Terminal (/terminal)

See §6. Kill-switch features.terminal. Hidden entirely when off.

#5.3 Files (/files)

Sandboxed browser rooted at allowlisted roots (/srv, /var/www, /home/*, C:\srv / %USERPROFILE% equivalents). Upload/download (chunked), editor (Monaco-lite/textarea v1), perms view, zip/unzip via helper. No symlink escape (realpath check). HTMX tree + Alpine preview.

#5.4 Users (/users)

List human users (UID 1000+ Linux / LocalUser Win / dscl macOS), create/disable, SSH key management (~/.ssh/authorized_keys), sudo-group visibility (read-only; membership change via helper + confirm-gate). Context: live system uses UIDs 1000–1004 — design the table to show UID, shell, last login, sudo membership.

#5.5 Services (/services)

systemd units (active/failed/enabled), journal tail (journalctl -u), start/stop/restart/enable via helper; launchd/Win mappings per matrix. Failed-units alert feeds Overview.

#5.6 Network (/network)

Interfaces/addresses, listeners (ss -tulpn / Win equivalent), port-check card, reverse-DNS hover. Read-only v1 except "open port in firewall" deep-link to Firewall module.

#5.7 Firewall (/firewall)

UFW-first UX (allow 22,66,80,443/tcp style presets + custom), dry-run → apply two-step on server profile, lockout guard (refuse to close current management port/session IP without override + countdown revert). Win/macOS/pf default read-only with "export rules" action. Context: live UFW allows 22, 66, 80, 443 — preset "ServeBeer standard" encodes exactly this.

#5.8 Packages (/packages)

Updates-pending count, search/install/upgrade via provider, reboot-required flag (/var/run/reboot-required), activity log. Server profile holds unattended-upgrades status card.

#5.9 Jobs (/jobs)

Cron + systemd timers (+ Task Scheduler/launchd read views) unified list; create cron entries via validated builder (no raw crontab paste in UI v1); run-now + last-exit-code; APScheduler for app-internal tasks (cert renew check, backup schedule).

#5.10 TLS/LE (/tls)

Domains → certs table (issuer, SANs, expiry bar), issue/renew via certbot webroot against configured webroot (context: /var/www/acme), self-signed generator for local-lite, deploy hooks (reload nginx/caddy/app), expiry alerts at 21/7/1 days. Private keys never leave server; UI shows metadata only.

#5.11 Backups (/backups)

Sources → destinations (local dir | rsync/ssh | S3-compatible), schedule, retain-last-N, one-click restore to staging path + checksum verify, pre/post hooks (e.g. pg_dump). v1: restic if present else tar+zst+gpg fallback via helper.

#5.12 Logs (/logs)

Journal/file tail with follow (SSE), grep filter, download slice. Audit log is separate, always-on, immutable-append (audit table + optional JSONL mirror).

#5.13 Monitoring (/monitoring)

CPU/RAM/disk/net sparklines, systemd-failed + cert-expiry + disk->90% alerts, uptime checks (HTTP ping list), notification channels (email/webhook v1). Retention by profile (24h local → 30d server). Prometheus /metrics exposition optional-behind-flag.

#5.14 Containers (/containers)

Docker/Podman (whichever socket present): containers/images/volumes, start/stop/logs/exec (exec reuses terminal pipeline, container-scoped), compose-file viewer (no apply in v1). Off when no runtime.

#5.15 DBs (/databases)

SQLite browser (app + user DBs under allowlisted paths) + Postgres (connection manager, pg_dump/restore, table row browser paginated). Credentials live in Secrets module; connection test button; destructive SQL requires confirm-gate + audit + (server profile) TOTP re-auth.

#5.16 Sites (/sites)

Reverse-proxy vhosts (nginx/caddy) list, enable/disable, docroot mapping, per-site LE selector (→ TLS module), basic-auth toggle, config test (nginx -t) + reload via helper. Context: dashboard site adm.servebeer.com on 443/80 (+ custom 66) is the reference vhost shape; static stdlib dashboard stays as-is, Black Manta links to it.

#5.17 Secrets (/secrets)

Env-file editor per site/app (scoped, masked), password generator, file-permission fixer (0600), sync-to-service (restart site worker). Backends per matrix (file+SQLite / Keychain / DPAPI). No plaintext in logs; values redacted in audit.


#6. Terminal Design (xterm.js + PTY/ConPTY/WSL, Audit)

  • Frontend: xterm.js canvas + fit + web-links addons, Alpine store for session list, HTMX only for the terminal page shell — the PTY stream itself is WebSocket (/ws/pty/{id}), binary-msgpack or JSON {t:"i|o|r", d:...} frames.
  • Backends (PtyProvider):
  • Linux/macOS: forkpty-style pty module + login shell ($SHELL -l), curses-safe TERM=xterm-256color, resize via TIOCSWINSZ.
  • Windows native: ConPTY via pywinpty (powershell.exe default, cmd.exe fallback); Win7/older → hidden module with "use WSL" hint.
  • WSL bridge: wsl.exe -d <distro> -- <shell> spawned from Win app; labeled WSL:… in tab.
  • Multiplexing: one FastAPI WS per tab; server-side session registry (max 4 tabs local / 8 server default, configurable); idle kill (15 min) + absolute cap (8 h); reconnect resumes scrollback (last 10k lines ring buffer in Redis if present else memory).
  • AuthZ: requires authenticated session + (server profile) fresh TOTP (≤15 min) or re-prompt; features.terminal=off kills WS with 4403.
  • Audit: per-session transcript (output truncated at 1 MB/session, env/secrets redaction filters) + command-level log (shell integration via PROMPT_COMMAND/precmd best-effort; keystroke log explicitly out of scope). Audit viewer replays scrollback read-only.
  • Safety: no root shell — PTY runs as app user; privilege escalation only via sudo black-manta-helper … inside the shell (still allowlisted + logged). Paste-confirm for multi-line pastes; rm -rf /-style denylist warns (not blocks, to avoid false security).

#7. Setup Wizard (/setup, first-run + re-runnable)

Trigger: no config.toml OR setup_complete=false → redirect all routes to /setup. Steps are idempotent; each step = probe → form (prefilled) → plan-preview → apply → verify.

  1. Welcome + profile: detect OS, recommend local-lite vs server-heavy; choose + set data dir.
  2. Domain & ports: hostname, admin domain (e.g. adm.example.com), HTTP/HTTPS + extra port (note: reference system uses 443/80 + custom 66 — wizard supports one extra TCP port field, validated against firewall), local-lite skips to 127.0.0.1:<port>.
  3. TLS: letsencrypt-webroot | self-signed | bring-your-own; webroot field (prefill context default /var/www/acme on Linux server), email, staging-toggle; verify = fetch cert metadata.
  4. Auth + TOTP: create admin user (argon2), enforce TOTP on server profile (QR + backup codes), session lifetime, fail2ban/rate-limit toggle.
  5. Database: sqlite (path) vs postgres (host/port/db/user/secret-ref) + connection test + migrate.
  6. Firewall: show probed provider; preset buttons (ServeBeer standard: 22/66/80/443, Web: 80/443, Custom); dry-run diff; lockout-guard acknowledgment; apply (server) or document-only (local read-only).
  7. Backups: destination, schedule, retention, test-snapshot.
  8. Monitoring: retention, alert email/webhook, uptime checks seed.
  9. Review & apply: single plan summary → Apply all → verify checklist → mark setup_complete=true, write config.toml, emit audit setup.complete.

CLI parity: black-manta setup --non-interactive --config seed.toml for scripting.


#8. Packaging (PyInstaller Single-Binary per OS + Installers)

  • Build: PyInstaller --onefile --name black-manta-<os>-<arch> from a versioned tag; vendor static/ (compiled Tailwind, Alpine, xterm), Jinja templates, Alembic, black-manta-helper; bundle certbot NOT included (system package dependency on server).
  • Matrix: linux-x86_64 (★ primary), linux-aarch64, macos-arm64, macos-x86_64, win-x64 (+ WSL note). GH Actions one workflow per target; smoke test = boot --profile local --port 0 + hit /api/health.
  • Installers (thin, per OS):
  • Linux: .deb (or install script) → /opt/black-manta/black-manta + black-manta app user + systemd unit + /etc/sudoers.d/black-manta allowlist + /etc/black-manta/config.toml.
  • macOS: .pkg/zip → /Applications/Black Manta.app-ish (binary + plist for launchd, runs as user, port 127.0.0.1).
  • Windows: Inno Setup / WiX → C:\Program Files\Black Manta\ + service entry (or autostart tray) + Defender FW loopback note + "open WSL distro" option.
  • Updates: in-app version check + "download + verify sig + restart" button (server) / installer re-run (desktop). Config + DB + secrets survive upgrades (paths versioned, migrations forward-only).

#9. Security Model

  • No run-as-root, ever. App runs as dedicated unprivileged user (black-manta on Linux server; user account on desktop). CI asserts: if os.geteuid()==0 → refuse to start unless --allow-root-for-tests.
  • Privilege boundary: exactly one escalation path — sudo -n /opt/black-manta/black-manta-helper <verb> <allowlisted-args>. Helper is a small audited script (argparse, no shell, path-pinned binaries like /usr/sbin/ufw, /bin/systemctl), logs every invocation to the audit trail + syslog. Sudoers allows only those verbs:

systemctl * black-manta-managed-units, ufw ..., certbot ..., nginx -t/-s reload, restic/tar ..., useradd/usermod (constrained), reboot-required-check.

  • Auth: session cookie (HttpOnly; SameSite=Lax; Secure on server profile) + argon2 passwords + mandatory TOTP on server-heavy (optional on local). Rate-limit login (5/min/IP, Redis-backed if present else in-memory), lockout + audit auth.failed. CLI/API tokens scoped + hashed at rest.
  • Web hardening: CSRF tokens on all HTMX POSTs, strict CSP (no inline scripts except Alpine nonces), X-Frame-Options: DENY, secure static caching, upload MIME/size caps, path-traversal + symlink guards on Files/Backups/Sites roots.
  • Secrets hygiene: masked in UI/API/logs; encrypted-at-rest option (Fernet key from OS store: systemd-creds/Keychain/DPAPI, fallback file 0600); rotation helper for DB + site keys.
  • Audit: append-only audit table (ts, actor, ip, module, action, args-redacted, result) + tamper-evident hash chain (each row hashes previous); admin can export, never edit/delete from UI.

#10. Reference: Existing Live System (Context Only — Do Not Enshrine)

The currently-running server is context for defaults and migration, not the target architecture. Black Manta must interoperate with it, not reimplement it:

  • Dashboard: https://adm.servebeer.com — plain-stdlib Python page (no framework); listens on 443, 66, 80 (custom 66 is load-bearing — wizard/firewall presets must include an "extra port" field defaulting to support it).
  • Firewall: UFW allowing 22, 66, 80, 443 — encode as preset ServeBeer standard (§5.7, §7 step 6).
  • TLS/LE: webroot /var/www/acme for certbot — prefill as default webroot on Linux server profile (§5.10, §7 step 3).
  • Users: human UIDs 1000–1004 — Users module table must handle this range cleanly (UID column, sudo flags, last-login).
  • Posture: Black Manta links to (not replaces) the stdlib dashboard during migration; Sites module models adm.servebeer.com as the reference vhost; no behavior of the live box may be broken by install (lockout-guard + dry-run mandatory).

#11. Open Decisions & Roadmap

  • v1 cut: Overview, Terminal, Files, Services, Firewall(UFW), TLS(webroot), Users, Jobs(cron), Logs, Packages(apt), Backups(tar/restic), Monitoring(basic), Sites(nginx), Secrets(file), Containers(read-mostly), DBs(sqlite+pg-basic), Network(read).
  • v1.1: Postgres hardening, S3 backups, Win/macOS firewall apply, Task Scheduler write, Podman parity.
  • Future: multi-host view, OIDC/SSO, Vault backend, Prometheus-native metrics, mobile-friendly terminal.
  • Decisions needed: helper language (Python vs Go for static binary), xterm stream encoding (JSON vs msgpack), HTMX+SSE vs WS for log tail.

End of authoritative design. Implementation must follow profiles (§2), provider matrix (§4), terminal (§6), wizard (§7), packaging (§8), and security model (§9).