RFC 0016: Fleet Console and Status Surface
Summary
A single agent-readable status endpoint, a minimal HTML console, and a browser-friendly per-app verifier page — so the operator (and Claude) can see at a glance what is deployed, what version it is pinned to, whether it is actually running, and so an attested app can be shown to a relying party via a URL.
Problem
The pinning data already exists. proxy/projects.py records commit_sha, tree_hash, image_digest, deployed_at, source, ref, runtime, and mode per project in project.json. But the only way to read it is GET /_api/projects/<name>, which returns raw JSON behind the admin token, one project at a time. There is:
- No aggregate view.
GET /_api/projectslists projects andGET /_api/routeslists routes, but neither joins manifest metadata with live container state into one picture. - No liveness/health signal in the manifest view.
GET /_api/routesalready distinguishes a running backend from “runtime not running” by inspectingrtm.image_cidsand the runtime containers — butGET /_api/projectsdoes not carry that, so you can’t tell from the inventory whether an app is actually up. - No human-facing presentation. RFC 0015 made
/_api/attest/<name>and/_api/verification/<name>public for attested projects, but they return JSON. There is no page you can hand someone that renders “this app is running commit X / tree Y, here is the dstack quote, here is the audit trail.” (The oldapps/router-dashboardwas a personal app, not a platform demo, and now lives in the separatewebhost-appsrepo.)
The result: the operator cannot answer “what do I have running and at what version” without curling per-project JSON, and cannot show an attested app to anyone without walking them through API calls.
Files to Modify
proxy/ingress.py— newGET /_api/statusaggregator; serve the console HTML; add an HTML rendering of the existing verification bundle.proxy/runtimes.py— factor the running/backend resolution used byGET /_api/routesinto one helper so status and routes share a single source of truth for liveness.- New static asset (
proxy/console.htmlor underassets/) for the console page.
Implementation
- One liveness helper. Extract the logic
GET /_api/routesuses to resolve a project to{running, container_id, backend}(the same check that emits “runtime not running”) into a function inruntimes.py. Both routes and status call it — no second copy of the liveness rule. GET /_api/status(authed, same gate as theGET /_api/projectslist). For each project fromProjectStore.list(), return the manifest fields a human cares about —mode,runtime,source,ref,commit_sha,tree_hash,image_digest,deployed_at,port/listen— joined with the live{running, container_id, backend}. For attested projects, include the public verification URL.- Console page (
GET /_api/console, authed): a single static HTML page that fetches/_api/statusand renders a table grouped bymode, with a health dot (running/stopped), short commit + short digest, relativedeployed_at, and links to the app URL, the verification page (attested only), and the audit log. No framework — plain HTML + fetch, matching the existing app style. - Per-app verifier page — the “show someone” deliverable. Add an HTML rendering of the existing RFC 0015 verification bundle, e.g.
GET /_api/verification/<name>?format=html(public for attested, same rule as the JSON form). It renders manifest + quote + audit into a readable page: what commit is running, the tree hash to check against GitHub, the dstack quote, and the audit log since promotion. This adds no new trust data — it is a view over what 0015 already serves.
Testing & Validation Requirements
GET /_api/statuslists every project with a correctrunningflag; stopping a runtime container flips that project torunning: falseon the next call.- The
runningflag for a given project agrees with whatGET /_api/routesreports (shared helper). - For an attested project, the verifier page returns 200 to an anonymous caller; for a dev project it 404s (consistent with RFC 0015).
- The console renders the table and the health dots from a live
/_api/status.
Report Requirements
curl /_api/statusoutput for a mixed dev/attested fleet.- The rendered console (HTML or screenshot) and a rendered verifier page for one attested app.
- Diff showing the liveness helper is defined once and used by both
/_api/routesand/_api/status.
Out of Scope
- Historical metrics, time-series, or graphs (request logging is RFC 0006).
- Any write/mutating action from the console — it is read-only; deploy/teardown stay on the existing API.
- A management-API auth UI (token is fine, per RFC 0001 non-goals).