Summary
Found by the rc.2 skilltester run (2026-07-17, GA blocker B2). Core encryptQuery will happily produce a free-text match query term for a 1–2 character needle. Because of how the match index tokenises, such a term matches essentially every row, silently turning LIKE '%ab%'-style searches into full-table matches instead of a real filter.
The Supabase v3 adapter already guards against this (short-needle rejection in its query builder), but the core encryptQuery path — which every other surface (Drizzle, raw pg, prisma-next) goes through — does not. So the protection is inconsistent: it depends on which adapter you happen to use, and the no-ORM / raw-SQL surfaces get no protection at all.
Impact
- Correctness / silent data exposure of intent. A query the developer believes is a narrow substring search returns every row. On an access-controlled surface (e.g. RLS + PostgREST), a match term that matches all rows can defeat the intended narrowing.
- Inconsistent behaviour across adapters for the same logical query.
Expected
Core encryptQuery should reject (or at minimum loudly refuse to emit) a free-text match term whose needle is shorter than the minimum the match index can meaningfully discriminate on, with an actionable error naming the minimum length. The rejection belongs in the core so every surface inherits it, and the Supabase adapter's bespoke guard can then defer to it.
Also
- The
stash-encryption skill currently overstates free-text search without noting the minimum-needle constraint — fix that claim in the same change (see AGENTS.md "check the skills").
Repro sketch
- Encrypt a free-text/match column.
encryptQuery('ab', { table, column, queryType: 'match' }) (a 2-char needle).
- Run the resulting term against a populated table → it matches all rows rather than only those containing
ab.
References
- rc.2 skilltester report:
docs/evals/2026-07-17-rc2-full-run-report.md
- Supabase adapter's existing guard is the reference behaviour to lift into core.
https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w
Summary
Found by the rc.2 skilltester run (2026-07-17, GA blocker B2). Core
encryptQuerywill happily produce a free-text match query term for a 1–2 character needle. Because of how the match index tokenises, such a term matches essentially every row, silently turningLIKE '%ab%'-style searches into full-table matches instead of a real filter.The Supabase v3 adapter already guards against this (short-needle rejection in its query builder), but the core
encryptQuerypath — which every other surface (Drizzle, raw pg, prisma-next) goes through — does not. So the protection is inconsistent: it depends on which adapter you happen to use, and the no-ORM / raw-SQL surfaces get no protection at all.Impact
Expected
Core
encryptQueryshould reject (or at minimum loudly refuse to emit) a free-text match term whose needle is shorter than the minimum the match index can meaningfully discriminate on, with an actionable error naming the minimum length. The rejection belongs in the core so every surface inherits it, and the Supabase adapter's bespoke guard can then defer to it.Also
stash-encryptionskill currently overstates free-text search without noting the minimum-needle constraint — fix that claim in the same change (see AGENTS.md "check the skills").Repro sketch
encryptQuery('ab', { table, column, queryType: 'match' })(a 2-char needle).ab.References
docs/evals/2026-07-17-rc2-full-run-report.mdhttps://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94w