pub fn backend_script(role: &str, contract_sha256: &str) -> StringExpand description
The backend mechanics, the fingerprint row, and the runtime grants, as one script.
role is interpolated rather than bound because PostgreSQL cannot
parameterize an identifier. crate::config::validate_role has already
restricted it to [a-z_][a-z0-9_]*, which needs no quoting and cannot
carry a separator, a quote, or a comment.
The privilege list grants exactly what the daemon does: read everything,
append history, and update the projections it rebuilds. Nothing in the
CONTRACT schema is deletable or truncatable, so the log never shrinks.
event, receipt, and ingested_record are append-only and lose UPDATE —
the last of those is a projection the kernel DOES rebuild, but only ever by
inserting, so granting it UPDATE would widen the role for a write no code
path makes. transition is the FSM seed the contract ships — the kernel
only ever reads it, so it loses every write.
The blob tables are the one place DELETE is granted, and only inside
gwk_internal: sweep reclaims unreferenced blobs, evidence pins are
released, and uploads expire. None of that is history — the events that
REFERENCE a blob stay in the log after its bytes are gone, which is what
makes a swept or shredded blob auditable at all.