Files
ruvnet--RuView/api-docs/adr/ADR-321-decision-policy-action-authorization.md
T
2026-08-11 17:41:30 +00:00

5.0 KiB
Raw Blame History

ADR-321: Decision policy — action authorization conditioned on certificate class, freshness, uncertainty, and evidence

  • Status: Accepted — initial implementation planned (ADR-300 phase 1)
  • Date: 2026-08-11
  • Deciders: ruv
  • Tags: policy, authorization, safety, certificates, governed-action, phase-1

Context

The perception substrate (ADR-300) makes RuView state what it knows and how well — the capability certificate (ADR-318) binds hardware, environment, model, calibration, metrics, expiry, and evidence level. But a certificate is a statement of knowledge, not a grant of action. The same certificate that is adequate to dim a light is wholly inadequate to release a door lock or clear an industrial stop condition.

Without an explicit authorization layer, every consumer re-implements its own (inconsistent, usually optimistic) rule for "is this good enough to act on," and a confident-but-out-of-domain inference can reach an actuator. That is the exact failure the substrate exists to prevent. Decision policy therefore belongs in phase 1, alongside the certificate it gates, not later.

This ADR realizes program invariant #1 (UNKNOWN is a first-class output, never an error) and the action-side of the refined acceptance test: a drift- invalidated capability must be denied at the actuator before a false confident inference is acted upon.

Decision

Introduce a ruview-policy crate providing an action authorization gate that sits between governed spatial state and any actuator.

1. Assurance requirements per action

An ActionClass declares the assurance an action demands:

  • min_certificate_class — the required CapabilityCertificate class (ADR-318).
  • max_certificate_age / min_domain_freshness — the certificate must be currently valid and the live domain signature (ADR-302) must not be in a DEGRADED/UNKNOWN state (this is the staleness guard, program invariant on certificate conditionality — see ADR-300).
  • max_uncertainty — inference uncertainty ceiling.
  • min_evidence_level — the L0L5 floor (ADR-282/ADR-304); e.g. a safety action may require ≥ L3 (held-out room+subject validation).

Reference action classes (illustrative, configurable):

Class Example Typical floor
Convenience lighting, scenes tolerant: L1+, higher uncertainty ok
Security alerts, arming stricter: valid cert, L2+, bounded uncertainty
SafetyCritical door lock, machine stop strict: fresh cert, L3+, low uncertainty, KNOWN domain only

2. The authorization decision

authorize(action, capability_certificate, live_state) -> Authorization where live_state carries the current SourceState (ADR-295), OOD/domain state (ADR-302), and inference uncertainty. Rules:

  • Fail-closed. Any unmet condition → Deny { failed_condition }. The denial names the specific condition (expired cert, domain DEGRADED, uncertainty over ceiling, evidence below floor, certificate class too low).
  • UNKNOWN denies high-assurance actions. A domain in UNKNOWN (ADR-302) cannot authorize Security/SafetyCritical actions; it may still authorize Convenience if that class's policy permits, but the authorization records that it proceeded under UNKNOWN.
  • The decision is a pure function of (action class, certificate, live state) — deterministic and unit-testable without a clock or actuator.
  • Every authorization (allow or deny) is emitted as the terminal stage of the witness chain (ADR-319), so "why was this actuator allowed/denied" is auditable end-to-end.

3. No silent optimism

A missing certificate, an expired certificate, or an unrecognized action class all deny by default. Absence of a policy is not permission.

Consequences

  • Action authorization becomes uniform and centrally reasoned instead of per-consumer and optimistic; this is the "RuView Certify → constrains action" boundary that is hard to commoditize.
  • A behavior change for existing automations that acted directly on presence: they now pass through the gate. Convenience-class defaults keep low-stakes automations working; high-stakes actions must opt into stricter classes.
  • Depends on ADR-318 (certificate), ADR-302 (domain/OOD state), ADR-295 (source state), ADR-304 (evidence). Built in the phase-1 dependent wave after those types land.

Validation

  • Unit tests: each action class authorizes/denies correctly across the matrix of (valid/expired/degraded cert × KNOWN/DEGRADED/UNKNOWN domain × uncertainty above/below ceiling × evidence above/below floor); UNKNOWN denies safety-critical; every deny names its failed condition; absence-of-policy denies; determinism.
  • Integration: the acceptance-test scenario (ADR-300) — post-certification room change drives domain to DEGRADED→UNKNOWN, and a SafetyCritical authorization is denied with failed_condition = domain_not_known before the inference reaches the actuator, witness chain preserved.
  • cargo test -p ruview-policy.