Observability & Resilience

This is the standard the Quality Gate's Reliability lens holds running systems to. It fills in the concrete defaults behind the observability and resilience principles the Infrastructure Planning Policy states (Β§1-5 Reliability and Delivery Are Measured, Β§1-6 Observability Is Built In): that policy says what we hold to β€” emit structured logs, metrics, and traces; hold an SLO; design with timeouts, retries, circuit breakers, and health checks β€” and this page says how: the exact log schema, the timeout and retry defaults, and what is allowed to wake a human. A principle nobody can fail is a principle nobody follows, so these defaults are checkable: a log line either has the required fields or it does not; an external call either has a timeout or it does not. Deviations are allowed, but β€” as everywhere in the handbook β€” they must be deliberate and justified in the project's design notes.

This is also where human⇄AI collaboration meets the running system. We write for both humans and AI. The same structured logs, metrics, and traces that let an on-call engineer find a fault are what let an AI agent investigate one β€” trace an error to its span, read the error budget, propose the rollback. Observability that only a human can read is half-built. Ship telemetry an agent can query.

Requirement levels follow RFC 2119, as elsewhere in the handbook. MUST / MUST NOT are absolute; SHOULD / SHOULD NOT state a strong default overridable only with a documented reason; MAY marks a free choice. Where a rule adopts an industry practice, the practice is named inline and cited under References β€” we adopt the criteria of large-scale practice and right-size them for an SME.

1. Goal

Make every OSBR system observable enough to operate to an SLO, and resilient enough to absorb the failures a distributed system will always have β€” without paging a human for anything a machine can handle.

Concretely, a service that meets this policy can answer, from its telemetry alone:

This serves the values directly. Be Nice β€” we do not wake a colleague at 3am for something a retry would have fixed. Be Kind β€” we mask personal data in our telemetry so that watching the system never becomes surveilling the people in it. Be Strong β€” a resilient system carries load and recovers on its own instead of collapsing onto the on-call engineer.

2. Responsibility

Every service, worker, job, and function OSBR ships is responsible for its own observability and its own resilience. This is not a platform team's job to bolt on afterwards β€” per Infra Β§1-6, it is built in from day one. It is the same implementer-owns-quality rule the Quality Gate states: verification is planned at design, not handed to a separate stage.

We lean on published, freely available standards rather than inventing our own vocabulary: Google's SRE practice for SLI/SLO/error budgets and the four golden signals, OpenTelemetry for the wire format of traces/metrics/logs, the RED and USE methods for which metrics, and Michael Nygard's Release It! for the resilience patterns.

3. Structured Logging

Logs are event streams (per Twelve-Factor, echoed in Infra Β§1-6): the process writes to stdout, the platform ships them to a central store. The process must never manage log files, rotation, or routing.

Every log line is a single JSON object, one per line (JSON Lines). Human-formatted, multi-line, or free-text logs are for local development only and MUST NOT reach a deployed environment.

3-1. Minimum Log Schema

Every log line from every component MUST carry at least these fields:

Field Type Required Notes
timestamp string MUST ISO 8601 / RFC 3339, UTC, millisecond precision (2026-07-15T09:12:33.482Z).
level string MUST One of debug, info, warn, error, fatal.
service string MUST Stable service name, matching the OpenTelemetry service.name (Β§5).
message string MUST Human-readable summary. A constant string per event; put the variables in their own fields, not interpolated into the message.
trace_id string MUST when a request/trace context exists The OpenTelemetry trace ID, so a log line joins its trace (Β§5).
span_id string SHOULD The active span, for the same reason.
request_id string MUST for request-handling components Correlates all logs of one inbound request even without a full trace.
error object MUST when level is error/fatal { "type", "message", "stack" }. Never log an error as a bare string; never swallow it silently.

A conformant error-level line:

{
  "timestamp": "2026-07-15T09:12:33.482Z",
  "level": "error",
  "service": "checkout-api",
  "message": "payment authorization failed",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "request_id": "req_01J9Z3K8",
  "error": { "type": "GatewayTimeout", "message": "upstream timed out after 2000ms", "stack": "..." },
  "env": "production",
  "version": "2026.07.15-a1b2c3d"
}

3-2. Rules

4. Metrics & Health Checks

