D-A3-3: Autonomy is a band boundary, not a free knob¶
Status: Accepted, implemented (guardrails/autonomy.py, Phase 3).
Context¶
The portfolio plan (PORTFOLIO_PLAN_V3.md §7 A3) describes three autonomy
levels — Inform, Recommend, Escalate — without saying which decisions the
setting is allowed to move. A knob that can move the escalation boundary is
not a safety-relevant control; it is a way to turn safety off, and it would
mean the same red flag could be answered directly at one setting and blocked
at another.
Decision¶
Bands are a property of the question, assigned by resolve_policy. The
autonomy level moves only the boundary between inform and recommend:
L1_conservativemoves the boundary down — someinformquestions are held for clinician review.L3_permissivemoves it up — somerecommendquestions are answered with education plus an explicit referral.escalateis returned unchanged at every level (guardrails/autonomy.py::effective_band) — there is no setting that turns off an emergency, crisis, or out-of-scope refusal.
tests/graph/test_resolve_policy.py::test_same_question_different_bands_across_autonomy_levels
and ::test_identical_escalation_across_autonomy_levels assert exactly this:
the same question produces different bands at L1/L2/L3 but identical
escalation at all three — the Phase 3 exit criterion.
Consequences¶
- A clinical owner can tune how much gets held for review without being able to accidentally (or deliberately) loosen the emergency/crisis/out-of-scope boundary.
- The autonomy setting is recorded on every
PolicyDecisionand shown in the UI, so the knob's effect is visible rather than a silent server-side behaviour change. - Case 5 (a decision-adjacent interaction question) is the one canonical case
whose pre-flight action genuinely differs by level — held for review at
L1/L2, answered with a pharmacist referral at L3 — and it is the only case
evals/canonical.pyruns three times, once per level.