Summary
There is currently no guidance anywhere in the shipped skills on how to index an EQL v3 encrypted column. As a result, integrations that are otherwise correct — encrypted at rest, genuinely EQL-backed search, exact round-trip — ship with no index on any encrypted predicate.
I'd like to propose a new skill covering this. Suggested name: stash-indexing (see naming note below).
Evidence
Two independent integration evals against stash@1.0.0-rc.4 / EQL v3 3.0.2, on two different surfaces (Prisma Next adapter, and raw postgres-js in a Supabase Edge Function). Both produced working, verified integrations. Neither created a single index on an encrypted column, and both assessors independently flagged the same root cause.
Grepping the skills installed by stash init across those runs — stash-encryption, stash-cli, stash-prisma-next — for create index|using gin|ord_term(|bloom_filter(|eq_term(:
- Zero
CREATE INDEX examples.
- The only
ord_term( occurrences are in an ORDER BY context (stash-encryption "On the Wire: Operators and Ordering"; stash-cli "Common issues"). Nothing connects the extractor functions to index creation.
So an agent (or a developer) reading the skills end to end has no reason to know encrypted columns can be indexed, let alone how.
These all work, including without superuser
Verified against local Supabase Postgres as postgres with rolsuper = f, on a table whose columns are public.eql_v3_integer_ord and public.eql_v3_text_search. All three succeed:
-- ordering / range, OPE-backed (_ord, text_search)
CREATE INDEX ON transactions (eql_v3.ord_term(amount));
-- free-text match (trigram bloom)
CREATE INDEX ON transactions USING gin ((eql_v3_internal.bloom_filter(description::jsonb)));
-- equality
CREATE INDEX ON transactions (eql_v3.eq_term(description));
The non-superuser part matters: the surrounding docs correctly warn that the ORE operator class needs superuser and is unavailable on managed Postgres, and I suspect that warning is being over-generalised into "you can't index encrypted columns on Supabase." These three forms are all available on a managed, non-superuser role.
Proposed scope
- The three index forms above, each tied to the domain families it applies to (
*_ord / text_search → ord_term; Match/Search → bloom_filter GIN; equality-capable domains → eq_term).
- Explicitly state that all three install without superuser, and how this differs from the ORE opclass restriction — that distinction is the confusing part today.
- Which domains have no index option (storage-only), so the absence is a deliberate answer rather than a gap.
- How this interacts with the ORM integrations: Drizzle and Prisma Next emit the operators for you, but neither emits DDL for these indexes, so it's the developer's job either way.
- Ideally, a note in the rollout lifecycle about when to create them (after backfill, before switching reads).
Naming
I'd lean stash-indexing over stash-postgres / stash-postgres-indexing:
- The gap is cross-cutting, not raw-SQL-specific — it applies equally to Drizzle, Prisma Next, Supabase, and hand-written SQL.
stash-postgres would imply the no-ORM surface.
- There is a genuinely separate gap for the raw-SQL / non-ORM surface (binding forms for
postgres-js / pg, the WASM entry, Deno specifics). That deserves its own skill — I'll open a second issue for it rather than conflate the two here.
Happy to be overruled on the name if stash-postgres is preferred for discoverability.
Summary
There is currently no guidance anywhere in the shipped skills on how to index an EQL v3 encrypted column. As a result, integrations that are otherwise correct — encrypted at rest, genuinely EQL-backed search, exact round-trip — ship with no index on any encrypted predicate.
I'd like to propose a new skill covering this. Suggested name:
stash-indexing(see naming note below).Evidence
Two independent integration evals against
stash@1.0.0-rc.4/ EQL v3 3.0.2, on two different surfaces (Prisma Next adapter, and rawpostgres-jsin a Supabase Edge Function). Both produced working, verified integrations. Neither created a single index on an encrypted column, and both assessors independently flagged the same root cause.Grepping the skills installed by
stash initacross those runs —stash-encryption,stash-cli,stash-prisma-next— forcreate index|using gin|ord_term(|bloom_filter(|eq_term(:CREATE INDEXexamples.ord_term(occurrences are in anORDER BYcontext (stash-encryption"On the Wire: Operators and Ordering";stash-cli"Common issues"). Nothing connects the extractor functions to index creation.So an agent (or a developer) reading the skills end to end has no reason to know encrypted columns can be indexed, let alone how.
These all work, including without superuser
Verified against local Supabase Postgres as
postgreswithrolsuper = f, on a table whose columns arepublic.eql_v3_integer_ordandpublic.eql_v3_text_search. All three succeed:The non-superuser part matters: the surrounding docs correctly warn that the ORE operator class needs superuser and is unavailable on managed Postgres, and I suspect that warning is being over-generalised into "you can't index encrypted columns on Supabase." These three forms are all available on a managed, non-superuser role.
Proposed scope
*_ord/text_search→ord_term;Match/Search→bloom_filterGIN; equality-capable domains →eq_term).Naming
I'd lean
stash-indexingoverstash-postgres/stash-postgres-indexing:stash-postgreswould imply the no-ORM surface.postgres-js/pg, the WASM entry, Deno specifics). That deserves its own skill — I'll open a second issue for it rather than conflate the two here.Happy to be overruled on the name if
stash-postgresis preferred for discoverability.