Docs V2: EQL v3 reference section, Tailwind-shaped (CIP-3326)#38
Merged
Conversation
Seven pages replacing the v2-era EQL reference, written against the eql_v3 branch of cipherstash/encrypt-query-language (3.0.0): - index: what EQL is, the v3 domain-variant model, install (single SQL script, idempotent), dbdev, Docker, migration/runtime permission split, managed-Postgres rationale - types: 10 scalar families × variants matrix; bool storage-only; _ord/_ord_ore twins; index terms per variant - operators: per-variant support matrix, typed-operand rule, no-LIKE, fail-loud blockers, query shapes, function-form equivalents - indexes: functional indexes on term extractors, engagement requirements, sort-key form for index-streamed ORDER BY, EXPLAIN checklist, large-table build guidance - json: ste_vec model, per-node-type terms (hm XOR oc), containment + GIN, field access, path queries, blocked native jsonb operators - functions: comparisons, extractors, min/max only (no SUM/AVG), version() - payload-format: v/i/c envelope (wire version still v:2), hm/ob/bf term keys, sv document shape, annotated examples (absorbs the legacy CipherCell page) Cross-page consistency verified against the shipped SQL: equality on _ord variants compares ORE terms (no hm in _ord payloads), and bare ORDER BY is correct but extractor-form sort keys stream from the index. Claude-Session: https://claude.ai/code/session_01ACPpFPHvKtrV48nbEYuv7P
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
EQL is an abstraction over SQL the way Tailwind is over CSS — the docs now follow the same shape: Install → Core concepts → type categories → Indexes → query patterns, increasing in complexity. Each type-category page is the complete reference for its types (variants, payload shape, operators/functions, example queries on one page). - index: trimmed to the Install page - core-concepts (new): the canonical home for shared mechanics — variant model, payload anatomy (v/i/c envelope + hm/ob/bf terms, absorbs payload-format/CipherCell), typed-operand rule, fail-loud blockers, ORE-equality on _ord, term-leakage pointer - numbers-and-dates, text, booleans (new) + json (reworked): category pages; text owns the no-LIKE treatment; json absorbs the sv payload shape; booleans framed as "every type has a storage-only variant — for bool it's the only one" - filtering, sorting, grouping-and-aggregates, joins (new): cross-type query patterns; joins headlines the same-keyset constraint - deleted: types.mdx, operators.mdx, functions.mdx, payload-format.mdx (content redistributed; URLs never shipped publicly, no redirect debt) - Anti-drift rule recorded in IA.md: mechanics live ONLY in core-concepts; category/query pages link, never restate - meta.json: flat URLs with ---Types---/---Indexes---/---Queries--- sidebar separators; legacy redirect map retargeted (queries → filtering, cipher-cell → core-concepts) Claude-Session: https://claude.ai/code/session_01ACPpFPHvKtrV48nbEYuv7P
…load v:3 Review feedback on the EQL section: - Variant tables: generic form first, then full enumeration of every concrete domain name (Tailwind-style); capability column made concise; "index term carried" column dropped — term internals live in core-concepts' payload anatomy - SEM specifiers documented as a concept in core-concepts: a trailing mechanism suffix (_ord_ore) pins WHICH searchable-encryption mechanism implements a capability; _ord tracks the default (currently ORE). Replaces the "twins" framing. Each orderable type page lists its specifiers under an "SEM specifiers" heading, noting the OPE specifier arriving for all orderable types (incl. text) in the v3 release - Payload `v` field documented as the EQL version (3) per team decision 2026-07-02; all payload examples updated from v:2 Claude-Session: https://claude.ai/code/session_01ACPpFPHvKtrV48nbEYuv7P
…perators and Functions Review feedback: - Dates & times split out of Numbers — same traits, distinct semantics; each page's examples now match its domain (payroll vs audit-event time windows / retention cutoffs / newest-first) - CREATE TABLE examples get an explicit "Example" sub-heading + lead-in - Operators and Functions are separate sections on every type page — operators as the per-variant support matrix, functions as the form-equivalents table (+ MIN/MAX, which only exist as functions) - IA.md: split reflected; query-performance follow-up added (CIP-3351 — the v3 branch already folded the v2 perf guide into database-indexes.md, which our indexes page absorbed) Claude-Session: https://claude.ai/code/session_01ACPpFPHvKtrV48nbEYuv7P
There was a problem hiding this comment.
Pull request overview
Adds a new Docs V2 EQL v3 reference section under /reference/eql, restructuring the content into a “Tailwind-shaped” learning arc (install → core concepts → type categories → indexes → query patterns) and retargeting relevant legacy redirects to the new canonical pages.
Changes:
- Replaces the EQL reference stub with a full set of new v3 reference pages (core concepts, types, indexes, and query patterns).
- Defines EQL sidebar ordering/grouping via
content/docs/reference/eql/meta.json. - Updates legacy→v2 redirect destinations to point at the new EQL pages, and updates IA tracking/checklists accordingly.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| v2-redirects.mjs | Retargets legacy EQL-related redirects to new v2 EQL pages. |
| IA.md | Updates the IA checklist to reflect the new EQL v3 page set and anti-drift rule. |
| content/docs/reference/eql/index.mdx | Replaces the EQL section stub with an install/overview landing page. |
| content/docs/reference/eql/core-concepts.mdx | Introduces the canonical mechanics page (variants, payload envelope, typed operands, fail-loud blockers). |
| content/docs/reference/eql/numbers.mdx | Adds the numeric types reference (variants, payload, operators, functions, examples). |
| content/docs/reference/eql/dates-and-times.mdx | Adds the date/timestamp reference with temporal query examples. |
| content/docs/reference/eql/text.mdx | Adds the text types reference including no-LIKE guidance and token containment. |
| content/docs/reference/eql/json.mdx | Adds encrypted JSON (ste_vec) reference including containment/path-query mechanics. |
| content/docs/reference/eql/booleans.mdx | Documents booleans as storage-only by design. |
| content/docs/reference/eql/indexes.mdx | Adds index recipes and engagement requirements for encrypted query patterns. |
| content/docs/reference/eql/filtering.mdx | Adds WHERE-clause patterns across equality/range/text containment/JSON predicates. |
| content/docs/reference/eql/sorting.mdx | Adds ORDER BY guidance including extractor-form sort keys and pagination patterns. |
| content/docs/reference/eql/grouping-and-aggregates.mdx | Adds GROUP BY/DISTINCT/COUNT and min/max guidance, with no SUM/AVG rationale. |
| content/docs/reference/eql/joins.mdx | Adds equijoin guidance including the same-keyset constraint and diagnosis steps. |
| content/docs/reference/eql/meta.json | Defines page ordering and sidebar group separators for the EQL section. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| ## What the terms reveal | ||
|
|
||
| Every index term a value carries is extra material stored in the database, and each term class reveals defined structure to an observer who can read the stored payloads: equality terms reveal *value repetition* (which rows share a value), ORE terms reveal *ordering* (which of two values is larger), and bloom terms reveal *probabilistic token overlap*. None of them reveal the plaintext — but you should only carry the terms you actually query on. The full analysis of what each term does and doesn't leak is in [Searchable encryption](/concepts/searchable-encryption). |
| | `float8` | `eql_v3.float8` · `eql_v3.float8_eq` · `eql_v3.float8_ord` · `eql_v3.float8_ord_ore` | | ||
| | `numeric` | `eql_v3.numeric` · `eql_v3.numeric_eq` · `eql_v3.numeric_ord` · `eql_v3.numeric_ord_ore` | | ||
|
|
||
| Declare only the capability you query on — each capability stores extra searchable material with defined leakage (see [Searchable encryption](/concepts/searchable-encryption)), and the variant model itself is covered in [Core concepts](/reference/eql/core-concepts). |
| | `date` | `eql_v3.date` · `eql_v3.date_eq` · `eql_v3.date_ord` · `eql_v3.date_ord_ore` | | ||
| | `timestamp` | `eql_v3.timestamp` · `eql_v3.timestamp_eq` · `eql_v3.timestamp_ord` · `eql_v3.timestamp_ord_ore` | | ||
|
|
||
| Time columns are nearly always ranged and sorted, so `_ord` is the usual choice. Declare only the capability you query on — each capability stores extra searchable material with defined leakage (see [Searchable encryption](/concepts/searchable-encryption)), and the variant model itself is covered in [Core concepts](/reference/eql/core-concepts). |
| | `eql_v3.text_match` | Free-text token containment: `@>` / `<@`. | | ||
| | `eql_v3.text_search` | Equality + ordering + token containment. | | ||
|
|
||
| Declare only the capabilities you query on — each capability stores extra searchable material with defined leakage (see [Searchable encryption](/concepts/searchable-encryption)). |
|
|
||
| ## Why there are no query variants | ||
|
|
||
| A two-value column has too little cardinality for any searchable index to be safe. An equality term over `true` / `false` would partition the table into two visible buckets — leaking the value distribution (and, with any outside knowledge, the values themselves) outright. Rather than ship an index term that can't keep its promise, EQL omits the query variants entirely. See [Searchable encryption](/concepts/searchable-encryption) for the general analysis of what index terms reveal. |
| | `ORDER BY` | ❌ | ❌ | ✅ | | ||
| | `IS NULL` / `IS NOT NULL` | ✅ | ✅ | ✅ | | ||
|
|
||
| Blocked cells raise an `operator … is not supported` exception — they never silently return wrong rows. Operands must be typed (`$1::eql_v3.int8_ord`), or PostgreSQL resolves the native `jsonb` operator instead of the encrypted one. Both rules are covered in [Core concepts](/reference/eql/core-concepts). |
| | `ORDER BY` | ❌ | ❌ | ✅ | | ||
| | `IS NULL` / `IS NOT NULL` | ✅ | ✅ | ✅ | | ||
|
|
||
| Blocked cells raise an `operator … is not supported` exception — they never silently return wrong rows. Operands must be typed (`$1::eql_v3.timestamp_ord`), or PostgreSQL resolves the native `jsonb` operator instead of the encrypted one. Both rules are covered in [Core concepts](/reference/eql/core-concepts). |
| | `ORDER BY` | ❌ | ❌ | ✅ | ❌ | ✅ | | ||
| | `IS NULL` / `IS NOT NULL` | ✅ | ✅ | ✅ | ✅ | ✅ | | ||
|
|
||
| Blocked cells raise an `operator … is not supported` exception — they never silently return wrong rows. Operands must be typed (`$1::eql_v3.text_eq`), or PostgreSQL resolves the native `jsonb` operator instead of the encrypted one. Both rules are covered in [Core concepts](/reference/eql/core-concepts). |
- indexes.mdx: cast query-shape example params to their EQL domain types, consistent with the typed-operand rule - numbers/dates-and-times/text: the fail-loud note now scopes to operators — ORDER BY on a variant without an ordering term doesn't raise, it silently returns a meaningless order (links Sorting)
# Conflicts: # v2-redirects.mjs
Contributor
Author
|
Copilot's comments addressed:
|
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.
Stacked on #37 (base:
v2). Implements CIP-3326: the EQL reference rewritten against theeql_v3branch, structured Tailwind-style — EQL is an abstraction over SQL as Tailwind is over CSS, and the docs follow the same arc: Install → Core concepts → type categories → Indexes → common queries, increasing in complexity.Structure (11 pages, flat URLs, sidebar-grouped)
/docs/reference/eql…/core-concepts_ord, term leakage…/numbersobpayload, operators + functions, range/min-max examples; owns no-SUM/AVG…/dates-and-times…/text@>ngram-bloom containment); hm+ob+bf payload…/json…/booleans…/indexes…/filtering…/sorting…/grouping-and-aggregates…/joinsAnti-drift rule (recorded in IA.md): shared mechanics live only in core-concepts; category and query pages link, never restate. Drift-management strategy for this section (test SQL blocks against the postgres-eql Docker image per
verifiedAgainst; capability matrix as generated data) is on CIP-3337.Accuracy notes (verified against shipped SQL, not just repo docs)
_ordvariants compares ORE terms —_ordpayloads carryobonly, nohmORDER BY colis correct but adds a Sort node;ORDER BY eql_v3.ord_term(col)streams from the btreehmXORoc(post-consolidation), not the staleocf/ocvsplit in sql-support.mdRelease-gated claims (verify at EQL 3.0.0 release)
v: 3— documented as the EQL version per team decision (2026-07-02); theeql_v3branch CHECKs still assertv = '2', so the upstream change must land before release:17-3.0.0(registry has17-3.0.0-alpha.1; final tag pending)eql_v3.version()output shown as'3.0.0'ocf/ocvtable; CHANGELOG 3.0.0 under[Unreleased]Smoke-tested: all 11 pages +
.mdxmirrors 200; typecheck + redirect gate pass; legacy redirects retargeted (encryption/queries→ filtering,cipher-cell→ core-concepts).https://claude.ai/code/session_01ACPpFPHvKtrV48nbEYuv7P