Every internal failure was mapped to a fixed sanitized code before anything
recorded the cause, so an intermittent execution_failed was undebuggable: an
exhausted model-call budget, a model turn with no text, and a genuine crash all
looked identical.
The bridge now writes one bounded line to container stderr on failure with the
code, the internal reason, the state and both call counters, and the failure
sites pass a reason (budget exhausted, empty final answer with its content block
types, token counts against the limits). The wire error is unchanged.
The backend logs the agent's terminal code together with its own call counters,
and the sanitized tail of container stderr rather than only its byte count.
deploy/logging.json gives every logger a timestamp (uvicorn's default config
leaves non-uvicorn loggers on logging's fallback handler); override with
CONFLUENCE_WEB_LOG_CONFIG.
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>).
- 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.
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.