ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / db/migrations/0082_provenance_by_source.sql

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / db/migrations/0082_provenance_by_source.sql
DateNot specified in source
RepositoryJanady13/missionmatch
Revision720d47fae476b0d38477ae4401697d372b1ea2bc
Branchfeature/opportunity-to-outcome
Path or archive memberdb/migrations/0082_provenance_by_source.sql
Original SHA-2565250f69e897783904ad4d0dae650873293c76ccf2ac72d9915f8b473bd1ca148
Git blob SHA6d63e33582dc78502f7b3a6dd31bb7e5d0e886f2
Reading-copy SHA-2565250f69e897783904ad4d0dae650873293c76ccf2ac72d9915f8b473bd1ca148

Original source ↗

Recovered source transcript

-- +goose Up -- PROVENANCE FOR opportunity_documents IS BOUND FROM THE SOURCE, not from the table. -- -- Migration 0081 bound provenance per TABLE, which was right for five of its six tables and wrong for this -- one. opportunity_documents holds BOTH a customer's own uploaded package AND published federal attachments -- pulled from sam.gov, and those are not the same kind of data: -- -- an uploaded PWS is the customer's private work product and must never leave the local plane -- a sam.gov attachment is a published US Government document, already public, and the external -- normalization lane exists precisely for text like it -- -- Binding every row to tenant_upload made the public ones unusable by the lane built for them. Binding every -- row to public_cache would be catastrophic. So the binding derives from source_type, which is the column -- that already states where the row came from. -- -- THE PROPERTY THAT MUST SURVIVE, and this is the whole point of provenance at origin: A CALLER STILL -- CANNOT DECLARE PROVENANCE. It is computed, never accepted. What a caller can now influence is -- source_type, which is a different and much more visible lie: it is a documented column with a CHECK -- constraint, it appears in every audit entry, and the binding sites test enumerates the code paths allowed -- to set the public values. Fabricating provenance therefore still requires touching a named location, it is -- simply a different named location than before. -- -- THE HONEST RESIDUAL RISK, written down rather than discovered later: application code that inserted a -- tenant document with source_type 'sam_attachment' would produce a public_cache row. Nothing in the -- database can distinguish that from a real attachment. The mitigation is that exactly one binary writes -- that source_type, cmd/sam-attachment-sync, and the test asserts it. -- +goose StatementBegin CREATE OR REPLACE FUNCTION provenance_from_document_source() RETURNS trigger AS $$ DECLARE born text; BEGIN -- The mapping is EXHAUSTIVE and its default is the restrictive one. A source_type nobody has thought -- about yet becomes tenant_upload, which fails closed: the worst outcome is that a public document is -- treated as private and cannot be sent to an external model, which is an inconvenience. The reverse -- default would be a disclosure. born := CASE WHEN NEW.source_type IN ('sam_attachment', 'url_import') THEN 'public_cache' ELSE 'tenant_upload' END; IF TG_OP = 'INSERT' THEN NEW.provenance := born; RETURN NEW; END IF; -- Provenance remains IMMUTABLE, and so does the source it is derived from. Allowing source_type to be -- updated would reintroduce exactly the hole this design closes: a row could be inserted as an upload -- and later relabelled an attachment, laundering a customer's document into the public class. IF NEW.provenance IS DISTINCT FROM OLD.provenance THEN RAISE EXCEPTION 'provenance is immutable: % cannot become % on table %', OLD.provenance, NEW.provenance, TG_TABLE_NAME; END IF; IF NEW.source_type IS DISTINCT FROM OLD.source_type THEN RAISE EXCEPTION 'source_type is immutable on %: % cannot become %, because provenance derives from it', TG_TABLE_NAME, OLD.source_type, NEW.source_type; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- +goose StatementEnd -- The trigger name is the one 0081 ACTUALLY created, read from pg_trigger. Guessing it wrong left the old -- trigger attached, and the reclassify UPDATE below was then refused by it with "provenance is immutable", -- which rolled the whole migration back. A correct rollback, and a wasted attempt that a two second query -- would have avoided. DROP TRIGGER IF EXISTS trg_opportunity_documents_provenance ON opportunity_documents; DROP TRIGGER IF EXISTS trg_provenance_opportunity_documents ON opportunity_documents; -- THE ORDER BELOW IS LOAD BEARING. The one time reclassification runs while NO trigger is attached, -- because the trigger's whole job is to refuse a provenance change, and the reclassify IS a provenance -- change. Creating the trigger first made the migration refuse itself, which it did correctly and which -- cost a second rolled back attempt. Trigger goes on AFTER the data is correct, and from that moment the -- column can never move again. -- The CHECK from 0081 pinned this table to a single value. Widen it to the two the mapping can produce, and -- no further: the column still cannot hold curated_card or tenant_record. ALTER TABLE opportunity_documents DROP CONSTRAINT IF EXISTS ck_opportunity_documents_provenance; ALTER TABLE opportunity_documents ADD CONSTRAINT ck_opportunity_documents_provenance CHECK (provenance IN ('tenant_upload', 'public_cache')); -- Existing rows are RECLASSIFIED to what the mapping says they should always have been. This is a one time -- correction of rows written before the mapping existed, not a licence to update provenance later; the -- trigger above refuses any subsequent change. UPDATE opportunity_documents SET provenance = 'public_cache' WHERE source_type IN ('sam_attachment', 'url_import') AND provenance <> 'public_cache'; CREATE TRIGGER trg_opportunity_documents_provenance BEFORE INSERT OR UPDATE ON opportunity_documents FOR EACH ROW EXECUTE FUNCTION provenance_from_document_source(); -- CHUNKS INHERIT FROM THEIR DOCUMENT, for the same reason. A chunk of a published federal attachment is -- public; a chunk of a customer's PWS is not. 0081 bound every chunk to tenant_upload, which would have -- made extracted public text unusable by the lane that exists for it. -- +goose StatementBegin CREATE OR REPLACE FUNCTION provenance_from_parent_document() RETURNS trigger AS $$ DECLARE parent text; BEGIN IF TG_OP = 'INSERT' THEN SELECT provenance INTO parent FROM opportunity_documents WHERE id = NEW.document_id; -- A chunk whose parent cannot be found fails CLOSED rather than defaulting to public. NEW.provenance := COALESCE(parent, 'tenant_upload'); RETURN NEW; END IF; IF NEW.provenance IS DISTINCT FROM OLD.provenance THEN RAISE EXCEPTION 'provenance is immutable: % cannot become % on table %', OLD.provenance, NEW.provenance, TG_TABLE_NAME; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- +goose StatementEnd DROP TRIGGER IF EXISTS trg_opportunity_document_chunks_provenance ON opportunity_document_chunks; DROP TRIGGER IF EXISTS trg_provenance_opportunity_document_chunks ON opportunity_document_chunks; ALTER TABLE opportunity_document_chunks DROP CONSTRAINT IF EXISTS ck_opportunity_document_chunks_provenance; ALTER TABLE opportunity_document_chunks ADD CONSTRAINT ck_opportunity_document_chunks_provenance CHECK (provenance IN ('tenant_upload', 'public_cache')); UPDATE opportunity_document_chunks c SET provenance = d.provenance FROM opportunity_documents d WHERE d.id = c.document_id AND c.provenance <> d.provenance; CREATE TRIGGER trg_opportunity_document_chunks_provenance BEFORE INSERT OR UPDATE ON opportunity_document_chunks FOR EACH ROW EXECUTE FUNCTION provenance_from_parent_document(); -- +goose Down DROP TRIGGER IF EXISTS trg_opportunity_document_chunks_provenance ON opportunity_document_chunks; DROP TRIGGER IF EXISTS trg_opportunity_documents_provenance ON opportunity_documents; DROP FUNCTION IF EXISTS provenance_from_parent_document(); DROP FUNCTION IF EXISTS provenance_from_document_source();

Search equations, builds, manuscript text, and recovered sources.