AshArcadic. Replicant. Verifiers. ValidateWriteActionsAuthorized
(AshArcadic v0.2.0)
Copy Markdown
View Source
Compile-verifier for a replicant CDC mirror target's write-action seam-lock
(build-blocking under --warnings-as-errors).
A replicant's effect-once guarantee depends on ordinary writes being impossible:
create/update/destroy actions must be forbidden by default, so only the CDC sink
writes — bypassing the whole authorizer with authorize?: false. That "forbidden
by default" property is what an authorizer (canonically Ash.Policy.Authorizer
with a forbidding policy, e.g. forbid_if always()) provides; without ANY
authorizer a plain Ash.create/update/destroy is ungated and the seam-lock is
absent.
This verifier enforces the necessary precondition that is soundly decidable at compile time: a replicant resource that declares any create/update/destroy action must declare at least one authorizer. A read-only replicant resource (no write actions) passes vacuously.
It deliberately does NOT attempt to prove full "forbidden by default" over the
policy set. Whether a given actor can pass the policies is resolved at runtime by
the authorizer via SAT over actor-dependent facts (and the domain's authorize
configuration), which a resource verifier — with no actor and no domain in view —
cannot soundly decide. A pattern-match on the canonical forbid_if always() would
also be unsound: an authorizer with only read policies already forbids writes by
default (no matching policy => forbidden), and authorize_if never(),
forbid_unless, or a custom authorizer are equally valid seam-locks — rejecting
those would over-reject legitimate resources. So the runtime seam-lock stays a
runtime guarantee; this check catches only the "forgot to gate the mirror action
at all" failure, at compile time.
Scope note: this reads the RESOURCE's persisted :authorizers only. A resource
that seam-locks its writes solely via a DOMAIN-level policy authorizer (with no
resource authorizer) trips this verifier — a benign false positive whose remedy
(also declare a resource authorizer, as the error message says) is harmless
belt-and-suspenders.