docs: ADR-318 decision policy + amend ADR-297 with epistemic-reliability invariants

Elevates decision policy (action authorization) into phase 1 (ADR-318): a
fail-closed gate that authorizes a governed action only when the capability
certificate class, freshness, uncertainty ceiling, evidence floor, and live
domain state (KNOWN, not DEGRADED/UNKNOWN) all satisfy the action class —
convenience vs security vs safety-critical. UNKNOWN denies high-assurance
actions; every decision is the terminal witness-chain stage.

Amends ADR-297 with: the epistemic-reliability pipeline as the product thesis;
four non-negotiable rules (UNKNOWN first-class; certificates bind
cryptographically; one canonical downstream semantics; benchmarks expose
worst-domain + CIs); the certificate-staleness guard (certificates conditional
on a continuously evaluated domain signature; VALID->DEGRADED->UNKNOWN
auto-degrade triggers recalibration); the three-primitive commercial framing
(Runtime / Certify / Trust-Fleet); and acceptance test B (drift invalidation
before a false inference reaches an actuator).

Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_015TcKegTS7QqhWPC2L2SzaS
This commit is contained in:
Claude
2026-08-11 00:36:05 +00:00
parent 559ad56aa4
commit 8bb55aac05
3 changed files with 190 additions and 12 deletions
@@ -28,10 +28,69 @@ Several of these primitives already have foundations in the tree and should be
- The in-flight ADR-292 (provenance state machine), ADR-293 (authenticated - The in-flight ADR-292 (provenance state machine), ADR-293 (authenticated
data plane, step one), ADR-295 (model sanity gates) — the first bricks. data plane, step one), ADR-295 (model sanity gates) — the first bricks.
## What RuView is optimizing for
Not inference capability — **epistemic reliability**:
```
signal → observation → calibration → inference → uncertainty → evidence
→ certificate → policy → governed action
```
That pipeline is the product. The defensible category is not "RuView perceives
the physical world" but "RuView determines what machines are justified in
believing about it, proves why, and constrains what they may do with that
belief."
### Four non-negotiable program rules
Every child ADR and implementation is bound by these:
1. **UNKNOWN is a first-class output, never an error condition.** A surface that
cannot answer says UNKNOWN and stays legible; it does not throw, default to a
confident class, or silently hold a stale value.
2. **Capability certificates bind cryptographically.** Hardware, environment,
model, calibration, metrics, expiry, and evidence level are bound under one
signature (ADR-315/ADR-302). An unsigned or partially-bound certificate is
not a certificate.
3. **One canonical semantics downstream.** Every surface (MQTT, REST, WebSocket,
RuField, Matter, agents, UI) consumes the same Observation → Inference →
GovernedEvent types (ADR-303). No transport- or UI-specific reinterpretation.
4. **Benchmarks expose worst-domain performance and confidence intervals.**
Pooled accuracy is never sufficient for promotion (ADR-314).
### Certificate conditionality (the staleness guard)
The central architectural risk is **certificate staleness**: a room can remain
syntactically calibrated while its RF distribution has drifted enough to
invalidate the certificate. Therefore a capability certificate is **conditional
on a continuously evaluated domain signature** (ADR-299), not a one-time stamp.
Crossing the OOD threshold automatically degrades state and triggers
recalibration rather than silently continuing:
```
VALID → DEGRADED → UNKNOWN (auto-degrade on domain drift; triggers recalibration)
```
This binds ADR-298 (calibration), ADR-299 (OOD), ADR-315 (certificate), and
ADR-318 (policy): a degraded/unknown domain must invalidate the affected
capability *before* a false confident inference reaches an actuator.
### Commercial framing — three primitives, not one product
- **RuView Runtime** — provides perception.
- **RuView Certify** — establishes what a deployment can legitimately claim
(calibration + evidence + capability certificate + policy).
- **RuView Trust / Fleet** — keeps that claim valid across hardware, firmware,
models, and environmental drift (ADR-313).
Certify and Trust are the parts that are hard to commoditize; presence
detection alone is not.
## Decision ## Decision
Adopt a **20-primitive phased program**. Each primitive gets a child ADR Adopt a **21-primitive phased program**. Each primitive gets a child ADR
(ADR-298…ADR-317) that owns its detailed decision, status, and validation. (ADR-298…ADR-318) that owns its detailed decision, status, and validation.
This ADR owns the framing, the dependency order, and the phase assignment. This ADR owns the framing, the dependency order, and the phase assignment.
### Primitive → ADR map ### Primitive → ADR map
@@ -58,23 +117,29 @@ This ADR owns the framing, the dependency order, and the phase assignment.
| 18 | Capability certificates | ADR-315 | 1 | | 18 | Capability certificates | ADR-315 | 1 |
| 19 | Witness chain | ADR-316 | 1 | | 19 | Witness chain | ADR-316 | 1 |
| 20 | RuView sensor HAL | ADR-317 | 2 | | 20 | RuView sensor HAL | ADR-317 | 2 |
| 21 | Decision policy — action authorization | ADR-318 | 1 |
### Dependency order (why phase, not score, drives sequencing) ### Dependency order (why phase, not score, drives sequencing)
``` ```
ADR-303 spatial ontology ──┐ ADR-303 spatial ontology ──┐
ADR-302 auth identity ─────┼──► ADR-298 calibration cert ──► ADR-299 OOD gating ADR-302 auth identity ─────┼──► ADR-298 calibration cert ──► ADR-299 OOD gating
│ │ │ │
└──► ADR-316 witness chain └──► ADR-316 witness chain │ (VALID→DEGRADED→UNKNOWN)
│ ▼
ADR-301 evidence engine ──► ADR-315 capability certificate ADR-301 evidence engine ──► ADR-315 capability certificate
│ (conditional on domain signature)
│ ▼
│ ADR-318 decision policy ──► governed action
└──► ADR-314 benchmark scorecard (per-PR gate) └──► ADR-314 benchmark scorecard (per-PR gate)
``` ```
- **Phase 1 (the certificate spine, built now):** 303, 302, 316, 298, 299, - **Phase 1 (the certificate spine, built now):** foundational roots 303, 302,
301, 315, 314. This set is exactly the acceptance test decomposed and is 301, 298 (implemented first, in their own crates); then the dependent wave
buildable without new hardware (types, logic, signatures, tests). 316, 299, 315, 314, 318. This set is exactly the acceptance test decomposed
and is buildable without new hardware (types, logic, signatures, tests). The
dependent wave adds the staleness guard (299 auto-degrades 315) and the
action gate (318) that denies at the actuator on a degraded/unknown domain.
- **Phase 2 (integration & operations):** 300 ground truth, 304 tracking, 307 - **Phase 2 (integration & operations):** 300 ground truth, 304 tracking, 307
802.11bf-native, 308 fusion, 313 fleet, 317 HAL. Depends on the spine. 802.11bf-native, 308 fusion, 313 fleet, 317 HAL. Depends on the spine.
- **Phase 3 (higher-ceiling, research-forward):** 305 placement optimizer, 306 - **Phase 3 (higher-ceiling, research-forward):** 305 placement optimizer, 306
@@ -84,7 +149,7 @@ This ADR owns the framing, the dependency order, and the phase assignment.
Phase-2 and phase-3 child ADRs are authored as **Proposed** (design intent, Phase-2 and phase-3 child ADRs are authored as **Proposed** (design intent,
validation plan) and are not implemented by the phase-1 swarm. validation plan) and are not implemented by the phase-1 swarm.
### Acceptance test (from the strategic assessment) ### Acceptance test A — onboarding (from the strategic assessment)
> Connect a new sensor type in an unseen room. Within 30 minutes RuView should > Connect a new sensor type in an unseen room. Within 30 minutes RuView should
> identify the hardware (HAL, ADR-317), calibrate the environment (ADR-298), > identify the hardware (HAL, ADR-317), calibrate the environment (ADR-298),
@@ -93,7 +158,18 @@ validation plan) and are not implemented by the phase-1 swarm.
> events (ADR-303), and return UNKNOWN whenever evidence falls outside that > events (ADR-303), and return UNKNOWN whenever evidence falls outside that
> certificate (ADR-299). > certificate (ADR-299).
Phase 1 makes every clause except HAL testable in software; HAL (phase 2) ### Acceptance test B — drift invalidation (the staleness guard)
> Deliberately change the room after certification — move furniture, change the
> AP channel, or substitute hardware. RuView should detect distribution drift
> (ADR-299), invalidate the affected capability (ADR-315) **before** a false
> confident inference reaches an actuator (ADR-318 denies with the specific
> failed condition), emit UNKNOWN, preserve the complete witness chain
> (ADR-316), and explain exactly which certificate condition failed.
Test B is the load-bearing one: it proves the substrate fails safe, not just
that it perceives well. Phase 1 makes every clause except HAL testable in
software; HAL (phase 2)
closes the "identify the hardware" clause. closes the "identify the hardware" clause.
## Consequences ## Consequences
@@ -0,0 +1,101 @@
# ADR-318: Decision policy — action authorization conditioned on certificate class, freshness, uncertainty, and evidence
- **Status**: Accepted — initial implementation planned (ADR-297 phase 1)
- **Date**: 2026-08-11
- **Deciders**: ruv
- **Tags**: policy, authorization, safety, certificates, governed-action, phase-1
## Context
The perception substrate (ADR-297) makes RuView state *what it knows* and
*how well* — the capability certificate (ADR-315) 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-315).
- `max_certificate_age` / `min_domain_freshness` — the certificate must be
currently valid **and** the live domain signature (ADR-299) must not be in a
DEGRADED/UNKNOWN state (this is the staleness guard, program invariant on
certificate conditionality — see ADR-297).
- `max_uncertainty` — inference uncertainty ceiling.
- `min_evidence_level` — the L0L5 floor (ADR-282/ADR-301); 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-292), OOD/domain state
(ADR-299), 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-299)
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-316), 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-315 (certificate), ADR-299 (domain/OOD state), ADR-292
(source state), ADR-301 (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-297) — 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`.
+2 -1
View File
@@ -154,7 +154,7 @@ Statuses: **Proposed** (under discussion), **Accepted** (approved and/or impleme
| [ADR-294](ADR-294-multi-node-semantic-correctness.md) | Multi-node semantic correctness — per-node inference, node-keyed rate limiting, stale state | Accepted (initial implementation) | | [ADR-294](ADR-294-multi-node-semantic-correctness.md) | Multi-node semantic correctness — per-node inference, node-keyed rate limiting, stale state | Accepted (initial implementation) |
| [ADR-295](ADR-295-model-release-sanity-gates.md) | Model release sanity gates — block degenerate and mislabeled model artifacts | Accepted (initial implementation) | | [ADR-295](ADR-295-model-release-sanity-gates.md) | Model release sanity gates — block degenerate and mislabeled model artifacts | Accepted (initial implementation) |
| [ADR-296](ADR-296-csi-data-incident-repo-controls.md) | Repository CSI data-incident controls — ignore rules and pre-commit/CI policy check | Accepted (controls implemented; tree remediation gated) | | [ADR-296](ADR-296-csi-data-incident-repo-controls.md) | Repository CSI data-incident controls — ignore rules and pre-commit/CI policy check | Accepted (controls implemented; tree remediation gated) |
| [ADR-297](ADR-297-perception-substrate-program.md) | RuView perception substrate — phased 20-primitive program (calibration, evidence, trust, deployment) | Accepted (program; children ADR-298..317) | | [ADR-297](ADR-297-perception-substrate-program.md) | RuView perception substrate — phased 21-primitive program (calibration, evidence, trust, deployment) | Accepted (program; children ADR-298..317) |
| [ADR-298](ADR-298-automatic-domain-calibration.md) | Automatic domain calibration — signed, versioned, invalidatable room fingerprint | Accepted (phase 1) | | [ADR-298](ADR-298-automatic-domain-calibration.md) | Automatic domain calibration — signed, versioned, invalidatable room fingerprint | Accepted (phase 1) |
| [ADR-299](ADR-299-out-of-distribution-detection.md) | Out-of-distribution detection — KNOWN / DEGRADED / UNKNOWN gating | Accepted (phase 1) | | [ADR-299](ADR-299-out-of-distribution-detection.md) | Out-of-distribution detection — KNOWN / DEGRADED / UNKNOWN gating | Accepted (phase 1) |
| [ADR-300](ADR-300-ground-truth-synchronization.md) | Ground-truth synchronization — reference sensors as a formal validation plane | Proposed (phase 2) | | [ADR-300](ADR-300-ground-truth-synchronization.md) | Ground-truth synchronization — reference sensors as a formal validation plane | Proposed (phase 2) |
@@ -175,6 +175,7 @@ Statuses: **Proposed** (under discussion), **Accepted** (approved and/or impleme
| [ADR-315](ADR-315-capability-certificates.md) | Capability certificates — validated-for-this-environment claims | Accepted (phase 1) | | [ADR-315](ADR-315-capability-certificates.md) | Capability certificates — validated-for-this-environment claims | Accepted (phase 1) |
| [ADR-316](ADR-316-witness-chain.md) | Witness chain — staged, signed epistemic envelope | Accepted (phase 1) | | [ADR-316](ADR-316-witness-chain.md) | Witness chain — staged, signed epistemic envelope | Accepted (phase 1) |
| [ADR-317](ADR-317-sensor-hal.md) | RuView sensor HAL — abstract all sensing hardware to one Observation type | Proposed (phase 2) | | [ADR-317](ADR-317-sensor-hal.md) | RuView sensor HAL — abstract all sensing hardware to one Observation type | Proposed (phase 2) |
| [ADR-318](ADR-318-decision-policy-action-authorization.md) | Decision policy — action authorization conditioned on certificate class, freshness, uncertainty, evidence | Accepted (phase 1) |
--- ---