Dry-run transcript coverage over 54 applied migrations (2026-08-31): 14 have one, 32 carry post-apply claims only, 5 carry post-DDL in-transaction asserts, 3 carry entry guards only - backfilling would manufacture the evidence, not recover it
MEASURED 2026-08-31, immediately after the TERRA-163 backfill put 38 dry-run files under db/migrations/dryrun/. THIRTY-NINE OF THE FIFTY-TWO APPLIED MIGRATIONS HAVE NO DIRECT TRANSCRIPT. Found by audit-terra-ca in an independent source-only pass and reproduced here by counting rather than accepted as reported: 53 files in db/migrations/applied (terra_1 is two files), 39 with no matching terra_NN entry in dryrun/. The set: terra_1 initial_schema and seed_vocabulary, terra_2 through terra_28 except 29, terra_30, terra_32, terra_40, terra_41, terra_42, and terra_45 through terra_48. Direct corpus coverage is 13 of 52. The README's twelve deliberately-unpaired files do not change that number - they are a different gap and already stated. WHAT THIS IS NOT, AND THE DISTINCTION IS THE WHOLE ROW. Absence of a retained transcript is NOT evidence that a migration was never dry-run, never applied, or behaved incorrectly. Every one of these is in applied/ because it was applied. What is missing is the RECORD of what came back, and reading a missing record as a defect would manufacture 39 incidents out of a filing convention that did not exist yet. audit-terra-ca said exactly this and it is right: file one decision, not 39 retrospective failures. WHY IT STILL MATTERS. The convention established in TERRA-163 says a script and its transcript are one artifact in two files, and that a transcript with no script cannot be re-run or audited. The inverse is just as true and nobody had stated it: an applied migration with no transcript cannot be audited either. It asserts its own correctness and there is nothing to check it against. That is the Class-A audit gate resting on evidence that, for 39 of 52 migrations, does not exist in the repository. NOT RE-DERIVABLE, WHICH IS WHY THIS IS A DECISION AND NOT A TASK. Re-running terra_11's dry run today measures TODAY'S data. It would produce a file with the right name asserting something about the wrong date - the same trap already recorded for the ten census transcripts. Backfilling these would MANUFACTURE the evidence rather than recover it, which is the more dangerous of the two failures because the result is indistinguishable from the real thing. THE DECISION REQUIRED, and it is two separate questions that must not be answered as one: 1. GOING FORWARD: is a retained dry-run transcript a REQUIREMENT for any future applied migration, or a convention that lapses quietly the first time someone is in a hurry? Today nothing enforces it. The README states it; no gate checks it. A convention with no instrument is a warning, and this project has already recorded that a warning is not an instrument. 2. HISTORICAL: is the 39-file gap ACCEPTED as baseline, explicitly and in writing, or does some subset warrant re-establishing evidence by a means that is honest about its date - a fresh census stating what is TRUE NOW rather than a transcript pretending to be from 2026-07? The two are different artifacts and must not share a filename convention. MY RECOMMENDATION, offered as a recommendation because scope is not mine to decide: answer 1 as a requirement with a gate that actually reads the directory, and answer 2 as accepted baseline recorded in the README, on the grounds that the alternative is fabricated evidence. Do not open rows against the 39. OUT OF SCOPE OF THE LANE THAT FOUND IT, stated rather than implied: audit-terra-ca holds no database connection, so none of this touches whether the migrations are actually correct in the live schema. It is a census of what the REPOSITORY retains. Drafts terra_50, terra_51 and terra_52 are excluded as unapplied; terra_51's script-without-result is already documented in the dryrun README.
Activity
-
THE CENSUS IN THIS ROW IS STALE AND THE FIX IS NOT ARITHMETIC. The row says 39 of 52 applied migrations have no retained transcript. The applied directory holds 54 terra_*.sql files today, counted just now, terra_54 among them. Found by audit-terra-ca comparing open rows against current source; I counted it myself rather than accepting the number. DO NOT SIMPLY EDIT THE DENOMINATOR TO 54, because the numerator's definition is what actually broke. terra_54's retained proof is named by WORK ITEM - terra_165-comment-fix-regression-arms.result.md - not by migration number. Any census that matches transcripts to migrations by filename number counts terra_54 as having none, and it has one. So the question the row exists to answer, how many applied migrations lack evidence, cannot be recomputed until DIRECT TRANSCRIPT is defined explicitly enough that a file named after a WI still counts, or is explicitly ruled not to count. That definition is a decision, not a measurement, and it belongs to this row. A SECOND DEFINITIONAL PROBLEM ARRIVES WITH terra_54 AND IT IS SHARPER. It was applied TWICE on the same day. The first execution ran the wrong text - comment-stripped, not the file's bytes - and reported complete success with every catalog field correct. The second ran the committed bytes. A census that asks whether an apply left evidence would score that file as evidenced on the strength of the FIRST apply's report, which was internally consistent and wrong. So retained evidence is not one property. There is evidence that SOMETHING ran, which a report supplies, and evidence that THE FILE'S OWN TEXT ran, which only a content-derived measurement against the committed bytes supplies. This row has been counting the first and reading it as the second. TERRA-171 owns the rule about what an apply report must carry; this row owns whether a retained transcript is required at all and whether the historical gap is accepted baseline in writing. They should be settled together, in that order, because the answer here depends on what a transcript is obliged to contain. RECOUNT ONLY AFTER THOSE DEFINITIONS EXIST. A number recomputed against the old definition would be precisely the failure this corpus keeps recording: a fresh measurement that reads as progress while measuring the wrong thing.
-
TWO DEFINITIONS FIRST, because this row cannot be recounted without them and the original 39-of-52 was taken before either existed. DEFINITION 1 - what counts as a TRANSCRIPT. An artifact is a dry-run transcript of migration M only if it is a record of M's OWN STATEMENTS having been executed and rolled back, or executed and read back. It is NOT a transcript because it names M. This is not pedantry, it is the difference between the two numbers below. DEFINITION 2 - the distinction the Class-A gate actually rests on, and the one nobody had stated. There are TWO properties and the evidence for them is different: (a) EVIDENCE SOMETHING RAN - a post-apply catalog read-back. It proves the database is now in the expected shape. It cannot distinguish "this file's text ran" from "text that produces the same shape ran", which is exactly the terra_54 failure: the first apply reported every catalog field correct having executed comment-stripped text. (b) EVIDENCE THIS FILE'S TEXT RAN - only a content check on the artifact the migration actually writes. For CREATE OR REPLACE FUNCTION that is md5(prosrc) against the file's extracted body, now specified in db/migrations/APPLY-VERIFICATION.md (TERRA-171, d8738d8). A dry-run transcript is evidence of NEITHER on its own - it is evidence that the statements WERE ONCE VALID AND HAD THE INTENDED EFFECT AGAINST LIVE DATA, which is a third thing, and it is the thing the audit gate consumes. Conflating the three is why this row's number never settled. MEASURED NOW, and both numbers stated because the gap between them IS the finding: - BY FILENAME, the instrument the original count used: 54 applied files, 15 have an artifact whose NAME carries their migration number, 39 do not. terra_1 through terra_28 are almost entirely in the 39, plus 12A/12A2/12B, plus 40/41/42/45/46/47/48/54. - BY CONTENT, grepping every file under db/migrations/dryrun and agents/*/evidence: 24 of those 39 are MENTIONED somewhere. That number is worthless as coverage and I am recording it as a trap rather than as progress. terra_1's hits are a table-selection census; terra_13/20/21/22/24/25/27's are a tgname-scoping census; terra_2/3/5's are inside terra_31's r4 dry-run, which exercises terra_31. None of those are transcripts of the file named. A mention is a citation, not an execution. - The ONE case where content-matching finds something real is terra_54, whose transcript exists under a WI NAME (2026-08-31-terra_165-comment-fix-regression-arms.sql/.result.md) and not a migration number. That is the case that breaks filename-counting, and it is why 39 is an upper bound on the gap rather than the gap. THE NUMBER ALSO WENT STALE WITHOUT CHANGING SHAPE. The row says 39 of 52. It is now 39 of 54 - the corpus grew by two and the deficit happens to still read 39. Same accidental-truth failure as the citation checker's 30-file comment, in a different file, three days apart. A count decays silently; state the DENOMINATOR and the DATE or state a named set. WHAT THIS TICK DID NOT DO, stated rather than implied: I did not read the 39 files' headers to classify each into transcript / read-back-only / nothing. That is 39 reads and it is the actual remaining work. Both numbers above are instrument outputs, and neither is the answer. CLOSE CONDITION, replacing "recount": every applied file classified into exactly one of - (A) has a dry-run transcript of its own statements, (B) has post-apply catalog read-back ONLY, so evidence something ran but not that this text ran, (C) has neither. Classification by READING the artifact, never by filename or grep. Report the three named sets, not three counts. Backfilling a transcript for anything in (B) or (C) remains forbidden - it would manufacture the evidence rather than recover it, which is the reason this row exists.
-
CLOSED ON FOUR NAMED SETS OVER A STATED DENOMINATOR, 54 applied migrations, dated 2026-08-31. Classification by db02-terra-cc READING each file and each matching dryrun/evidence artifact - never by filename and never by grep, both of which this row already proved worthless. A (14) - a retained artifact replays THAT migration's own statements, rolled back or read back, independent of the real apply: terra_31, 32, 33, 34, 35, 36, 37, 38, 39, 43, 44, 49, 53, 54. B (32) - post-apply catalog or behavioural confirmation STATED AS FACT in the file, no separate re-execution of its own statements: terra_1 (both files), 2, 3, 4, 5, 6, 10, 11, 12A, 12A2, 12B, 13, 14, 15, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 40, 41, 42, 45, 46, 47, 48. D (5) - post-DDL in-transaction assertion, no retained artifact: terra_7, 17, 18, 19, 23. C (3) - pre-DDL entry guard only, which says nothing about whether the change landed: terra_8, 9, 16. SET D IS THE FINDING AND IT DID NOT EXIST WHEN THIS ROW WAS WRITTEN. The first classification put all eight of C+D in "neither", which reads as UNVERIFIED. I spot-checked rather than accepted it and found every one of the eight carries a top-level DO assertion block; db02 then re-derived all sixteen DDL/DO line positions independently rather than take my grep, and split them on position. An in-transaction assertion is not a transcript (nothing survives) and not a post-apply read-back (it runs mid-apply), so the three-box taxonomy had nowhere to put it and it fell into the box that means "no evidence". ON THE ONE PROPERTY THIS ROW EXISTS TO ESTABLISH, D IS STRONGER THAN B. A failed assert ABORTS THE TRANSACTION, so "this migration is in the applied corpus" ENTAILS "this assertion passed against this file's own statements". It cannot be a stale claim, a transcribed claim, or a claim about text that differs from the file - which is precisely the terra_54 failure that motivated this row and that nothing in B can exclude, because B's evidence is A SENTENCE SOMEBODY WROTE while D's is A CONSEQUENCE OF THE APPLY HAVING SUCCEEDED. What D lacks is auditability after the fact: there is no artifact to re-read, only the inference, which is exactly why it looked like absence. THE PRE/POST SPLIT IS NOT COSMETIC. A pre-DDL guard checks preconditions and is genuinely evidence of nothing about the outcome, so terra_8/9/16 stay in C. Collapsing D and C would have inflated the coverage claim by three files. TWO INSTRUMENT LESSONS THIS ROW PAID FOR, both recorded because the wrong instrument passed twice. A MENTION IS A CITATION, NOT AN EXECUTION: content-grep found 24 of 39 "covered" and every one that mattered was a census citing the migration number, not a transcript of it. FILENAME-MATCHING FAILS THE OTHER WAY: terra_54's real transcript is named for its WI, carries no migration number, and was invisible to the count. And the original figure went stale without changing shape - "39 of 52" became "39 of 54" with the deficit still reading 39. State the denominator AND the date, or state a named set. BACKFILL REMAINS FORBIDDEN for B, C and D. Writing a transcript now would manufacture the evidence rather than recover it, which is the condition this row was opened against. ONE DEFECT FOUND IN PASSING, NOT FIXED HERE because it is DDL and db-terra-cc's: terra_17's assert reads `SELECT proconfig INTO v_conf FROM pg_proc WHERE proname = 'changeTerraMembership'` - namespace-unqualified and overload-undiscriminated, and INTO silently takes an arbitrary row if a second match ever exists. Correct today only because exactly one such function exists; a guard whose correctness rests on the absence of a second definition.
-
completed
-
Dry-run transcript coverage over 54 applied migrations (2026-08-31): 14 have one, 32 carry post-apply claims only, 5 carry post-DDL in-transaction asserts, 3 carry entry guards only - backfilling would manufacture the evidence, not recover it
-
CATALOG RECONCILIATION OF applied/ AGAINST THE LIVE DB: PASS, ZERO DISAGREEMENTS, AND THREE FILES THAT STAY UNMEASURED. This is the complement of what this row measures. This row counts TRANSCRIPTS, which record what came back at apply time. This measures whether the DB today actually holds what the files claim - a different question with a different failure mode, and the two together bound the gap much more tightly than either alone. RUN BY db-terra-ca on 2026-08-31, SELECT only, ref eprpywqwzsvrjeaforei confirmed before reading. Evidence at agents/db-terra/evidence/2026-08-31-applied-live-reconciliation.md. COUNTS: 54 files in db/migrations/applied. 55 rows in supabase_migrations.schema_migrations. 22 terra_* history rows, 22 exact-name matches. 32 files with no same-name history row. THE 32 ARE NOT DRIFT AND THE REASON IS STRUCTURAL, NOT AN EXCUSE: db-enamel-cc applies terra DDL under enamel_NNN names, so a terra file's absence from history proves nothing whatsoever about whether it ran. Name-based comparison is invalid on this project and a report built on it would show 32 false findings. The catalog is the only arbiter. WHAT THE 32 SPLIT INTO, which is the number I actually asked for, because "set aside as explained by naming" and "confirmed by catalog" are different states and only one is evidence: 29 confirmed by OBJECT-SPECIFIC catalog evidence of their principal persistent structural or ACL effect - pg_class/namespace for tables and views, pg_proc plus pg_get_functiondef and proconfig for functions, pg_trigger plus pg_get_triggerdef for triggers, pg_indexes for terra_9, pg_default_acl for terra_46 and terra_47, pg_attribute for userGroups.revokedBy. ZERO were set aside on the naming argument alone. Not a whole-file text diff in any case. THREE REMAIN UNMEASURED FOR EXACT SOURCE REPLAY, and the word stays as written rather than being upgraded: terra_1_seed_vocabulary.sql, terra_7_seed_cirugias.sql, terra_43_cirugias_strip_conf_annotation.sql. All three are DATA-ONLY. They leave no catalog object behind, so the instrument that confirmed the other 29 cannot reach them at all - present-state data could have arrived by any path. This is the same class this row exists for: absence of a measurement is not a defect, and calling these three failures would manufacture three incidents out of the shape of the data. A LIMIT db-terra-ca STATED WITHOUT BEING ASKED, and it is the right one to keep: for files that successively REPLACE the same function, a current catalog definition confirms the current endpoint state, not that every historical intermediate body was replayed. Catalog presence is not exact source replay and none of the 29 are upgraded to it. ONE FALSE POSITIVE WAS REPORTED AND WITHDRAWN, recorded because the mechanism generalises. terra_54_changeTerraMembership_lastAdmin_comment_correction was first reported as a real BLOCK - in applied/, no live history, and the corrected comment missing from pg_get_functiondef. I checked it before acting: the comment IS live, oid 36520, exactly one changeTerraMembership with no overload. Cause, confirmed by the author: the search pattern was written from the file's PROSE, "lastAdmin is UNREACHABLE today", while the literal carries a BACKTICK - lastAdmin-backtick-space-is UNREACHABLE today. A pattern retyped from how a line reads does not match how it is stored. Detail on TERRA-161. They did NOT do a whole-file diff and did not read a different DB or function, so the 29 were produced by a sounder method than the one bad pattern, which is what I needed to know before keeping the rest. NET FOR THIS ROW: 39 applied migrations have no transcript, and now 29 of the 32 unnamed-in-history files have independent catalog evidence that their effect is live. That does not restore a transcript and does not close anything here. It narrows what the missing transcripts could be hiding: not "did the object arrive", which is now measured, but "what came back at the time, and whether anything unexpected was in it" - which remains unrecoverable and is exactly why backfilling would manufacture evidence rather than recover it. DECAY CONDITION, so this measurement does not quietly become perishable: it is true of the DB as of 2026-08-31 and of the 54 files present then. It says nothing about any migration applied afterwards.