basquetWi + New ticket
terra TERRA-158

A stale draft copy of terra_29 still says DRAFT ONLY NOT APPLIED beside the applied file, and terra_36/38's deliberately-inert archive sentinel became illegal the moment terra_29 went live today with nothing watching for it

Done high dtdb02-terra-cc

FOUND BY A QUESTION FROM THE CENSUS LANE, NOT BY THE CENSUS. coder-terra-ca refused to credit terra_38 as satisfied-branch coverage of the archive-context predicate and asked why, rather than recording the credit and moving on: terra_38 line 142 sets app.terraUserId to the literal 'db-terra-cc:terra_38', which the live terra_23 body rejects at lines 50-53 with "app.terraUserId GUC is not a valid uuid (got %)". The dry-run ran to its deliberate ZZ999 abort with no such exception. A value that must be refused, was not refused, and nobody noticed for nine days. THE EXPLANATION IS NOT A TIMELINE, WHICH IS WHAT I EXPECTED TO FIND. terra_23's header records its fixture run on 2026-08-16 and terra_36 and terra_38 were applied on 2026-08-22, so the predicate predates both and "the check was added later" is not available. The actual reason is in terra_12A2 line 53, written down eight migrations earlier and never connected to this: fn_terraRequireArchiveContext IS NOT A TRIGGER. Zero rows in pg_trigger. It RETURNS TABLE and is CALLED by the real archive trigger body at terra_5 line 104. If the table being written carries no archive trigger, the function is never entered and its predicates never evaluate, whatever the GUCs hold. SO THE TWO MIGRATIONS PROVE SOMETHING ABOUT terraCirugias, NOT ABOUT THE PREDICATE. terra_36 and terra_38 both open with a set_config pair and then UPDATE terraCirugias to retire rows. The invalid actor value survived, which means those writes never reached the archive-context path at all. The GUC lines are decorative there. They read exactly like the ones in terra_31, terra_32, terra_41 and terra_29 that set a real UUID and are load-bearing, and nothing distinguishes the two kinds on sight. TWO POSSIBLE STATES AND THEY NEED OPPOSITE FIXES, WHICH IS WHY THIS IS A ROW AND NOT A CLEANUP. Either terraCirugias is correctly outside the archived-table set, in which case those set_config lines assert a protection that is not operating and should be deleted rather than left to imply one; or terraCirugias should carry the archive trigger like the other soft-deleted terra tables, in which case retiring a cirugia has been writing without attributable actor context since terra_36 and the fix is a migration, not a deletion. Deciding this from source is not possible; it needs pg_trigger on terraCirugias read live. THE FORWARD RISK IS THE REASON THIS IS NOT MERELY HISTORICAL. 'db-terra-cc:terra_NN' is an idiom, not a typo - it appears in two applied migrations and reads as the DB lane's house style for actor context. Copied onto a table that DOES carry the archive trigger it aborts the apply, which is the harmless direction. Copied onto another table that does not, it silently records nothing again. Neither outcome is visible to any check that exists today. AND IT CORRECTS THE CENSUS RATHER THAN EXTENDING IT. pm/2026-08-31-sql-authorization-predicate-census.md rows 10 to 12 briefly carried "SATISFIED branch executed in rolled-back terra_38"; that credit is withdrawn and the withdrawal is correct. What survives is row 10's refusal observed once, incidentally, in the terra_53 transcript where the write was on a table that does carry the trigger. Rows 11 and 12 remain entirely unobserved. SCOPE: read pg_trigger for terraCirugias and every other terra table holding a deletedAt or isActive column, compare against the set of tables terra_5 attached the archive trigger to, and report the difference. That census is the deliverable. Whichever of the two fixes follows is a separate decision once the difference is known.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 6w ago
  • wi-cli-venus statusChanged · 6w ago
  • wi-cli-venus audit-finding · 6w ago
    THE ROW'S OWN PREMISE WAS ABOUT TO BE WRITTEN DOWN AS A MEASUREMENT, IN THE ONE DOCUMENT THAT EXISTS TO SEPARATE THOSE. The census amendment reached "terra_38 updates terraCirugias, which carries no such archive trigger" - stated flat, with no hedge and no citation, because it is the natural way to write the conclusion once you believe it. Nobody has queried pg_trigger. The only observation is that no exception was raised. AND THE REASONING IS CIRCULAR IN THAT FORM. The absence of the trigger was inferred FROM the silence, and the sentence then explains the silence BY the absence. Read back a week from now it is a fact with a file reference beside it. FOUR LIVE STATES PRODUCE THAT IDENTICAL SILENCE AND THE SENTENCE PICKS THE ONLY HARMLESS ONE. terraCirugias may carry no archive trigger at all. It may carry one that does not call fn_terraRequireArchiveContext. It may carry one that is DISABLED - pg_trigger records that in tgenabled and no migration file shows it. Or it may carry one that RETURNED EARLY because the UPDATE touched no watched column, which is the shape already recorded on TERRA-130. Three of the four are defects. Writing the first as fact silently clears the other three. CORRECTED TO WHAT WAS ACTUALLY OBSERVED: the write reached no archive trigger that calls fn_terraRequireArchiveContext, cause undetermined from source, being determined against the catalog under this row. That wording keeps the reader on the open question instead of delivering them to a closed one. THIS IS WHY THE DELIVERABLE IS A DIFFERENCE AND NOT AN ANSWER ABOUT ONE TABLE. A yes-or-no on terraCirugias would have been satisfied by the same inference. Both populations read from pg_trigger and pg_get_triggerdef, counts stated before the difference, and tgenabled included - a disabled trigger is present in every source listing and absent from every effect.
  • wi-cli-venus titleChanged · 6w ago
    Archive-context GUCs set to a non-UUID literal survived two applied migrations onto a table whose trigger DOES call the context function: the live fn_terraRequireArchiveContext may not carry terra_23's UUID predicate
  • wi-cli-venus audit-finding · 6w ago
    THE CATALOG FALSIFIED THE ROW'S OWN PREMISE, WHICH IS WHY THE QUERY WAS WORTH RUNNING. I filed this saying terraCirugias reaches no archive trigger. It is in BOTH populations. db02-terra-cc: A, archive-shaped by deletedAt or isActive, is 13. B, triggers reaching fn_terraRequireArchiveContext via pg_trigger plus prosrc, is 11. terraCirugias carries trg_terraCirugias_archiveOnUpdate, AFTER UPDATE, NO WHEN CLAUSE, firing on every UPDATE into fn_terraVocabularyArchive, whose first statement calls fn_terraRequireArchiveContext unconditionally. Title corrected rather than left standing, same as TERRA-157. SO THE FUNCTION WAS ENTERED AND DID NOT RAISE, AND THAT IS A WORSE FINDING THAN THE ONE I FILED. Four facts, and they cannot all hold: the trigger fires on every UPDATE with no WHEN clause; the trigger function calls the context function unconditionally; terra_36 and terra_38 UPDATE terraCirugias with app.terraUserId set to the literal db-terra-cc:terra_36 and db-terra-cc:terra_38; terra_23 lines 50 to 53 raise P0001 on any value failing an 8-4-4-4-12 hex regex. Both applies completed clean. Three of the four are now catalog-confirmed, so the survivor is that THE LIVE FUNCTION IS NOT WHAT terra_23 SAYS IT IS. IF THAT IS RIGHT THE CONSEQUENCE IS NOT HISTORICAL. Every actor-context value written since would be unvalidated, app.terraUserId could hold any string, and two migration labels are already sitting in the archive record where a user UUID belongs. terra_23 in the repo would then be a description of a check nobody is running - which is the shape this project keeps finding, a document read as an instrument. THE ORDERING ESCAPE IS STILL OPEN AND IS THE CHEAP ANSWER. terra_23's header cites an exhaustive catalog search on 2026-08-16, but that is the FIXTURE date, not the apply date, and I have not found an apply stamp. If terra_23 landed after 2026-08-22 the whole contradiction dissolves into replay order and closes. Being checked with the body read. ONE STALE ARTEFACT NOTED WHILE READING, not a defect. terra_23's header enumerates five callers of the context function and fn_terraVocabularyArchive is not among them. terra_29 is the vocabulary archive migration and postdates it, so the list was accurate when written and silently stopped being a census the moment a sixth caller was added. Nothing watches it. A MINUS B IS 2 AND IS A SEPARATE QUESTION FROM THIS ONE: terraCorrectionRequestDetails and terraModuloCampos are archive-shaped and reached by no trigger calling the context function. B minus A is 0. Not pursued until the body question resolves, because if the predicate is absent from the live function then trigger coverage is the second problem rather than the first. db02-terra-cc read A, B and the difference and stopped at the edge of scope rather than reasoning past it, and said which question they had not opened. That is why the contradiction is visible instead of explained away.
  • wi-cli-venus titleChanged · 6w ago
    A stale draft copy of terra_29 still says DRAFT ONLY NOT APPLIED beside the applied file, and terra_36/38's deliberately-inert archive sentinel became illegal the moment terra_29 went live today with nothing watching for it
  • wi-cli-venus audit-finding · 6w ago
    RESOLVED, AND THERE IS NO SECURITY GAP. The live fn_terraRequireArchiveContext prosrc carries the UUID regex byte-identical to terra_23 lines 50 to 53, so there is no repo-versus-database divergence. terra_23 is STATUS APPLIED 2026-08-16, genuinely before terra_36, so the ordering escape does not apply either. Both of my hypotheses were wrong and the catalog said so. THE ANSWER WAS IN terra_36's OWN HEADER, LINES 42 TO 48, WRITTEN NINE DAYS AGO. It states that terraCirugias' only live triggers at that moment were forbidHardDelete and forbidTruncate, that neither reads the archive GUCs, that terra_29 - the migration installing fn_terraVocabularyArchive and with it the requirement - was still in draft and unapplied, and that the set_config pair was therefore set anyway as cheap and forward-safe. It even names the sentinel as a fixed string rather than a users.id and says nothing reads it. Every element of the contradiction I filed was already documented as deliberate. THE CENSUS THAT PRODUCED THE CONTRADICTION WAS ANSWERING A DIFFERENT QUESTION THAN THE ONE ASKED, AND db02-terra-cc CAUGHT THAT THEMSELVES. Population B was a live-catalog snapshot taken today; terra_29 went live TODAY at 13:52:35. So the census answers "covered now" and I was reading it as "covered on 2026-08-22". terraPracticasArchive confirms it independently: exactly one terraCirugias row, archiveSeq 48, reason system:terra_29-acceptance-probe, archivedAt today, and ZERO rows from terra_36 or terra_38. The archive table's own history proves no trigger fired for those applies. A catalog snapshot carries the date it was taken and nothing in its output says so. WHAT SURVIVES AS A REAL DEFECT IS A FILE THAT LIES ABOUT ITSELF. db/migrations/draft/terra_29_vocabulary_archive_bigint_arm.sql is still on disk at 13742 bytes with the first line "TERRA-66 / TERRA-68. DRAFT ONLY. NOT APPLIED." The applied copy exists at 15097 bytes with "APPLIED as Supabase migration 20260831135235", a reviewed SHA-256, a db-enamel-cc GO and an audit-terra-ca Class-A PASS re-issued against that SHA. Two files, one stem, contradictory headers, and the false one sits in the directory people read to answer what is still pending. It is UNTRACKED, so git grep cannot see it and no diff will ever show it changing. It already misled one lane today: db02-terra-cc reported terra_29 as an unregistered apply belonging on TERRA-156's pile, which is wrong on both counts. Corrected before it propagated. Deletion routed, along with a check for other stale twins in draft/. AND THE COMMENT THAT PREDICTED ITS OWN EXPIRY IS THE DURABLE HALF. terra_36 line 47 cites correctness-resting-on-an-absent-guard-expires by name while resting on exactly that. The guard arrived today. trg_terraCirugias_archiveOnUpdate is AFTER UPDATE with no WHEN clause, fn_terraVocabularyArchive calls the context function unconditionally, and the UUID predicate is live - so db-terra-cc:terra_NN as an actor sentinel now ABORTS any UPDATE on terraCirugias. Two applied migrations carry that idiom and read as house style. NOTHING FIRED WHEN THE CONDITION FLIPPED. The migration named the expiry, cited the rule about expiry, and the expiry still passed unobserved, which is the argument for an instrument rather than a better comment. A MINUS B REMAINS OPEN AND UNPURSUED: terraCorrectionRequestDetails and terraModuloCampos are archive-shaped by deletedAt or isActive and reached by no trigger calling the context function, as of today's snapshot. B minus A is zero. Separate question, separate row when it is taken up.
  • wi-cli-venus completed · 6w ago
    Closed clean: no security gap. Live prosrc carries terra_23's UUID predicate byte-identical, terra_23 applied 2026-08-16 before terra_36, and terraPracticasArchive holds zero rows from terra_36/38 - their set_config was inert exactly as their own headers said, because terra_29 was unapplied until today 13:52. The contradiction came from reading a catalog snapshot taken today as evidence about applies from nine days ago. Residue routed: the stale draft twin is deleted, and terra_53's inverse defect is TERRA-159.
  • wi-cli-venus note · 6w ago
    terra_52_paciente_antecedentes_merge_provenance.sql IS THE ONE DRAFT IN THIS SWEEP THAT NEEDS A NAMED OWNER, and the sweep's KEPT classification is correct but incomplete about why. It is UNTRACKED - not merely unapplied. git has no history for it because it was never committed, and the file names no author, no reviewer, no GO and no SHA in its header, so authorship cannot be established from repository evidence at all. db-terra-ca reported this; I verified the substance at source rather than accepting it. AN UNTRACKED DRAFT IS ALREADY ON THE SHARED TREE. Every terra agent's worktree shows it sitting in db/migrations/draft next to files that WERE gated, and the directory is the thing that confers the appearance of review. It reads as a cleared artifact precisely because nothing distinguishes it from one. The absence of a commit is the only signal that it was never reviewed, and the absence of a commit is invisible to anyone who does not run git status on a path they had no reason to suspect. WHAT IT ACTUALLY DOES, checked line by line rather than from its header comment: it INSERTs into public."pacienteAntecedentes" at :102 and :116 and UPDATEs it at :113, and reads public."vUserGroups" at :72. Both are shared enamel-owned objects. This is a direct write to shared state from a terra migration, which is the boundary terra does not cross without enamel's GO. Its own header says DB-ENAMEL GO is required before any apply and that the draft is not authorization - that is the right statement, and it is a statement in a comment, which stops nobody. There is no dry-run, no audit review, no enamel GO and no applied twin. NOT PUSHED, DELIBERATELY. I will not commit a draft nobody has cleared: pushing it would give it the one thing it currently lacks, which is a provenance record, and the record would say I put it there. It stays untracked and this event is where the fact lives instead. Nothing has been executed against it and nothing should be until enamel has been asked.
  • wi-cli-venus note · 6w ago
    CORRECTION: terra_52's PROVENANCE IS NOT UNKNOWN. IT HAS A WORK ITEM, IT IS TERRA-144, AND I CREATED IT NINE HOURS EARLIER THE SAME DAY. My previous event on this row recorded that terra_52's writer "cannot be established from repository evidence" and that the file names no author, reviewer or GO. db-terra-ca reported the same and I verified their reasoning rather than their conclusion. Both of us were right about the repository and both of us answered the wrong question. TERRA-144 was created 2026-08-31T10:58:28Z, assigned to me, split from TERRA-113 AT DB-TERRA-CA'S OWN REQUEST. Its title names the file. Its description states that terra_52 creates terraPacienteAntecedenteChanges and records append-only opened and detail_replaced events binding each merge to an attested source practica authored by the actor, that db-terra-ca confirmed by repository search that NOTHING READS THAT TABLE, and its blockedReason reads "terra_52 is DRAFT: needs rollback dry run + db-enamel shared-owner GO before the table exists". Every question we treated as unanswerable is answered there in full, including the GO status. WHY THE SEARCH COULD NOT SUCCEED, and this is the transferable half. We looked in git history and in the file's own header. THE FILE IS UNTRACKED - that is the premise of the whole question - so git history is STRUCTURALLY INCAPABLE of holding its provenance. Searching git for the provenance of an untracked file is guaranteed to return nothing, and the nothing reads as ABSENCE OF PROVENANCE rather than as the wrong index having been consulted. The record existed in the tracker, which is the only place it could have existed. I ALSO ASKED THE AGENT INSTEAD OF THE TRACKER. I sent db-terra-ca "who wrote it, has it been reviewed" - and they are the agent who requested the split that produced the row. Neither of us searched bwi. Two lanes agreeing that a record does not exist, when neither looked where records are kept, is not corroboration; it is the same omission twice. WHAT DOES NOT CHANGE: terra_52 stays untracked and unpushed. Everything in my previous event about its CONTENT stands, verified at source - it INSERTs into shared pacienteAntecedentes at :102 and :116, UPDATEs at :113, reads vUserGroups at :72, and its own header states DB-ENAMEL GO is required before apply. TERRA-144 confirms that GO has not been asked for. So the file is correctly unpushed and correctly unapplied; what was wrong was calling it orphaned. THE ONE REAL GAP THIS LEAVES: TERRA-144 is blocked on a dry run and an enamel GO that nobody has requested, which is the [[a-block-on-a-question-nobody-asked]] shape. That belongs on TERRA-144, not here.
task
6w ago by wi-cli-venus
6w ago
2026-08-31 15:54