Guard / foldkit-guard
When a rule refuses
| Cause | Server | Client |
|---|---|---|
| A row's Read refused | not returned, not settled | not found; a tombstone |
A member's Read refused (omit) | the field settled, unread | that field Unavailable |
A member's Read refused (redact) | the replacement value | Ready with it, by design indistinguishable |
| A relation's Read refused | withheld, as a member's | unavailable |
| A write refused | Forbidden, a 403 over JSON | Data.mutation is Failed with _tag: 'Forbidden', reason from an explain |
| A write moved a row out of its writer's sight | answered in deleted | tombstoned; it leaves every list |
| A delete of a row its writer cannot see | nothing deleted; answered gone | tombstoned |
| A Sync edit refused | rejected by its id, with its reason | the replica drops it, with the reason |
| An agent's capability refused | — | AgentAuthorizationError before dispatch, its message an explain's; not offered while available says no |
| A Source left unguarded | GuardServer.validate throws at startup | — |
A refusal says why only through Guards.explain: a plain one is forbidden,
so a probing caller learns only "no", and a row a principal may not read is
not found rather than forbidden, so its existence does not leak.