Skip to content

Degraded mode

An outage never stalls your agent. That is the point of this design, so it goes first.

Under load or partial dependency failure, context.assemble returns a smaller answer with degraded: true rather than an error. It is a successful response carrying a real verdict.

Depth, not correctness:

NormallyDegraded
Full candidate setA reduced one
Graph expansionMay be skipped
All guides resolvedThe highest-priority ones
Full rankingA cheaper pass

What does not change: tenancy, scope, clearance and status filtering. Admission is never degraded. A degraded answer may be shallower; it is never one you were not allowed to see.

The most common mistake. degraded: true is a success — retrying adds load to a system that is already telling you it is under pressure, and the retry is likely to degrade too.

d = interpret_verdict(assembled.verdict)
if d.degraded:
log.info("degraded context", extra={"request_id": assembled.request_id})
# carry on — do NOT retry, do NOT treat as a hold
if not d.proceed:
return hold(d.summary())

The SDK will not retry it either: retry classifies on transport outcome and never reads degraded or any governed payload.

A degraded response still carries a real verdict. If it says allow, that is a genuine allow computed from what was reachable.

Log it. With the request_id. A rising degraded rate is a signal worth a dashboard.

Consider telling the model. If your agent reasons about confidence, “this context was assembled under pressure and may be less complete” is honest and occasionally changes what it does.

Decide for irreversible actions. For a force-push or a production migration you may reasonably want full context or nothing. That is your call to write down:

if d.degraded and action_is_irreversible:
return escalate("degraded context; not proceeding unattended on an irreversible action")

Note the shape: you wrote the rule. Vectadyne did not stop you — consistent with advisory-first.

Do not confuse three different budgets:

WhoseOn overrun
latency_budget_ms (default 800)server, on context.assembledegrades — returns a smaller answer
Per-attempt timeout (30s)clientthat attempt fails; may retry
Total timeout (60s)clientthe call fails

A degraded assemble is a success and must not consume a retry. Conflating the server budget with a client timeout produces a client that retries its way through an incident.

The limit. During degradation you get less context than you would have. Nothing tells you exactly what was omitted.

What still holds. Your agent keeps running, the verdict is real, admission is untouched, and the response says plainly that it was degraded rather than pretending to be complete.

What to do. Log it, surface the reduced confidence if your agent can use it, and set your own policy for irreversible actions.