Modules
The conformance mechanisms
The Tier 1 case template. use Mediate.Conformance.AdapterCase, adapter: Mediate.Rbac, repo: Example.Infrastructure.Repo, world: Example.World
defines a test module. Its setup prepares the repo for the test, stubs
the clock, and binds the adapter through the configuration override. So
each adapter's conformance run is its own module in its own package, and
each package's suite is its own OS process. Every adapter in this
repository passes async: false, sandbox:, setup_queries:,
committed:, and versions:. Cerbos, OpenFGA, and Postgres pass
outage:, and OpenFGA passes seed:.
The bodies of the template's tests. Each is a function of the test
context and the generated values. So the template stays a list of names,
and the assertions live where a reader can read them. Nothing here names
a schema, a subject, or an operation. A law that gets a population
reaches its Mediate.Conformance.World through the struct. A law that
needs a fixed one asks the module the template got.
The bodies of the account laws, ac2-01 to ac2-04 and ac6-01. They
assert
The bodies of the audit laws, au2, au3, and au12. They assert what
a decision event, a change event, and an access event carry. They assert
what the seam records or refuses of a read and a write. Each is a
function of the test context, as Mediate.Conformance.AdapterCase.Laws
describes.
The bodies of the change-management laws, cm3-01 to cm3-04, over the
Mediate.Conformance.Versions module the template got. They assert
The generators the conformance properties draw from. A world-shaped generator takes the world module, or a population, and reaches the module through the struct. It asks that module what terms its rule uses. The unknown operations, kinds, and subjects that the port must always deny are the same for every world.
The law table under "The laws" in
the conformance document as
data. Each row has an id, a sentence, and the controls it answers.
Mediate.Conformance.AdapterCase names each test from a row here. The
freeze test in mediate holds this table to the document row for row, so
a change to one needs a commit that changes both.
The conformance case for a repo. use Mediate.Conformance.RepoCase, repo: MyApp.Repo writes the tests that hold the repo to the seam. The
repo must answer __mediate__/1. It must export nothing outside the
surface of the build it comes from. It must refuse, before any SQL,
every query, write, and raw call on a protected schema that carries no
decision and no exemption.
A protected schema with no table, for Mediate.Conformance.RepoCase:
every refusal it drives happens before SQL, so the table is never
touched. It carries nothing and belongs to itself through parent, which
gives preload an association to ask for.
What an adopter gives Mediate.Conformance.RepoCase so the case can
hold a repo to the five guarantees the change and access events make
How the conformance template makes an adapter agree with a population,
for an adapter whose state is not the world's own tables. seed/1 runs
after every write of a population through the seam. An adapter that
reads the tables needs no seed module. outage/0 makes the adapter's
engine unreachable for the rest of the test. The fail-closed case exists
only for a template given outage:.
What the cm3 laws need and a law cannot write without the adapter's
name. It says how this adapter publishes a policy version, how to
tighten a rule on it, and how to put the original back. The test passes
it to Mediate.Conformance.AdapterCase as versions:. A template given
none runs the cm3 laws as skipped and prints the reason.
The population a Tier 1 run writes, which the caller supplies.
use Mediate.Conformance.AdapterCase, world: MyApp.World hands the
template a module. That module answers what a population holds, what the
rule over it says, and how to write one through the seam. The properties
and the laws ask it for everything they need. The core package names no
schema and no rule of its own. So an adapter outside this repository
proves itself against its own tables.