-- WP-0006-T09: Breach/Compliance Record hosting. -- Depends on migrations/0001_registries.sql. -- -- Per License V1C1 §7.4: a breach record's lifecycle is a sequence of -- distinct, dated events (alleged -> cured, or alleged -> determined -> -- terminated), never an edit of a prior event. "The Trust Service shall -- update the record promptly upon resolution" (§7.4) means append a new -- event for the same case, not mutate the existing one — the same -- append-only pattern as phase_manifests/ledger_entries/attestations. BEGIN; CREATE TABLE IF NOT EXISTS breach_records ( sequence bigint GENERATED ALWAYS AS IDENTITY, record_id text NOT NULL UNIQUE, case_id text NOT NULL, phase_id text NOT NULL REFERENCES phase_manifests(phase_id), event_type text NOT NULL CHECK (event_type IN ('alleged', 'cured', 'determined', 'terminated')), category text NOT NULL, event_at timestamptz NOT NULL, anonymized boolean NOT NULL DEFAULT true, named_entitlement_holder text, evidence_reference text, published_by text NOT NULL REFERENCES licensors(licensor_id), signature text NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (phase_id, sequence), -- License V1C1 §7.4: naming is governed exclusively by the applicable -- Commercial Use Agreement's opt-in; a name may only be stored -- alongside an explicit non-anonymized record, never as a side effect -- of an anonymized one. CHECK (anonymized OR named_entitlement_holder IS NOT NULL), CHECK (NOT anonymized OR named_entitlement_holder IS NULL) ); CREATE INDEX IF NOT EXISTS breach_records_phase_sequence_idx ON breach_records (phase_id, sequence); CREATE INDEX IF NOT EXISTS breach_records_case_idx ON breach_records (case_id); GRANT SELECT, INSERT ON breach_records TO trf_app; -- Deliberately no UPDATE, no DELETE for trf_app: matching phase_manifests, -- ledger_entries, and attestations, a published breach event is -- permanent — resolution is recorded as a new event, never an edit. GRANT USAGE, SELECT ON breach_records_sequence_seq TO trf_app; COMMIT;