"""Console Board v2 (/board, L19), UI chrome, and agent discovery routes."""
from __future__ import annotations
import re
import subprocess
from pathlib import Path
from typing import Any
from fastapi.testclient import TestClient
from tessera import ChildSpec, QueueConfig, Store, TaskSpec
from tessera.access import ServiceSettings
from tessera.service import create_app
_ROW_RE = re.compile(r"
(.*?)
", re.DOTALL)
_COL_RE = re.compile(r"([^<]*) | ")
def _parse_board_queue_counts(html_text: str) -> dict[str, dict[str, int]]:
parsed: dict[str, dict[str, int]] = {}
for q_name, inner in _ROW_RE.findall(html_text):
cols = dict(_COL_RE.findall(inner))
parsed[q_name] = {
state: int(cols[state])
for state in ("ready", "leased", "waiting", "done", "dead", "cancelled")
}
return parsed
def test_board_matches_counts_on_empty_and_populated_fabric(tmp_path: Path) -> None:
db_path = tmp_path / "board.db"
store = Store(db_path)
admin_secret, _ = store.issue_key("admin", queues=["*"], scopes=["admin", "store"])
worker_a_secret, worker_a_grant = store.issue_key(
"worker-a", queues=["*"], effect_classes=["read", "write-internal", "write-repo"]
)
app = create_app(store, ServiceSettings(db_path=str(db_path), reaper_seconds=3600))
with TestClient(app) as client:
# 1. Empty board renders cleanly with zero queues and zero write controls.
empty_resp = client.get("/board")
assert empty_resp.status_code == 200
empty_html = empty_resp.text
assert "No queues yet." in empty_html
assert "Live Verb Queues" in empty_html
assert "Task Dependency & Split Wave DAG" in empty_html
assert "Parked Tiles" in empty_html
assert "Monotonic Cursor Event Feed" in empty_html
assert ".table-wrap{overflow-x:auto" in empty_html
counts_empty = client.get(
"/v1/counts", headers={"authorization": f"Bearer {admin_secret}"}
).json()["queues"]
assert _parse_board_queue_counts(empty_html) == counts_empty
# 2. Populate all states, split waves, dependencies, parked tiles, and delta feeds.
store.define_queue(QueueConfig(name="alpha", max_attempts=1))
store.define_queue(QueueConfig(name="beta", max_attempts=3))
# Done task + dependent task (waiting on another unresolved task)
t_done = store.enqueue(TaskSpec(queue="alpha", brief={"step": "done"}))
l_done = store.claim("alpha", "w1", key_id=worker_a_grant.key_id)
assert l_done is not None
store.submit(
t_done,
l_done.fencing_token,
{"ok": 1},
idempotency_key="b-done",
completed_by_key=worker_a_grant.key_id,
)
# Dead task (max_attempts=1 on alpha)
t_dead = store.enqueue(TaskSpec(queue="alpha", brief={"step": "fail"}))
l_dead = store.claim("alpha", "w1", key_id=worker_a_grant.key_id)
assert l_dead is not None
store.submit(
t_dead,
l_dead.fencing_token,
{"err": 1},
idempotency_key="b-dead",
ok=False,
error="boom",
completed_by_key=worker_a_grant.key_id,
)
# Cancelled task
t_cancel = store.enqueue(TaskSpec(queue="alpha", brief={"step": "cancel"}))
store.cancel(t_cancel, "no longer needed")
# Parked task (waiting for input)
t_park = store.enqueue(TaskSpec(queue="beta", brief={"step": "park"}))
l_park = store.claim("beta", "w1", key_id=worker_a_grant.key_id)
assert l_park is not None
store.park(t_park, l_park.fencing_token, reason="awaiting reviewer", resume_within=600)
# Split parent + wave children (child 0 ready, child 1 waiting on child 0)
t_parent = store.enqueue(TaskSpec(queue="beta", brief={"step": "split"}))
l_parent = store.claim("beta", "w1", key_id=worker_a_grant.key_id)
assert l_parent is not None
kids = store.split(
t_parent,
l_parent.fencing_token,
[
ChildSpec(brief={"wave": 1}),
ChildSpec(brief={"wave": 2}, after=[0]),
],
)
# Leased task (claim child 0) + ready task + dependent task
l_kid0 = store.claim("beta", "w2", key_id=worker_a_grant.key_id)
assert l_kid0 is not None and l_kid0.task_id == kids[0]
t_ready = store.enqueue(TaskSpec(queue="beta", brief={"step": "ready"}))
t_dep = store.enqueue(
TaskSpec(queue="alpha", brief={"step": "dep"}, depends_on=[t_done, t_ready])
)
# Monotonic feed entry
store.publish_feed("ops.live", {"tile": t_ready}, summary="queued ready tile")
# 3. Verify every queue's counts on /board match GET /v1/counts (L19).
board_resp = client.get("/board")
assert board_resp.status_code == 200
board_html = board_resp.text
api_counts: dict[str, Any] = client.get(
"/v1/counts", headers={"authorization": f"Bearer {admin_secret}"}
).json()["queues"]
board_counts = _parse_board_queue_counts(board_html)
assert board_counts == api_counts
# Verify DAG, Parked Tiles, and Feed entries appear in the read-only HTML.
assert t_parent in board_html and t_dep in board_html
assert t_park in board_html and "input" in board_html
assert "ops.live" in board_html and "queued ready tile" in board_html
# Strictly read-only: zero forms, inputs, textareas, or buttons on /board, and zero leaked secrets.
for forbidden_tag in ("