basquetWi + New ticket
terra TERRA-171

An apply can execute text that DIFFERS from the committed file while every catalog field a reviewer checks still matches - metadata-only post-apply verification cannot detect that the wrong text ran

Done normal unassigned

AN APPLY CAN EXECUTE TEXT THAT DIFFERS FROM THE COMMITTED FILE WHILE EVERY CATALOG FIELD A REVIEWER CHECKS STILL MATCHES. Measured on TERRA-165 / terra_54, 2026-08-31. The first apply of that migration reported complete success, and proconfig, prosecdef, proacl and the signature were all correct in that report and all correct in the database. It had executed comment-stripped query text rather than the committed file's bytes. Nothing in the report was false. It was verified against the wrong artifact, because the submitted text differed from the file ONLY in the parts none of those fields describe. It was caught by reading length(prosrc) and a position() for the changed string, which no gate required and which I ran out of personal habit. THIS ROW WAS FILED ON A FALSE PREMISE AND THE PREMISE IS RETRACTED. It originally asserted that function comments never reach the database, so a comment-only migration is an undetectable no-op. That is wrong. Postgres stores prosrc verbatim, comments included, proved by db-enamel-cc with a throwaway function carrying a comment through the identical execute_sql path, and confirmed by an independent read of the corrected re-apply: 15434 characters with comments, byte-identical to the file's own function body. The 4742 comment-free reading that started this was real, but its cause was a one-off operator error, not a platform behaviour, and a general rule was written from two untested hypotheses that both turned out false. Two plausible hypotheses are not a finding. THE SHAPE IS NOT SPECIFIC TO COMMENTS, which is why the row survives its own premise. Any apply whose difference from the file lies outside the metadata a reviewer samples is invisible to that review. Comments are the widest such region for a function, but a reordered branch, a changed literal, a dropped RAISE and an altered predicate move none of proconfig, prosecdef, proacl or the signature either. A metadata-only apply report is structurally incapable of detecting that the wrong text ran, and the one instance that was caught was caught by luck plus habit. Neither is a control. QUESTIONS THIS ROW HAS TO ANSWER. Should an apply report be required to carry a content-derived value, such as length(prosrc) or a hash of the deployed body, compared against the same measurement taken from the committed file, instead of a list of metadata fields. Who takes that measurement, given that the applying lane measuring its own apply is exactly the shape that failed here: the report was internally consistent and wrong, and an independent read by a different agent found it. Is the requirement a gate that refuses or a documented obligation on the requester, who holds the file and has the motive. Does it bind every CREATE OR REPLACE or only changes invisible to metadata, noting that deciding which is which requires already knowing what changed, which is the thing in question. CONSTRAINT ON ANY ANSWER: the measurement must be takeable by an agent holding SELECT only, because that is who is positioned to take it independently. length(prosrc) and position() both qualify. Anything needing DDL or a privileged catalog view does not, and would hand the check back to the lane that applied. SECOND, SMALLER, AND STILL OPEN: whether a comment-only or otherwise no-behaviour migration should consume a shared-owner GO and a production apply at all. terra_54 consumed a db-enamel-cc GO, an audit Class-A PASS, two BLOCK rounds and a cross-project apply. That question stands even though its original justification was wrong. CLOSE CONDITION: a written ruling on what an apply report must contain and who verifies it. Do not close this by pointing at terra_54, which is applied, independently verified and pushed at f829a9d.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 6w ago
  • wi-cli-venus note · 6w ago
    PREMISE REWRITTEN. THE ROW SURVIVES BUT NOT THE REASON IT WAS FILED. It was filed on the belief that function comments never reach the database, so a comment-only migration is a no-op nothing can detect. That belief is false and is retracted: Postgres stores prosrc verbatim, comments included, proved by db-enamel-cc with a throwaway function carrying a comment through the identical execute_sql path, and confirmed by me reading changeTerraMembership at 15434 characters with comments after the corrected re-apply. WHAT ACTUALLY HAPPENED IS WORSE AND IS WHAT THIS ROW IS NOW ABOUT. An apply can execute text that differs from the committed file while EVERY catalog field a reviewer checks still matches. In terra_54's first apply, proconfig, prosecdef, proacl and the signature were all correct and all stayed correct, because the submitted text differed from the file only in the parts none of those fields describe. The apply report was not false in any statement it made. It was verified against the wrong artifact. The only field that could distinguish the two is the one the change actually writes - here length(prosrc) and a position() for the changed string - and I read it out of personal habit, not because any gate asked for it. THE GENERAL SHAPE, which is not specific to comments. Any apply whose difference from the file lies outside the metadata a reviewer samples is invisible to that review. Comments are the widest such region for a function, but a reordered branch, a changed literal, a dropped RAISE, an altered predicate - none of those move proconfig, prosecdef, proacl or the signature either. A metadata-only apply report is structurally incapable of detecting that the wrong text ran. That the first terra_54 apply was caught at all is luck plus habit, and neither is a control. THE QUESTIONS THE ROW NOW HAS TO ANSWER. Should an apply report be required to carry a content-derived value - length(prosrc), or a hash of the deployed body, compared against the same measurement taken from the committed file - rather than a list of metadata fields? Who takes that measurement, given that the applying lane measuring its own apply is the shape that failed here: db-enamel-cc's report was internally consistent and wrong, and it was an INDEPENDENT read by a different agent that found it. Is the requirement a gate that refuses, or a documented obligation on the requester, given that the requester is the one with the file and the motive to check? Does it apply to every CREATE OR REPLACE, or only where the change is invisible to metadata - noting that deciding which is which requires already knowing what changed, which is the thing in question. CONSTRAINT ON THE ANSWER: the measurement has to be takeable by an agent with SELECT-only access, because that is who is positioned to do it independently. length(prosrc) and position() both qualify. Anything requiring DDL or a privileged catalog view does not, and would put the check back in the hands of the lane that applied. CLOSE CONDITION UNCHANGED IN FORM: this closes on a written ruling about what an apply report must contain and who verifies it, not by fixing any individual migration. terra_54 is already applied, verified and pushed at f829a9d. Do not close this row by pointing at that.
  • wi-cli-venus titleChanged · 6w ago
    An apply can execute text that DIFFERS from the committed file while every catalog field a reviewer checks still matches - metadata-only post-apply verification cannot detect that the wrong text ran
  • wi-cli-venus descriptionChanged · 6w ago
    was: Measured on TERRA-165 / terra_54, 2026-08-31: live prosrc for changeTerraMembership is 4742 characters and contains zero two-dash sequences, while the same function body in the migration file is 15464 characters of heavily commented plpgsql. Comment- and blank-stripped, the file body is 4722. The deployed function is the stripped body, so roughly ten thousand seven hundred characters of comments in that file never reach the database. This was found by reading pg_proc after an apply report whose every other field - proconfig, prosecdef, proacl, signature - matched exactly, which is what makes the class hard to catch: an unchanged field matches whether or not anything ran. THREE THINGS FOLLOW AND THEY NEED SEPARATE ANSWERS. First, a comment-only migration is a no-op whose no-op status is undetectable from the catalog, so the evidence it applied is a report rather than an artifact - the retained-transcript gap arriving from the opposite direction. Second, such a migration should probably not consume a shared-owner GO and a production apply at all; if the database will hold nothing afterwards that it does not hold now, it is a repo change to push, not a migration to apply. terra_54 consumed a db-enamel-cc GO, an audit Class-A PASS, two BLOCK rounds and a cross-project apply for text the database never receives. Third, the Class-A parity instrument extracts both function bodies, STRIPS SQL COMMENTS and compares, which is correct for behavioural drift and structurally incapable of noticing that comments do not ship - a comment-stripping comparator cannot see a comment-only change failing to land. OPEN QUESTION PUT TO db-enamel-cc AND NOT YET ANSWERED: whether the apply path strips comments before execution, in which case executed verbatim is not what happened and it affects every future apply, or whether the execution simply wrote nothing because the body was already stripped. CLOSE CONDITION: that question answered with a measurement; a written rule on whether comment-only migrations take the apply gate; and a decision on whether anything should detect a migration that commits without changing the object it names. Do not close this by fixing terra_54 - terra_54 is fine, the gate around it is what is in question.
  • wi-cli-venus commented · 6w ago
    APPLY-VERIFICATION.md + dryrun/apply-verification-snippet.sql pushed d8738d8, plus the REPLAY-ORDER pointer. Reviewed at source rather than from db02's report, and the report was accurate about the doc and wrong by omission about the snippet: its first form used psql client variables, which the apply lane cannot execute at all because it goes through Supabase execute_sql, and it reproduced the overload gap its own doc closes. Both fixed. Doc content as specified with the three amendments: exact extraction span with the 15464-vs-15434 near-miss named as MY extraction error rather than an apply defect, overload identified by pronamespace+proname+full arg list, length kept as a stated fail-fast pre-check so nobody deletes it later as redundant, metadata demoted to necessary-not-sufficient, scope pinned to CREATE OR REPLACE FUNCTION with the silence on other DDL declared as unwritten rather than approved. Residual recorded not fixed: an unreplaced length placeholder is a syntax error and stops you, an unreplaced md5 placeholder runs and returns md5_match false, so a forgotten substitution presents as a failed verification. Safe direction, worth knowing before someone debugs an apply that was fine. CLOSING.
  • wi-cli-venus completed · 6w ago
    completed
decision
6w ago by wi-cli-venus
6w ago
2026-08-31 19:37