Implementation: SHADOW (abstain) · DESIGN (router-driven escalation) · Exposure: INTERNAL. See status labels. Every cognitive step has an honest way to say “not me”: abstain (do not answer) or escalate (hand to something stronger or to a person).

Architecture contract

A decision result carries a threshold action set by policy, not by the component: Rules:
  • Without valid calibration, abstain. An uncalibrated result never reaches AUTO.
  • Outside the calibrated coverage region, abstain or escalate.
  • Escalation is chosen by policy and routing, never by a weaker component judging itself.
  • The degradation chain is: alternate local component, a stronger component, deterministic reconstruction, then a person or an explicit failure. It never fails open.
  • A human route always goes through an attention request with reason low_confidence or verification_inconclusive.
Why: a system that must always answer will guess. Making abstention a normal, typed outcome lets the system be right when it acts and honest when it cannot.

Current implementation

  • The decision runtime on main marks every result without a passing calibration manifest as uncalibrated and abstains. Only judge.first_pass.tool has a passing manifest, and it acts only through a canary with live mode on. Every other S1 result abstains today.
  • For agency-origin work, a judge timeout, error or invalid answer moves the node to NEEDS_HUMAN, never to done.
  • Escalation to a stronger mode or component needs the router, which is on main as library code but not yet called on the normal path.

Availability

Developer relevance

Treat abstention as a result, not an error. Your graph should have an explicit path for it: an escalation node, a deterministic fallback, or an attention request.