Test the append-only guard the database actually runs - #154
Merged
davidmckayv merged 2 commits intoAug 22, 2026
Conversation
The immutability test read `0000_schema.sql` and asserted on the function defined there. 0007 replaced that function and 0012 replaced it again and added the truncate trigger, so the assertions described a definition no database runs, and would have gone on passing if the live one were edited out from under them. A mirror test pinned to one file is a test of that file. It now reads the whole migration chain, requires both triggers, and fails if a later migration drops either. Also covers the trigger's own branch for a malformed retention window. `sweepAuditTrail` returns before it opens a connection, so the existing test proves the caller's guard and never reaches the trigger, which is the branch anything not going through the sweep would meet. Both reported by @beardthelion in #138 and written in their PR #139, which arrived before the fix that merged and covered ground it did not. Catches the changelog up with tonight's fixes, including the truncate hole with the caveat about the owner role that the report was careful to state.
davidmckayv
requested review from
MikeRyanDev,
guidovizoso and
tylerslaton
as code owners
August 22, 2026 04:31
9 tasks
The mention row's reason read "you chose them yourself". True in the conversation and false on the audit page, where every row belongs to somebody else and an administrator is the one reading it. The person is already on the row as actorUserId; the reason only has to say what kind of decision it was. @zopeVaibhav had this right in #134.
davidmckayv
deleted the
fix/the-append-only-test-reads-the-whole-migration-chain
branch
August 22, 2026 04:35
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two findings from @beardthelion, from #138 and their PR #139. Both are real and neither was covered by the fix that merged as #148.
The immutability test described a definition nothing runs
audit.test.tsread0000_schema.sqland asserted on the function defined there:0007replaced that function.0012replaced it again and added the truncate trigger. So the assertions described a definition no database has run for a while, and would have gone on passing if the live one were edited out from under them — including if a later migration dropped the truncate trigger entirely.A mirror test pinned to one file is a test of that file, not of the deployment. It now reads the whole chain, requires both triggers, and fails if any migration drops either.
What the guard does is still proved against a real database in
audit-retention.integration.test.ts. This only holds that it is installed.The trigger's own malformed-window branch was never reached
That one stops in TypeScript.
sweepAuditTrailreturns{deleted: null}before it ever opens a connection, so it proves the caller's guard and says nothing about the trigger — which has a branch of its own for this that nothing exercised.That is the shape where a guard reads as covered and is not, and it matters because the trigger is the only thing standing between the table and anything that does not go through the sweep. The new test sets the value the sweep would have set and then deletes directly, for
"0","-1",""and"garbage".Changelog
Catches it up with tonight's five fixes: the truncate hole, the declined take-the-wheel, the routing trail, the partial connector grant, and answer provenance.
The truncate entry keeps the caveat the report was careful to state — the application connects as the database owner in the shipped compose file, and an owner can still disable or drop a trigger, so this closes the one-statement path rather than making the guarantee absolute.
On process: #139 was open before I built #148, and I did not check. The fix that merged is the same trigger with the same
TG_OP-first ordering, because the issue laid out both. Their PR covered ground mine did not, and this is that ground, credited.