Instrument browser-facing service boundaries, distinguish health from readiness, restore durable data, and keep secrets out of logs and support bundles.
Operations completes the user path. A browser needs an actionable degraded state, an operator needs bounded metrics and dependency probes, and a support bundle must explain failure without exporting tokens or private code. This chapter connects those concerns to the running FastAPI service, SQLite and artifact directories, structured redaction, and a restore drill.
Redaction is a boundary
A token can appear in an exception, an HTTP header, an environment dump, or a copied request. Scrub at the logging and bundle boundary, not only at call sites. The scrubber should be tested with seeded secrets and strings that resemble real credentials.
A fuzzed regression should generate variants of key names, token lengths, JSON nesting, and exception messages. The invariant is simple: seeded secret values never appear in emitted logs or bundles. Redaction can over-match, so inspect usability as a second metric.
Health, readiness, and metrics answer different questions
/healthz asks whether the process can answer HTTP. /readyz probes whether the session repository and artifact store can serve work. /metrics exposes low-cardinality counters such as sessions created, runs started, and artifacts uploaded. Session ids, raw paths, prompts, and error strings never become metric labels.
The browser should translate a failed request or disconnected socket into a visible offline or degraded state. It should not replace an unavailable API with an empty session list, because that makes dependency failure look like data loss.
The counters identify request volume without exposing a user’s session. Readiness can fail while health remains green, which tells a process supervisor that restart may not repair an unavailable dependency. A deployment should add latency histograms, active WebSockets, queue depth, replay count, and error classes with bounded labels.
Backup and restore the durable boundary
A backup is a claim that a future restore will recover coherent browser-visible state. Stop or coordinate writes, copy the SQLite database, journal, and artifact directory, restore into a different location, start the service against that location, and compare session ids, event ids, cursors, and artifact digests through the API. Never overwrite the source during a drill.
The copy helper supports the local drill; production backups need snapshot consistency, encryption, retention, access control, and scheduled restore probes. After restore, load the application through REST and WebSocket replay rather than only checking that files exist. The capstone records both the backup artifact and the browser-visible recovery evidence.
Exercises
Seed a debug bundle with a token, a private path, and an exception. Add a scrubber test that proves the token is absent from every archive member, then document which fields are intentionally retained for diagnosis and which are dropped.
[P11.1] Bound a debug bundle
Choose three fields to retain and three to drop from a support bundle. Add the redaction invariant and a restore check.