Skip to content

docs(v2): consume the EQL manifest — generated function catalog + drift-lint#46

Open
coderdan wants to merge 6 commits into
v2from
docs/v2-eql-manifest-consumer
Open

docs(v2): consume the EQL manifest — generated function catalog + drift-lint#46
coderdan wants to merge 6 commits into
v2from
docs/v2-eql-manifest-consumer

Conversation

@coderdan

@coderdan coderdan commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

The docs-side companion to cipherstash/encrypt-query-language#364 (which emits eql-manifest.json from EQL's Doxygen'd SQL + domain definitions). Closes the EQL generation gap: generate the mechanical surface, keep the pedagogy hand-written, and bind the two with a lint.

What it does

scripts/generate-eql-api-docs.ts (generate-docs:eql-api, wired into prebuild):

  1. Generates content/docs/reference/eql/functions.mdx — version-stamped, drift-proof, added to the EQL nav under "Reference". It leads with the encrypted-domain variant matrix (domain × type × variant → capabilities → index terms) from the manifest's domains array — the core of the v3 surface — then the function catalog:

    Domain Type Variant Capabilities Index terms
    eql_v3.integer_ord integer _ord order ob
    eql_v3.text_search text _search equality, order, match hm ob bf
  2. Drift-lints the hand-written pages — every eql_v3.<symbol> (function or domain) they reference must exist in the manifest for the shipped EQL version.

The lint already found a real bug 🐛

Running it against the pages surfaced a concrete mismatch the manifest exists to catch:

The v3 pages reference eql_v3.int4_* / int8_* / float4_* / float8_* domains (in numbers.mdx, core-concepts.mdx, filtering.mdx, booleans.mdx), but the shipped SQL defines eql_v3.integer_* / bigint_* / real_* / double_*.

So casts like $1::eql_v3.int8_ord in the docs would fail against the real schema (the domain is eql_v3.bigint_ord). Docs-vs-codegen naming needs reconciling — exactly the drift this is designed to catch.

Manifest source: sample → real

Reads an illustrative sample fixture today so the format + lint are reviewable now. Once #364 releases, generate-eql-docs.ts (which already downloads the eql-docs-<tag> asset) extracts the real json/eql-manifest.json; point MANIFEST_PATH at it and set STRICT = true to make the lint a failing gate. Renderer and lint stay identical.

Depends on #364. Mirrors the CLI generator pattern (#45).

https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA

@vercel

vercel Bot commented Jul 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
public-docs Ready Ready Preview, Comment Jul 6, 2026 1:54pm

Request Review

coderdan added a commit that referenced this pull request Jul 6, 2026
Refresh: rebased on the latest #46 (placeholder + 'three schemas' + index
uninstall fixes) and swapped in the corrected manifest (#372 mis-parse fix)
— public 986->696, no bogus eql_v3_internal function. Not for merge.

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
coderdan added 6 commits July 6, 2026 23:52
…-lint

Consumes the eql-manifest.json the EQL repo emits from its Doxygen'd SQL
(cipherstash/encrypt-query-language#364) to:

- generate content/docs/reference/eql/functions.mdx — a version-stamped,
  drift-proof catalog of the eql_v3 function surface that the hand-written
  pedagogical pages link to (added to the EQL nav under "Reference");
- drift-lint the hand-written pages: every `eql_v3.<fn>(...)` they reference
  should exist in the manifest for the shipped EQL version. This is what
  would have caught the fabricated function names / stale payload that slipped
  into the v2 docs.

Wired into prebuild. Reads an illustrative sample fixture today (so the format
and lint are reviewable now); swaps to the real json/eql-manifest.json from the
eql-docs release asset once #364 ships — generate-eql-docs.ts already downloads
that tarball. The lint is report-only against the sample and becomes a failing
gate once wired to the real manifest (STRICT).

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
…t to domains

The generated functions.mdx now leads with the encrypted-domain variant matrix
(domain × type × variant → capabilities → index terms), consumed from the
manifest's new `domains` array (cipherstash/encrypt-query-language#364). The
drift-lint now covers domain-type references too, not just function calls.

Running it surfaced a real mismatch worth fixing: the hand-written v3 pages
reference eql_v3.int4_*/int8_*/float4_*/float8_* domains, but the shipped SQL
defines eql_v3.integer_*/bigint_*/real_*/double_* — so casts like
$1::eql_v3.int8_ord would fail. Docs-vs-codegen naming needs reconciling; this
is exactly the drift the lint exists to catch.

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
Matches the manifest change in encrypt-query-language#364: domains now come from
the Rust catalog (`eql-codegen dump-catalog`), carrying authoritative type names
and the exact `supportedOperators` per domain (replacing the CHECK-key-derived
`terms`/`termFunctions`). The generated variant matrix renders an Operators
column; the sample fixture is updated to match. Note `_ord` correctly shows
equality + order now (ORE collapses to equality).

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
Matches encrypt-query-language#368 (stacked on #364): the manifest now carries
the 3 jsonb (SteVec) domains and per-domain `termFunctions`. The variant matrix
renders the jsonb domains (json capability), and the drift-lint adds each
domain's extractor functions (eq_term / ord_term / match_term / ord_ope_term) to
its known set — resolving those false-positives (61 → 57 unknowns on the sample).

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
Wires the v2 EQL reference to the corrected manifest (public. domains,
eql_v3./eql_v3_internal. functions — cipherstash/encrypt-query-language#369)
and turns the drift-lint into a real gate.

- generate-eql-api-docs.ts: schema-aware drift-lint — matches
  public.<domain>, eql_v3.<fn>, eql_v3_internal.<fn> by schema AND name, so
  right-name/wrong-schema refs are caught, not just fabricated ones. Group
  public overloads by name (the raw 1680-function surface -> 39 functions);
  omit internal functions from the page (kept in the lint's known set).
  Manifest source: EQL_MANIFEST_PATH -> release cache -> sample, auto-strict
  against any real manifest.
- generate-eql-docs.ts: extract json/eql-manifest.json from the release
  tarball to a gitignored cache the reference generator reads (best-effort;
  falls back to the sample until a release ships the manifest).
- Swept content/docs/reference/eql/*.mdx (165 refs): domains -> public.,
  internal ctors -> eql_v3_internal., PG aliases -> canonical catalog names
  (int4->integer, float8->double, bool->boolean, ste_vec_*->jsonb_*).
- Updated the illustrative sample fixture to the corrected schema.

Drift-lint verified green against a locally-generated corrected manifest;
report-only against the committed sample until a release ships the manifest.

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
Follow-ups from reviewing the rendered preview:
- Variant tables used the eql_v3.<T> placeholder (booleans, core-concepts,
  dates-and-times, grouping-and-aggregates, indexes, numbers) — the concrete-
  token sweep missed it. Now public.<T>.
- core-concepts: new 'The three schemas' section — public (encrypted domain
  types, kept in an unversioned schema so EQL upgrades don't rewrite your
  column types), eql_v3 (user-callable functions/operators), eql_v3_internal
  (implementation, don't call). Fixed prose that placed the domains and the
  SEM index-term types in eql_v3 (they're public / eql_v3_internal).
- index: domains are public not eql_v3; corrected the uninstall Callout —
  DROP SCHEMA eql_v3, eql_v3_internal CASCADE removes operators/functions but
  leaves the public.* types + columns (data survives), where the old text
  claimed dropping eql_v3 drops the columns.
- Grammar: 'an public.*' -> 'a public.*' left over from the schema sweep.

Claude-Session: https://claude.ai/code/session_01CqDNqLSEEkCi7xAJFq7HJA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant