Rows in append-only history are never deleted; their content can now be made irrecoverable through one audited path. A redaction replaces the content columns of an event, memory, message, model call, belief or assertion with a fixed marker, keeps identifiers, links, timestamps, scores and breakdowns, writes an append-only ledger row with a SHA-256 of the removed content, appends a redaction event, optionally cascades to derived rows and to the events that quote them, and scrubs stored snapshot archives before re-signing them. noema_redact() is the only write the append-only trigger admits, for UPDATE only, under a transaction-local flag the application never sets; plain updates and all deletes stay refused. Replay labels redacted stimuli instead of inventing them. Cryptographic erasure was considered and deferred with reasons (ADR-0009); docs/privacy.md defines retained, redacted, irrecoverable and deleted and states what backups and earlier exports are not covered. Migration 0023.
14 lines
967 B
PL/PgSQL
14 lines
967 B
PL/PgSQL
-- Redacted content cannot be restored; this only removes the machinery.
|
|
DROP FUNCTION IF EXISTS noema_redact(text, uuid, uuid);
|
|
CREATE OR REPLACE FUNCTION noema_forbid_change() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
RAISE EXCEPTION 'table % is append-only', TG_TABLE_NAME USING ERRCODE = 'integrity_constraint_violation';
|
|
END $$;
|
|
ALTER TABLE assertions DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
ALTER TABLE beliefs DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
ALTER TABLE llm_calls DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
ALTER TABLE messages DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
ALTER TABLE memories DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
ALTER TABLE cognitive_events DROP COLUMN IF EXISTS redaction_id, DROP COLUMN IF EXISTS redacted_at;
|
|
DROP TABLE IF EXISTS redactions;
|