S58 · E.D.I.T.H. / Hasan-Jalal - one authorization plane for the fleet

Declared state: built 2026-10-17 - one authorization plane: 12 action categories x 8 actors resolve to exactly one verdict each, an unknown action escalates rather than passing as harmless, a dangerous payload shape is refused for the owner too, every decision appends to the existing hash-chained trail with the actor that asked, and the gate going down reads rather than eats.

This is the repository plan and evidence, not a live health reading. A task marked done may still depend on credentials, devices, deployment or a newer acceptance test.

Dependencies

S43, S14, D-13, D-95

Tasks and gates

58.F1 · Action taxonomy as a typed enum with an ALLOW/ESCALATE/DENY verdict, behind one authorize(actor, category, action, target) entry point.

Tier F · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - every declared category maps to exactly one verdict; an empty actor name is refused rather than treated as trusted.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

58.F2 · Rules are data keyed on (actor, category) with exact match - no substring matching - and an actor with no row for a category escalates, never allows.

Tier F · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - the brief's `action.upper()` substring blocks are the shape being refused: a misnamed actor must not widen or narrow access.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

58.F3 · Taint pre-check on payloads before any model sees them: destructive shell patterns, credential shapes, instruction-override markers.

Tier F · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - destructive commands and credential shapes are flagged without a model in the path.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

58.F4 · Every decision writes the EXISTING hash-chained audit line with actor, decision, rule and reasoning. No second ledger is created.

Tier F · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - the audit gains the rows it already has columns for; `audit_verify.py` still verifies the chain afterwards.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py, bench/test_audit_integrity.py

58.R1 · The door-lock refusal still lives inside ha_call; policy is the second opinion, not the only wall (D-100).

Tier R · done · Verification: hermetic-test

Gate: asserts the policy layer would also deny it, so the two agree - while `test_blast_radius_refusal.py` continues to assert the actuator holds it. A hard block that lives only in the policy layer is one refactor away from being wrong.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py, bench/test_blast_radius_refusal.py

58.R2 · The verdict table is exhaustive over declared categories and stable: one input, one verdict, and the table has no holes.

Tier R · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - stability is what makes the decision reviewable after the fact.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

58.R3 · E.D.I.T.H. unavailable is not fleet unavailable: read-only proceeds on the existing per-tool guards, side effects escalate (D-101).

Tier R · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - the failure this rule must never have is a silent ALLOW on a side-effecting action while S58 is down.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

58.R4 · No credential literal anywhere in the module, checked as an AST walk rather than a grep (D-102).

Tier R · done · Verification: hermetic-test

Gate: `test_policy_engine.py` - a grep is defeated by string concatenation, which is the easy way in.

  • hermetic-green · 2026-10-17 · bench/test_policy_engine.py

HUD screen contracts

All subsystems · Source: docs/systems-plan.json.