Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / docs/evidence/phase2/functional/provenance-at-origin.txt |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | docs/evidence/phase2/functional/provenance-at-origin.txt |
| Original SHA-256 | 2be283e11eebaab40da06f5645563759d17d4731980cf37b4718702b81c0b23d |
| Git blob SHA | bd6e474a7d5ce789055b58e02f8024eb87801fcc |
| Reading-copy SHA-256 | 2be283e11eebaab40da06f5645563759d17d4731980cf37b4718702b81c0b23d |
Recovered source transcript
Download complete source text ↓64 lines · 3.6 KB
PROVENANCE BOUND AT ORIGIN. Evidence, 28 July 2026, migration 0081.
THE SHARPENING: provenance must be stamped by the subsystem that creates the
data, immutable, carried with the record, and the egress decision must derive
from the STORED provenance of every element, never a call time declaration.
WAS IT ALREADY BUILT THIS WAY: NO. The first implementation took provenance as a
call time argument and the one external call site passed the literal
scrub.ProvenancePublicCache. That is a control a single mistake defeats, because
the only thing between a tenant document and OpenAI was a constant somebody
typed. It has been removed.
HOW IT IS BOUND NOW, migration 0081. For each source table: a DEFAULT supplies
the value, a CHECK pins it to exactly one value, and a BEFORE INSERT OR UPDATE
trigger OVERWRITES whatever a writer supplied on insert and RAISES on any change.
A default alone was not enough, because a default only applies when the column is
omitted and an INSERT naming the column would still let a writer choose.
sam_opportunities born public_cache
opportunity_records born public_cache
opportunity_documents born tenant_upload
opportunity_document_chunks born tenant_upload
opportunity_scope_items born tenant_record
candidates born tenant_record
PROVEN AGAINST THE LIVE STAGING DATABASE, not by reading the migration:
1. A writer that ASKED for tenant_upload on a sam_opportunities insert got a
row stamped public_cache. The trigger overrode the writer.
2. Laundering by UPDATE raises:
"provenance is immutable: public_cache cannot become tenant_upload"
3. candidates carries DEFAULT 'tenant_record', so the workforce table is born
private without anyone electing it.
4. All six binding sites carry the column, the CHECK, and the trigger:
candidates col=1 check=2 trigger=1
opportunity_document_chunks col=1 check=1 trigger=1
opportunity_documents col=1 check=1 trigger=1
opportunity_records col=1 check=1 trigger=1
opportunity_scope_items col=1 check=1 trigger=1
sam_opportunities col=1 check=1 trigger=1
THE EGRESS DECISION NOW DERIVES FROM STORED VALUES. AllowEgress takes the SET of
provenance values read from the rows a payload was composed from. The normalize
command SELECTs s.provenance and passes what the database returned; it names no
constant. Four conditions, all failing closed: a non empty set, every element
permitted, a permitted class, and the marker backstop.
ONE TENANT ELEMENT POISONS THE WHOLE PAYLOAD, proven by test. A public notice
with one paragraph of a customer's PWS folded in IS a customer's PWS.
AN EMPTY SET IS REFUSED, proven by test. Silence is not permission, and before
this an empty set would have passed every loop vacuously.
THE BINDING SITE INVENTORY, internal/platform/scrub/binding_sites_test.go, is
what makes "fabricating provenance requires touching a named location" checkable
rather than aspirational:
every site in the inventory is asserted bound by the migration, column, CHECK,
trigger, and stamped value
the migration may not bind a table ABSENT from the inventory, so a silent
addition fails the suite
NO provenance constant may appear in application code outside the scrub
package. A future call time declaration fails the day it is written.
POSITIVE CONTROL on the detector itself: it must SEE a planted declaration and
must NOT flag a call that correctly reads provenance from the row. Without
this the regression test would pass an empty repository.