4-1. The Four Golden Signals, RED, and USE

Instrument every service for Google SRE's four golden signals β€” latency, traffic, errors, saturation. In practice:

Metrics MUST be exported via OpenTelemetry (Β§5). Emit latency as a histogram, not an average β€” an average hides the tail, and the tail is where users feel pain. Alert and SLO on percentiles (p95/p99).

4-2. Three Distinct Health Checks

A single /health endpoint conflates three different questions and gets used wrongly. OSBR distinguishes them, and every long-running service MUST expose them separately:

Check Question If it fails MUST NOT
Liveness Is the process alive and not deadlocked? Orchestrator restarts the instance. Check downstream dependencies β€” a dependency outage would trigger a pointless restart loop.
Readiness Can this instance serve traffic right now? Orchestrator stops routing to it (no restart). Stay green while a required dependency (DB, cache) is unreachable.
Business / deep health Is the core business function actually working end to end? Alerts a human (Β§6); does not restart or de-route. Be on the hot request path or run on every probe β€” it is heavier; run it on a schedule.

The distinction is what stops the classic cascade: a shared dependency blips, every service's liveness check fails, the orchestrator restarts the entire fleet at once, and the blip becomes an outage. Liveness checks only what the process itself owns.

5. Traces & OpenTelemetry

OpenTelemetry is the OSBR standard for all three signals β€” traces, metrics, and logs β€” because it keeps instrumentation vendor-portable (per Infra Β§1-6); the backend can change without re-instrumenting the code.

6. SLOs, Alerts & Self-Healing

6-1. Error Budgets

Per Infra Β§1-5, reliability is measured, not assumed. Each service defines SLIs (usually availability and latency, from the golden signals) and an SLO target, agreed up front as a non-functional requirement. The gap between the SLO and 100% is the error budget β€” the amount of failure we have explicitly decided is acceptable. Self-healing spends this budget silently; alerting is what we do when the rate of spend threatens to exhaust it.

6-2. Alerts Wake a Human β€” So Alert Only on What a Human Must Fix

An alert is a claim that a human must act now. Every page that turns out to need no action erodes trust in every future page (alert fatigue), and a tired on-call engineer is neither Strong nor safe.

6-3. Pre-Decided Rollback Triggers

Deploys must be reversible (Infra Β§1-10). Reversibility is worthless if nobody decides to use it in time, and 3am is the worst moment to invent the criteria. So the rollback triggers are decided before the deploy, written down, and β€” where the platform allows β€” automated:

Rolling back is the Strong move, not the failure. It is a normal, un-blamed operation; the postmortem (Incident Management) asks what the system missed, never who shipped it. Progressive delivery (canary / blue-green, per Infra Β§1-10) is what makes these triggers fire while a bad release still reaches few users.

7. Resilience Defaults on Every External Call

Every call that leaves the process β€” HTTP, database, cache, queue, third-party API β€” can and eventually will fail, hang, or slow down (the fallacies of distributed computing; how those boundaries are drawn is the domain of the Architecture Standards). Michael Nygard's Release It! names the patterns; these are OSBR's defaults. A call that reaches the network MUST have all three of timeout, bounded retry, and a circuit breaker, unless the design notes justify an exception. These defaults are checkable, so they SHOULD be exercised against a real dependency in tests (Testing Standards) β€” a timeout you never fire is a timeout you do not really have.

7-1. Timeouts

7-2. Retries β€” Bounded, Backed Off, Jittered

7-3. Circuit Breakers & Bulkheads

These are defaults, not dogma

A steady internal call to a fast, co-located dependency may not need a full breaker. The rule is that the omission is deliberate and justified in the design notes β€” recorded in the pull request's Specification per the Development Guide, the same standard Infra sets for every deviation. The unacceptable case is the call with no timeout because nobody thought about it.

8. Privacy in Telemetry β€” Be Kind

Logs, metrics, and traces are protected assets (Application Security). Observability must never become surveillance of users or colleagues.

Masking protects the people in the system and it protects OSBR: telemetry an attacker or a careless export can turn into a personal-data breach is a liability, not an asset.

References

Named, freely available standards this policy is built on.

Reliability, SLOs & signals

Observability

Resilience patterns

Delivery metrics

Related OSBR standards