The running view showed one fixed line for up to 15 minutes, which reads as a
hang. js/running-status.js maps elapsed run time to a line, starting neutral
("Searching Confluence…") and getting more playful at 20 s, 1, 2, 4, 7 and 11
minutes, in the same register as the Exit queue button. app.js re-evaluates
the line every 5 s from wall-clock time (correct after background-tab
throttling), restarts the clock when the running state is entered after a
queue wait, and stops the ticker when the view leaves the running state. The
backend streams no progress, so no line claims a specific activity.
Submit joins the admission queue first and sends the PAT only once the
reservation is held. Queued state shows the shaping orb, ordinal position
with estimate, and an exit button whose label changes with the wait;
running switches the orb to solving. Rejoin once on a lost reservation or
ticket, best-effort leave on pagehide. Mock server gains the queue
endpoints and five scenarios; contract, unit and e2e tests cover them.
In-memory AdmissionController (idle/reserved/running, FIFO tickets keyed by
the session cookie, reservation and heartbeat expiry, promotion after
cleanup, EMA wait estimate) behind POST /api/v1/queue/join,
GET /api/v1/queue/status and DELETE /api/v1/queue/ticket. POST /api/v1/query
claims the session's reservation first and joins implicitly when idle.
Settings: CONFLUENCE_WEB_QUEUE_{RESERVATION_SECONDS,HEARTBEAT_SECONDS,MAX_LENGTH}.
The 180 s query cap was enforced independently by the backend clamp, the
agent limits, and the container supervisor. All three now follow
CONFLUENCE_WEB_MAX_DEADLINE_SECONDS (default 900, allowed 60-3600): the
backend passes it into the container at launch, the supervisor reads it and
forwards it to the bridge, and both fall back to 900 s on invalid input. The
query timeout must not exceed it (startup fails otherwise). The supervisor
keeps a separate 180 s guard for a container that never receives a start
frame.
Add assets/book.svg as the tab icon: the backend serves assets/ and the CSP
allows same-origin images (the sanitizer still never emits <img>).
Replace the gear spinner with the thinking-orbs canvas engine (vendored
framework-free build, driven by js/orb.js in the "solving" state) and the
inline SVG brand icon with a pure CSS book whose cover flips open on page
load and while the brand is hovered (js/logo.js).
scripts/make-tls.sh creates a CA whose critical nameConstraints permit only the
listed IPv4 addresses (and the .invalid DNS subtree), plus an end-entity server
certificate; run-backend.sh passes CONFLUENCE_WEB_TLS_CERT/KEY to uvicorn.
- tests/integration: frontend served by backend, runtime error mapping,
backend + real pi image with scripted model/Confluence (shared example,
variants, failure paths, cancellation/busy gate, isolation canaries,
HTTP download ownership, 16 MiB prompt round trip), real OpenAI-compatible
adapter + real image over a scripted transport, real Chrome against the
real backend with a scripted runtime peer, backend crash/restart
reconciliation, and an opt-in live model check (marker: live).
- backend: map runtime terminal codes (model_output_limit,
model_context_exceeded, query_timeout, connectivity_failed) to the
contract's HTTP statuses; make the artifact 404 body identical for
no-session, wrong-session, unknown and expired IDs.
- Makefile, scripts/run-backend.sh, deploy/confluence-web.env.example,
root README for the integrated application; integration pytest marker.
- Drop --init so the image supervisor stays namespace PID 1, as the
runtime handoff requires; add --memory-swap=1g and nosuid,nodev tmpfs
options to match the runtime's tested launch flags.
- Mount only frontend css/, js/ and vendor/ at the root origin so
index.html's relative asset paths resolve; dev/tests are not exposed.
- Add X-Content-Type-Options: nosniff to every response.
- Add CONFLUENCE_WEB_CONFLUENCE_PROXY (socks5/http, Confluence only) and
CONFLUENCE_WEB_MODEL_TIMEOUT_SECONDS; disable environment proxy
inheritance for both upstream clients; add socksio dependency.
Static frontend with vendored marked/DOMPurify, bounded Markdown
pipeline, same-origin mock server with scenario selection, unit,
contract and CDP end-to-end tests under frontend/**.
FastAPI app, upstream Confluence/model adapters, authoritative history,
rootless container lifecycle, artifact storage and downloads, fake peers
under backend/dev, tests under tests/backend. Root pytest.ini deselects
the live marker by default; requirements gain the backend dependencies.
Pinned pi SDK 0.85.1 bridge, Python supervisor, artifact exporter,
scripted backend peer, image checks and boundary checks under agent/**.
Review findings F1-F3 are recorded in docs/implementation/PI_AGENT_REVIEW.md.