Formal JSON Schema for EQL v2.2 baseline and v2.3 target payload format#208
Conversation
Captures the current on-the-wire payload as the baseline for v2.3 schema work. Two mutually exclusive top-level forms (`EncryptedPayload` for scalars, `SteVecPayload` for jsonb / containment), discriminated by `k`. Index-term fields and STE-vector element shape are factored into shared $defs.
Captures the target shape for v2.3 alongside the v2.2 baseline. Three breaking changes from v2.2: `b3` is removed (root and `sv` element); `sv` elements now carry `hm`; `opf` and `opv` collapse into a single `op` field; OPE (`op`) and ORE (`ob`/`ocf`/`ocv`) are mutually exclusive within a payload or element, encoded as a shared `OreOpeExclusion` $def.
Adds `tests/sqlx/tests/payload_schema_tests.rs` (20 tests, no database required) that load both schema files and assert against a battery of hand-crafted positive and negative payloads. Coverage: - v2.2 baseline: minimal / fully-populated EncryptedPayload, SteVecPayload with mixed-index elements, root-only fields rejected on `sv` elements, EncryptedPayload <-> SteVecPayload mutual exclusion, additionalProperties. - v2.3 target: `b3` rejected everywhere, legacy `opf`/`opv` rejected, OPE (`op`) and ORE (`ob`/`ocf`/`ocv`) mutually exclusive at both root and element level, `hm` now permitted on `sv` elements, required-field enforcement. Tests live in the existing sqlx test crate as a database-free integration target; jsonschema 0.17 added as a non-dev dependency to keep the dep tree flat.
No-op wrapper around `cargo test --test payload_schema_tests` in the sqlx test crate. Database-free, runs in <1s. Useful as a fast pre-flight when editing either schema file.
Adds a new `schema` job to `test-eql.yml` that runs `mise run test:schema` on a vanilla ubuntu runner (no Postgres, no matrix). The `test` matrix job now `needs: schema`, so a broken JSON Schema fails the build in seconds instead of after the 4x Postgres matrix has spun up. `splinter` is left independent — schema correctness has no bearing on Supabase compatibility checks.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds formal JSON Schema files for EQL payloads (v2.2 and v2.3), a Rust test suite that validates sample payloads against both schemas, a ChangesEQL Payload Schema Validation
Sequence DiagramsequenceDiagram
participant CI as GitHub Actions
participant SchemaJob as schema job
participant Mise as mise
participant CargoTest as cargo test
participant Validator as jsonschema validator
participant Schema22 as v2.2 Schema
participant Schema23 as v2.3 Schema
CI->>SchemaJob: trigger schema job
SchemaJob->>Mise: mise run test:schema
Mise->>CargoTest: cargo test --test payload_schema_tests
CargoTest->>Validator: load and compile schemas
Validator->>Schema22: compile v2.2 schema
Validator->>Schema23: compile v2.3 schema
Validator->>Validator: validate sample payloads
Validator-->>CargoTest: assertion results
CargoTest-->>Mise: test exit code
Mise-->>SchemaJob: task completion
SchemaJob-->>CI: schema job result
CI->>CI: test job runs only if schema job passes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/sqlx/tests/payload_schema_tests.rs (1)
28-34: 💤 Low valueDraft 7 fallback is documented but consider future compatibility.
The comment explains that the jsonschema crate falls back to Draft 7 despite the schema declaring draft 2020-12, and notes that the used constructs are compatible. This is acceptable for the current implementation, but be aware that future schema enhancements using 2020-12-specific features may require a crate upgrade or workaround.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/sqlx/tests/payload_schema_tests.rs` around lines 28 - 34, The comment in compile() notes jsonschema::JSONSchema falls back to Draft 7 for schemas declaring draft 2020-12; update the compile function to explicitly handle future-compatibility by detecting a 2020-12 $schema and emitting a clear warning or TODO that the crate may need upgrading or a workaround if 2020-12-specific features are later used. In short: inside compile (where JSONSchema::compile is called), inspect schema.get("$schema") for "2020-12" and log a warning message (or add a TODO comment) indicating the fallback to Draft 7 and recommending upgrading jsonschema or adding a compatibility path if new draft features are required.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Line 27: Update the CHANGELOG.md paragraph about the Formal JSON Schema for
the EQL payload format to include the PR link in parentheses at the end of the
paragraph; append the suggested PR link text
`([`#208`](https://github.com/cipherstash/encrypt-query-language/pull/208))` to
the existing sentence so the entry follows the repository's CHANGELOG guideline.
In `@tests/sqlx/Cargo.toml`:
- Line 13: Update the jsonschema crate dependency in Cargo.toml by changing the
version specifier for "jsonschema" (currently jsonschema = { version = "0.17",
default-features = false }) to a more recent stable release (e.g., "0.46.4" or a
current patch), keeping or adjusting default-features as needed; run cargo
update and cargo test to ensure compatibility and fix any API changes in code
that references the jsonschema types/functions if compilation fails.
---
Nitpick comments:
In `@tests/sqlx/tests/payload_schema_tests.rs`:
- Around line 28-34: The comment in compile() notes jsonschema::JSONSchema falls
back to Draft 7 for schemas declaring draft 2020-12; update the compile function
to explicitly handle future-compatibility by detecting a 2020-12 $schema and
emitting a clear warning or TODO that the crate may need upgrading or a
workaround if 2020-12-specific features are later used. In short: inside compile
(where JSONSchema::compile is called), inspect schema.get("$schema") for
"2020-12" and log a warning message (or add a TODO comment) indicating the
fallback to Draft 7 and recommending upgrading jsonschema or adding a
compatibility path if new draft features are required.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: be5d45f8-da6e-4f98-8d39-aa55c0ddae22
⛔ Files ignored due to path filters (1)
tests/sqlx/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (7)
.github/workflows/test-eql.ymlCHANGELOG.mddocs/reference/schema/eql-payload-v2.2.schema.jsondocs/reference/schema/eql-payload-v2.3.schema.jsonmise.tomltests/sqlx/Cargo.tomltests/sqlx/tests/payload_schema_tests.rs
freshtonic
left a comment
There was a problem hiding this comment.
Nice - it's good to have proper schemas to compare.
I left a comment about upgrading the jsonschema version.
Bumps the jsonschema crate from 0.17 to 0.46.4 (current stable). The API moved from `JSONSchema::compile` to `validator_for` / `Validator` and `instance_path` is now a method rather than a field — both updated. Side benefit: the new crate has native Draft 2020-12 support, so the schemas are now validated under their declared draft instead of the Draft 7 fallback. Also runs `cargo fmt` to fix the rustfmt failure on `payload_schema_tests.rs` that broke the `test:lint` step on all four Postgres matrix jobs. Appends the PR link to the CHANGELOG entry per repo convention.
Note
ORE fields have not been consolidated in the 2.3 schema version (upcoming release) but may be before release finalisation
Summary
docs/reference/schema/describing the on-the-wire EQL payload format:eql-payload-v2.2.schema.json(current baseline) andeql-payload-v2.3.schema.json(target for the in-flight v2.3 release).tests/sqlx/tests/payload_schema_tests.rsthat validate hand-crafted positive/negative samples against both schemas. Database-free.schemaCI job that gates the 4× Postgres matrix.What the schemas capture
Two mutually exclusive top-level forms, discriminated by
k:EncryptedPayload— scalar ciphertext form. Requiredv,c,i.{t,c}; any subset of the index-term fields (hm,bf,ob,ocf,ocv, …) depending on configured indexes. Must not carrysv.SteVecPayload— jsonb / containment form. Requiredv,k=\"sv\",i,sv. No top-levelcor scalar index terms — those live on individualsvelements.A shared
IndexTerms$defsblock describes each index-term field in exactly one place; root andsv-element shapes$refinto it.v2.2 → v2.3 delta (encoded in the schema and in the changelog)
b3(Blake3) term is removed. STE vector element equality now useshmdirectly (which is now permitted at thesv-element level — it was previously root-only).opf(fixed-width / numeric OPE) andopv(variable-width / text OPE) collapse into a singleopfield. Width information that was previously implied by the field name is now carried on the value.op) and ORE (ob,ocf,ocv) are mutually exclusive within a payload orsvelement. Encoded as a sharedOreOpeExclusion\$defreferenced from both shapes.Tests
mise run test:schema(orcargo test --test payload_schema_testsfromtests/sqlx/) runs the 20 tests in ~0.02s, no database required. Coverage:EncryptedPayload⊥svandSteVecPayload⊥c;hm/i/v/ nestedsvrejected on elements;additionalProperties: falseenforced.hmaccepted on elements;b3rejected at root and in elements; legacyopf/opvrejected at root and in elements;op×{ob, ocf, ocv}mutual exclusion at both levels; required-field enforcement across both variants.Locked to
jsonschema = \"0.17\"for API stability. The crate falls back to Draft 7 because it doesn't recognise the2020-12\$schemaURL — every construct we use (\$defs,\$ref,oneOf,allOf,not,const,pattern, …) is valid in Draft 7, so semantics are unaffected, but we're not strictly enforcing 2020-12 features. Worth a note if we later reach for 2020-12-only constructs.CI
New
schemajob on plainubuntu-latest(no Postgres, no SQL build). Thetestmatrix job nowneeds: schema, so a broken JSON Schema fails the build in seconds instead of after spinning up 4× Postgres containers. The job shares theSwatinem/rust-cachekeysqlx-testswith the matrix so it primes (or reuses) the same Rust dep cache.Follow-ups (not in this PR)
The v2.3 schema is documentation only — the SQL changes that match it (drop
b3fromsvelements, accepthmthere, replaceopf/opvwithop, enforce OPE/ORE exclusion in the SQL layer) land in subsequent PRs.Summary by CodeRabbit
Documentation
Tests
CI