From 651e999152475f63c47834680331055c24569ee2 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Tue, 1 Sep 2026 17:36:56 +0800 Subject: [PATCH 1/2] chore(issues): raise #ZBAC9D to P1 with verified retrieval-path evidence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-verified the orphaned-document republication hazard against main a633eb6e3. The row understated it. The retrieval path is closed at no layer: retrieval_owner_matches still resolves the public sentinel to `row_owner_id is null`, and public_corpus appears zero times across rag-candidate-sources, corpus-grounding, deep-memory, document-enrichment, owner-scope, clinical-search and query-privacy. The helper written to close the hazard, src/lib/documents/is-public-document.ts, has no production caller — it is exercised only by its own test, which pins the exact orphaned-row case. Only the REST document read is genuinely closed, via withOwnerReadScope. Append-only inbox request; the canonical ledger is untouched. Co-Authored-By: Claude Opus 5 --- .../224cda1c-ae72-4921-b8aa-e6b3e315796a.json | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json diff --git a/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json b/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json new file mode 100644 index 000000000..4a2427f23 --- /dev/null +++ b/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json @@ -0,0 +1,13 @@ +{ + "version": 2, + "id": "224cda1c-ae72-4921-b8aa-e6b3e315796a", + "createdOn": "2026-09-01", + "action": "update", + "payload": { + "id": "#ZBAC9D", + "pri": "P1", + "detail": "documents.owner_id is ON DELETE SET NULL (supabase/schema.sql:63) while a null owner independently means 'public corpus', so deleting an auth user silently republishes that user's private documents. RE-VERIFIED against main a633eb6e3 on 2026-09-01 and the picture is WORSE than this row previously recorded, hence P2 -> P1. (1) The retrieval path is NOT closed at any layer. public.retrieval_owner_matches still resolves the public sentinel to 'row_owner_id is null' with no public_corpus condition, and grep for 'public_corpus' returns ZERO occurrences across the entire retrieval chain: rag/rag-candidate-sources.ts, corpus-grounding.ts, deep-memory.ts, document-enrichment.ts, owner-scope.ts, clinical-search.ts and query-privacy.ts. An orphaned document is therefore retrievable as public corpus and citable in an answer to an anonymous query. (2) The helper written to close exactly this hazard is DEAD CODE. src/lib/documents/is-public-document.ts requires owner_id === null AND metadata.public_corpus === true, and tests/documents-is-public.test.ts:22 pins the precise case ('Orphaned after user delete' -> false), but grep across src/ and worker/ finds NO production caller outside its own module and the barrel re-export. Same shape as #A3AHCX. (3) The only genuinely closed path is the REST document read: withOwnerReadScope in src/lib/public-api-access.ts:116 applies .is('owner_id', null).eq('metadata->>public_corpus','true'). The earlier wording 'the application read paths were closed' is true only of that one path and should not be read as general closure. NEXT, in order: (a) one read-only live count of documents where owner_id is null and metadata->>'public_corpus' is distinct from 'true' — this decides whether the hole is currently leaking or merely armed, and needs owner approval as a provider-backed read; (b) close the retrieval path, which is a genuine retrieval behaviour change on a protected RAG surface and so needs the RAG flag plus a live eval-canary pair; (c) in an approved production window, change documents.owner_id to ON DELETE RESTRICT or add an explicit visibility column and align the RPC predicate. Note the offline proof proposed in the previous version of this row (assert no table whose null owner means public declares ON DELETE SET NULL) cannot be added green today — it would fail on documents.owner_id, so it is the guard that accompanies (c), not a step that precedes it.", + "source": "repo-wide audit at 3ed1932 (six domain reviewers); re-verified and expanded against main a633eb6e3 by the database coordination chat 2026-09-01", + "baseRowFingerprint": "13eb57d22f4630a32ff989e07c37a577b5fd8eb3f7388c641c31998143ecdfe0" + } +} From 9ffdd1a86ed5c29d6e2de7ca77883c0f1cba1101 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Tue, 1 Sep 2026 18:31:43 +0800 Subject: [PATCH 2/2] fix(issues): correct #ZBAC9D deletion-path evidence per Codex --- .../224cda1c-ae72-4921-b8aa-e6b3e315796a.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json b/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json index 4a2427f23..24db15580 100644 --- a/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json +++ b/docs/outstanding-issues-inbox/224cda1c-ae72-4921-b8aa-e6b3e315796a.json @@ -6,8 +6,8 @@ "payload": { "id": "#ZBAC9D", "pri": "P1", - "detail": "documents.owner_id is ON DELETE SET NULL (supabase/schema.sql:63) while a null owner independently means 'public corpus', so deleting an auth user silently republishes that user's private documents. RE-VERIFIED against main a633eb6e3 on 2026-09-01 and the picture is WORSE than this row previously recorded, hence P2 -> P1. (1) The retrieval path is NOT closed at any layer. public.retrieval_owner_matches still resolves the public sentinel to 'row_owner_id is null' with no public_corpus condition, and grep for 'public_corpus' returns ZERO occurrences across the entire retrieval chain: rag/rag-candidate-sources.ts, corpus-grounding.ts, deep-memory.ts, document-enrichment.ts, owner-scope.ts, clinical-search.ts and query-privacy.ts. An orphaned document is therefore retrievable as public corpus and citable in an answer to an anonymous query. (2) The helper written to close exactly this hazard is DEAD CODE. src/lib/documents/is-public-document.ts requires owner_id === null AND metadata.public_corpus === true, and tests/documents-is-public.test.ts:22 pins the precise case ('Orphaned after user delete' -> false), but grep across src/ and worker/ finds NO production caller outside its own module and the barrel re-export. Same shape as #A3AHCX. (3) The only genuinely closed path is the REST document read: withOwnerReadScope in src/lib/public-api-access.ts:116 applies .is('owner_id', null).eq('metadata->>public_corpus','true'). The earlier wording 'the application read paths were closed' is true only of that one path and should not be read as general closure. NEXT, in order: (a) one read-only live count of documents where owner_id is null and metadata->>'public_corpus' is distinct from 'true' — this decides whether the hole is currently leaking or merely armed, and needs owner approval as a provider-backed read; (b) close the retrieval path, which is a genuine retrieval behaviour change on a protected RAG surface and so needs the RAG flag plus a live eval-canary pair; (c) in an approved production window, change documents.owner_id to ON DELETE RESTRICT or add an explicit visibility column and align the RPC predicate. Note the offline proof proposed in the previous version of this row (assert no table whose null owner means public declares ON DELETE SET NULL) cannot be added green today — it would fail on documents.owner_id, so it is the guard that accompanies (c), not a step that precedes it.", - "source": "repo-wide audit at 3ed1932 (six domain reviewers); re-verified and expanded against main a633eb6e3 by the database coordination chat 2026-09-01", + "detail": "documents.owner_id is ON DELETE SET NULL (supabase/schema.sql) while a null owner independently means 'public corpus' in retrieval. CORRECTION (Codex on PR #2494): deleting an auth user does NOT silently republish private documents — documents_require_publication_approval (BEFORE INSERT OR UPDATE) runs guard_document_publication_transition, which rejects every non-null-to-null owner transition without matching publication evidence, so the user-delete transaction fails instead of orphaning/republishing. Distinguish blocked user deletion from any pre-existing orphan rows. RE-VERIFIED against main and the P2 -> P1 escalation still holds on the retrieval hazard, not on a live delete-to-publish path. (1) The retrieval path is NOT closed at any layer. public.retrieval_owner_matches still resolves the public sentinel to 'row_owner_id is null' with no public_corpus condition, and grep for 'public_corpus' returns ZERO occurrences across the entire retrieval chain: rag/rag-candidate-sources.ts, corpus-grounding.ts, deep-memory.ts, document-enrichment.ts, owner-scope.ts, clinical-search.ts and query-privacy.ts. Any ownerless row (pre-existing orphan or armed hole) is therefore retrievable as public corpus and citable in an answer to an anonymous query. (2) The helper written to close exactly this hazard is DEAD CODE. src/lib/documents/is-public-document.ts requires owner_id === null AND metadata.public_corpus === true, and tests/documents-is-public.test.ts:22 pins the precise case ('Orphaned after user delete' -> false), but grep across src/ and worker/ finds NO production caller outside its own module and the barrel re-export. Same shape as #A3AHCX. (3) The only genuinely closed application read path is the REST document read: withOwnerReadScope in src/lib/public-api-access.ts applies .is('owner_id', null).eq('metadata->>public_corpus','true'). NEXT, in order: (a) one read-only live count of documents where owner_id is null and metadata->>'public_corpus' is distinct from 'true' — this decides whether the hole is currently leaking or merely armed, and needs owner approval as a provider-backed read; (b) close the retrieval path, which is a genuine retrieval behaviour change on a protected RAG surface and so needs the RAG flag plus a live eval-canary pair; (c) add a database proof that deleting an owner of an unapproved private document fails and creates no ownerless indexed row, then in an approved production window change documents.owner_id to ON DELETE RESTRICT (or an explicit visibility column) and align the RPC predicate. Note the offline proof that no table whose null owner means public declares ON DELETE SET NULL cannot be added green today — it would fail on documents.owner_id, so it is the guard that accompanies (c), not a step that precedes it.", + "source": "repo-wide audit at 3ed1932 (six domain reviewers); re-verified and expanded against main a633eb6e3 by the database coordination chat 2026-09-01; deletion-path correction per Codex review on PR #2494", "baseRowFingerprint": "13eb57d22f4630a32ff989e07c37a577b5fd8eb3f7388c641c31998143ecdfe0" } }