Files
rune/scripts
Nick e9d3efae5d feat(mutation_guards): port to FULL Rust — dichotomy wave
DICHOTOMY VERDICT: RUST (deterministic classification core — severity
lattices, branch order, verdict+reason+recovery are pure logic; zero IO).

Ported (name-preserving, src/rust/mutation_guards/src/lib.rs):
- classify_mutation (the full gate flow: unattributed identity-family
  DENY first — it beats read ops and the destructive gate — then the
  destructive-unbacked DENY, CONFIRM via score >= 4 or identity-kind +
  mutating-op, ALLOW; severity-table defaults for unknown kind/op/scope)
- guard_mutation (dict.get defaults: missing-key default vs present-null
  falsy passthrough — 0/[]/None falsy, non-empty strings truthy)
- mu_classify/mu_guard FFI exports (doc-envelope law: one JSON doc in,
  {ok, value|err} out; no free-string export — callers free through
  capability_scoring's cs_free_string)

Python semantics preserved exactly: Python truthiness over JSON values,
str(None) rendering in the reason f-strings, the exact reason/recovery
strings.

Truth: scripts/gen_mutation_guards_truth.py freezes 43 cases from the
live oracle (frozen_mg_truth.json embedded verbatim; RUNE_MG_CORE=python
pinned, deep-copied inputs) — every branch of both public functions:
DENY-1 precedence proofs (falsy 0/None attribution, read-op denial),
DENY-2 boundary (op/kind severity-2, falsy-zero backup), CONFIRM score-4
boundary and identity-rule, truthy non-bool backups, ALLOW lattice with
unknown kind/op/scope defaults, null kind/operation rendered as None,
guard defaults/extra-keys/empty-mutation. Battery green VERBATIM in-crate
(whole-doc compare). Live parity: facade 43/43 + kernel 43/43 (direct
loader), RUNE_MG_CORE=python fallback 43/43. Python tests green both
modes (test_governance_quartet 15/15).

Contract: BUILDER-2026-10-12T12:11:14Z-ab92a8-factory-wave (walked
draft→approved→building→verifying→closed back-to-back in ONE process,
scripts/open_contract_mutation_guards.py).
2026-10-12 13:58:40 +01:00
..