Oikos Console v0 (oikos/console/) — read-mostly, server-rendered FastAPI
+ Jinja2 web UI, no SPA build chain. Signals landing page, service grid
+ detail, node/blast-radius view, live Mermaid relationship graph, drift
findings, approvals queue (approve/deny, destructive confirmation-phrase
enforced), daily/weekly reports. Tested end-to-end via the preview tools
against live production data, including a real click-through of the
approve/deny flow.
Found and fixed two bugs during that testing:
- Severity-dot CSS classes didn't match the actual severity strings
(dot-warn/dot-crit vs "warning"/"critical") — warning-severity signals
rendered with no visible indicator at all.
- The console's sys.path setup pointed at its own webhook checkout
(/opt/oikos-console) rather than /opt/homelab-context, which would have
made its oikos.* imports resolve to a SEPARATE copy of oikos/signal.py
etc. than the scheduler and CLI use — silently forking signal/approval
data into two locations in production. Fixed to match mcp/server.py's
CONTEXT_DIR pattern. Also added _commit_push() so the console's writes
(approval replies, signal ack/resolve) don't sit uncommitted against
the 5-min-synced clone.
Split oikos/gen_topology_lib.py out of oikos/gen-topology.py (hyphenated
filenames aren't importable) so the console's /graph route can render
live without shelling out.
oikos/console/deploy/ — third webhook on dtoro/Homelab-Docs (port 9831),
matching the homelab-mcp/secrets-issuance precedent. README documents the
Caddy route and Gitea webhook registration this repo can't do for itself,
and that Authentik step-up on /approvals needs a live instance to
configure.
Approval hardening: grants are now single-use (oikos/approve.py
check_grant marks the request "executed" atomically, so a second call
for the same id fails even within the TTL) — verified with a test. Per-
agent age-key-signed requests, as originally planned, turned out not to
be buildable as stated: age is encryption-only, no signing primitive.
Documented the real alternative (SSH-key signing) and moved it to the
60/90-day backlog pending an inventory schema gap (no SSH pubkeys
recorded today).
Docs pass: added the Oikos command surface to operations/commands.md,
new MCP tools to AGENTS.md. Found two more stale references while at
it — commands.md and AGENTS.md both still pointed DNS at the destroyed
LXC 124/dnsmasq instead of Technitium on dns (107), and a claudio-monitor
reference deprecated since 2026-06-04 — fixed both.
60/90-day backlog written into OIKOS.md, derived from gaps actually
observed this month, not guesswork.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>