"""LAN-only, READ-ONLY web status dashboard for the agent-team coordinator. The agent-team is a single durable LangGraph pipeline; "agents" here are the per-stage model roles, and what an operator actually wants to see is *which task is in which phase* and *which tasks are blocked on the human gate*. This module serves that view as a tiny self-refreshing HTML page so Adam can glance at the queue without SSHing to the R720 and running ``run-team.py list``. Posture (read this before changing anything): * **READ-ONLY.** The page exposes no mutating endpoints. The SQLite ledger is opened read-only (``mode=ro`` / ``immutable``-safe URI) and never written. It reads the same two durable sources the coordinator owns: - ``pending_questions`` (the human-interaction lifecycle ledger) for "who is waiting on what" — reused via :mod:`agent_team.ledger`. - the LangGraph SQLite checkpoint (``channel_values`` holds ``task``, ``current_phase``, ``status``) for each task's phase/description — read through the same :class:`SqliteSaver` the coordinator uses in :func:`agent_team.graph.build_sqlite_checkpointer`. * **Sensitive content.** Task descriptions are operator input and may contain sensitive detail (repo names, ticket content, remediation context). The page renders them in plain text with HTML-escaping but applies NO authentication. It must therefore stay **LAN/VPN-only and never public**. The sh-secrev R720 VM (10.10.60.120, VLAN 60) has no public NIC and sits behind the UniFi firewall, so binding ``0.0.0.0`` exposes it to the LAN/VPN only. No secrets, tokens, channel refs, or answer bodies are rendered. * **Fail-safe.** A missing, locked, or unreadable DB renders a friendly "no data" page; the server never crashes on a bad read. The page is a live visual pipeline map: server-rendered inline SVG of the agent-team DAG (``INTAKE -> CLARIFY (human gate) -> PLAN <-> REVIEW -> [BUILD -> VERIFY -> DISPATCH] -> DONE``), with each stage coloured by live state and badged with a task count. Vanilla inline JS polls a JSON sidecar endpoint (``GET /api/state``) every few seconds with ``fetch()`` and updates the node states, counts, tooltips, and "last updated" clock *in place* — no full-page reload, so hover and scroll survive the refresh. A ``