Skip to content

feat(eql): test equality and ranges on one array element of a json_tree document - #1445

Open
coderdan wants to merge 3 commits into
fix/eql-v4-json-function-blockersfrom
feat/eql-v4-json-tree-element-match
Open

coderdan wants to merge 3 commits into
fix/eql-v4-json-function-blockersfrom
feat/eql-v4-json-tree-element-match

Conversation

@coderdan

@coderdan coderdan commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

EQL v4 stores an encrypted JSON document in a public.eql_v4_json_search column. Until now a filter such as "some emergency contact is a Sibling and has more than five calls" could only be written as two separate tests, an equality (@>) and a range (an ordering over eql_v4.json_tree_path_query), and two different contacts could satisfy them. So the query returned more rows than the plaintext jsonpath exists($.contacts[*] ? (@.relationship == "Sibling" && @.calls > 5)) does.

This PR adds eql_v4.json_tree_element_match(col, $1::eql_v4.query_json_elements), which is true only when one array element satisfies every part of the predicate, and the Stack Encrypt query operator element_match that derives its one parameter. No stored format changes: existing documents answer the new query as they are.

Changes

EQL (packages/eql)

  • src/v3/json_tree/functions.sql: new eql_v4.json_tree_subtree_indexed(e, tokens, budget DEFAULT 64) RETURNS TABLE (k integer, entry public.eql_v4_json_entry). It is the existing subtree read body, now returning k, the 1-based place in tokens of the token whose node each row sits in (0 for the sealed-root fallback past the budget). json_tree_subtree is now a projection of it, so there is one implementation.
  • src/v3/json_tree/types.sql: new domain eql_v4.query_json_elements ({"m": [{"t": [token, …], "gt"|"gte": leaf, "lt"|"lte": leaf}, …]}), with a CHECK that validates each member's tokens and its bounds as query_json_leaf operands.
  • src/v3/json_tree/elements.sql (new, v4 only): eql_v4.json_tree_element_match. It opens the row's document once, finds the node each member's tokens name by its self tag (the node json_tree_subtree_indexed returns at d = 0, and nothing beneath it), pairs the members' nodes by k, and compares with the existing entry-against-leaf operator functions. Each bound is checked by the same validator the query_json_leaf CHECK now calls (eql_v4_internal.json_tree_is_valid_leaf_query_payload). It raises invalid_parameter_value (SQLSTATE 22023) when a probe token finds a node (see "How the probe is detected" below).
  • Catalog: eql_domains::JSON_TREE gains the ElementsQuery role (JsonSearchElementsQuery, eql_v4.query_json_elements). Generated from it: the eql-bindings v4 inventory and the Go type eql.JSONSearchElementsQuery in languages/golang/encrypt/eql/eql_gen.go. Hand-written: the JsonTreeElementsQuery binding struct, and Target::elements_query_sql_domain().
  • Docs: a new "One array element in EQL v4" section in docs/reference/eql-functions.md (the function, the operand, the folded-equality caveat, the probe error, the planner cost, the hand-written EXISTS … JOIN … ON c.k = r.k form), and a bullet in json-tree-leakage.md on what the query reveals. packages/eql/AGENTS.md lists the new file and domain.
  • Changeset: @cipherstash/eql minor.

Engine (packages/stack-encrypt)

  • dynamic/json_query.rs: a new operator, element_match. Its input is {"path", "wildcard_bound"?, "predicates": [{"member", "op", "json" | "low"+"high"}]}, and it derives the eql_v4.query_json_elements operand. It reuses the subtree token derivation for path + member, and the leaf-operand derivation gt_at/between_at use. eq is one leaf operand used as both gte and lte. There is no new cryptographic derivation. The module's operator table has the new row and a section on element predicates.
  • dynamic/query.rs, target.rs, mod.rs: OpSpec::ElementMatch (input path_predicates), TargetDescriptor::with_elements_query_sql_domain, and four new refusal reasons: json_path_no_wildcard, json_no_predicates, json_wildcard_bound_zero and json_unknown_predicate_op. OpSpec::fidelity's rustdoc says the orderings and element_match are exact on the ordering terms, so element_match's eq is an equality of folded values.
  • json/derive.rs: JsonSubtreeKey::below(steps), which extends a derived read by member and element steps, so element_match derives the elements' read once and extends it per member. A test holds it equal to the full path's key under both root options, through nested wildcards.
  • target/pending.rs: one Box::pin around the keyset loads' join_all. See the review notes.

Verification

Everything ran locally on macOS against a private PostgreSQL 17 container (port 7541), after mise run build in packages/eql.

  • mise x --env test -- cargo nextest run -p stack-encrypt --all-features: 1008 passed. That includes 8 new element_match tests in tests/json_operators.rs:

    • each op derives the ordering's leaf operand, and eq has lo = hi;
    • each member's tokens are the subtree read of its full path, and every member ends with the same probe;
    • the default bound is used when none is given;
    • a Rust model of the SQL function over sealed documents: two halves are not a match, one element with both is, and an array longer than the bound is a probe hit;
    • a proptest oracle (48 cases) against plaintext jsonpath semantics;
    • every refusal by its reason, including wildcard_bound: 0, an unknown op, and a member path error whose offset lands in the member's own text;
    • the operator is listed only with an ordered path and a named domain.
      The heap-hygiene test now covers the operator too.
  • Root workspace: cargo clippy --workspace --all-targets -D warnings under default features and under --all-features, mise run wasm:wasi-check, mise run wasm:no-http-test, mise run wasm:guest:test (76 passed), cargo fmt --all --check, doctests (91) and mise run doc:stack-encrypt: clean. JsonSubtreeKey::below and its test carry #[cfg(feature = "dynamic")], the feature of its only caller, as the crate gates MAX_DEPTH and JsonPath::of; without that, every build without dynamic reported it as dead code: the WASI check, and also the --all-features workspace clippy, because that builds stack-encrypt a second time as a dev-dependency of the proc-macro crate stack-encrypt-derive, with that crate's features, which do not include dynamic.

  • cargo-mutants, cargo mutants -p stack-encrypt --in-diff <diff against fix/eql-v4-json-function-blockers>: 35 mutants, 26 caught, 9 unviable, 0 missed (re-run after the rebase onto the new fix(eql): block native jsonb functions on the v4 JSON tree domains #1444 head). The unviable ones are Default::default() replacements of types that have no Default.

  • SQLx lint_tests (12), build_validation_tests (5), selector_literal_guard (10) and v3_public_surface_tests (7): passed.

  • EQL_TEST_DATABASE_URL=… mise run test:encryption:postgres on a fresh database: all suites passed, json_tree 28: the 14 existing json_tree PostgreSQL tests (which run json_tree_subtree unchanged), the 8 function-blocker tests from fix(eql): block native jsonb functions on the v4 JSON tree domains #1444, and six new tests in tests/json_tree/elements.rs. Every one seals real documents with Stack Encrypt under the fake key source and derives its operands through a data plan over eql-bindings' target table; EQL tests must run over real encrypted data, and the SQLx suite has no way to produce a JSON tree document, so the SQL's contract is pinned here rather than in a SQLx file with hand-built documents. Five of them cover:

    • the operand domain's CHECK, member by member, over a derived operand and its parts (20 refused shapes, 4 accepted);
    • one element must satisfy every member while the component orderings return the superset, under the sealed root and the open one;
    • each bound (gt, gte, lt, lte, between, eq, and two bounds on one member) compares as the entry operators do, and a field with no ordering term or no field satisfies none;
    • a probe hit raises: an array longer than the bound, and a token whose node was moved to the element's selector;
    • json_tree_subtree equals the indexed read without k under budgets 0, 1, 2, 3 and 64, k is the place of the token whose node a row sits in, and the sealed root falls back to k = 0.

    The sixth, postgres_an_element_predicate_holds_of_one_element, checks:

    • two halves are returned by @> plus json_tree_path_query, and not by json_tree_element_match;
    • one contact with both halves is returned by both queries;
    • "sibling" ties with "Sibling" under the element predicate but not under exact @>;
    • a bound of 1 raises 22023;
    • the subtree read equals the indexed read without k, and a k join pairs the fields of one contact;
    • an unordered member is refused by the engine.
  • mise run test:crates (498), test:encryption (541), types:check, typescript:check and codegen:parity: passed.

  • The engine also has a derive.rs test that holds JsonSubtreeKey::below equal to the full path's key, under both root options and through nested wildcards.

  • docs:validate:required-tags, docs:validate:coverage, docs:validate:documented-sql (against my own container), test:doc-anchors and test:docs_v3_grep: passed.

  • Go: wasm:guest:build, wasm:auth-guest:build, wasm:guest:build:deterministic, wasm:guest:build:eql and wasm:guest:build:eql:deterministic built, then mise run go:test passed for every package.

Not run:

  • v3_v4_coexistence_tests, v3_privilege_tests and v3_uninstall_tests fail to compile here: they read the credential-generated fixtures/eql_v3_integer.sql and v3_ste_vec.sql, and this environment has no CipherStash credentials. They test v3 and integer surfaces. This PR does not change the v3 bundle, because every file it touches is -- ONLY EQL VERSION: 4.
  • pnpm run code:check: no JS or TS changed.
  • go:test:postgres: not run.

Related

Closes #1440

Stacked on #1444. Refs #1441 (this operand becomes one leaf kind of that predicate tree) and #1442 (the Go call that wraps it).

Review notes

  • Operand shape. One parameter, as preferred: {"m": [member, …]}, each member {"t": [tokens…], "gt"|"gte": leaf, "lt"|"lte": leaf}.
    • I used bound keys named by their comparison instead of plain lo/hi, because gt and lt are strict. A plain lo/hi pair could not express that without extra flags.
    • A domain CHECK can validate nested leaf operands through a PL/pgSQL validator, as query_json's group validator already does, so the single operand works.
    • The leaf check is restated inside the new validator rather than shared with query_json_leaf's inline CHECK. Sharing it would mean a new SQL helper, which pin_search_path then pins, or an eql-inline-critical allowlist entry.
  • How the probe is detected. By selector, not by position. Every non-probe token of a member names the field ($.contacts[i].relationship), whose selector is the one the member's bounds carry. The probe names the element itself ($.contacts[N]), at the array's selector. So a d = 0 row whose selector differs from its member's raises.
    • This also covers nested wildcards, where probes sit in the middle of the list.
    • It raises even if an element within the bound matched. A true would be correct in that case, but the error stays deterministic per row rather than depending on which element matched first.
  • Refusals Go SDK: no way to test an equality and a range on the same array element of a JsonSearch field — add an element-scoped Match on top of #1440 #1442 mirrors: json_path_no_wildcard, json_wildcard_bound_zero, json_no_predicates, json_unknown_predicate_op, json_input (keys that do not fit the op), json_path_wildcard (a wildcard in a member), and the index's JsonOrderingAtPosition, JsonPathNotOrdered, JsonLeafNotOrdered, JsonPath (at an offset into the member's own text) and JsonTooDeep. subtree still accepts wildcard_bound: 0: a probe-only read still answers whether an array is empty, where a probe-only predicate can never be true.
  • The unordered-member refusal does not print the path. It is the same TermError::JsonPathNotOrdered the orderings give. The crate keeps path text out of errors, because a key name can be customer data (see JsonPathError), so the error names neither the path nor which predicate failed. Go SDK: no way to test an equality and a range on the same array element of a JsonSearch field — add an element-scoped Match on top of #1440 #1442's stashgen check runs at generate time, where the path is schema, and that is the place to name it. If you want the engine error to carry the predicate's index, it is a small follow-up.
  • The Go guest is deliberately not wired. The operator is listed only when the target names the elements domain. The Go guest (languages/golang/encrypt/guest/src/targets.rs) does not name it yet, so the Go SDK sees no new operator and its pinned operator lists stay unchanged. Go SDK: no way to test an equality and a range on the same array element of a JsonSearch field — add an element-scoped Match on top of #1440 #1442 needs:
    • one with_elements_query_sql_domain(target.elements_query_sql_domain()) line in that guest;
    • element_match added to parseOperatorName (encrypt/checker.go) and to stashgen's jsonOperators.
      Without those, a catalog listing it is refused as an unknown operator.
  • pending.rs is a workaround with an unidentified mechanism; please decide. Without it, tests/heap_hygiene.rs's json_open (subtree) watch fails on this branch every time (macOS arm64, debug build), and passes on the base.
    • What was freed: load_keysets' future box (256 bytes), holding the retrieved data key at offset 64, the key's first 16 bytes again after it, and two stack addresses, in a pattern repeated later in the block. That looks like an image of a stack frame.
    • What it is not: the test harness's own copy of the key (Recorded::record). Rewriting that copy to go through no stack temporary left the failure unchanged. It is also not residue from before the watch: scrubbing 1 MiB of stack instead of 256 KiB left it unchanged too.
    • What fixes it: boxing the keyset loads' join_all, so the outer future holds the loads as a pointer.
    • What I could not find: which write copies the bytes in. The comment at the call site states the observation, not a mechanism.
    • The cost: one allocation per dispatch.
  • Equality is folded: text is case- and accent-folded, and integers past 2⁵³ can tie, as json_tree: an equality and a range cannot be tied to one array element — return the token index from json_tree_subtree and derive per-element reads in the engine #1440 states. Exact per-element equality would need a stored-format addition and is out of scope.
  • Input values are JSON text, as in every other JSON operator: "json": "\"Sibling\"", not "json": "Sibling".

https://claude.ai/code/session_01MrxG724qYKcAWJdcABBFNY

@changeset-bot

changeset-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 15e9c56

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@cipherstash/eql Minor
stash Patch
@cipherstash/stack-prisma Patch
@cipherstash/basic-example Patch
@cipherstash/e2e Patch
@cipherstash/prisma-example Patch
@cipherstash/stack-drizzle Patch
@cipherstash/stack-supabase Patch
@cipherstash/stack Patch
@cipherstash/wizard Patch
@cipherstash/bench Patch
@cipherstash/test-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI; Enforced overrides: Organization
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b3079dfa-214e-42d0-8b0b-1b85cbc2300b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

Comment thread packages/eql/src/v3/json_tree/elements.sql Outdated
Comment thread packages/stack-encrypt/src/dynamic/query.rs
Comment thread packages/stack-encrypt/src/dynamic/json_query.rs Outdated
Comment thread packages/stack-encrypt/src/dynamic/json_query.rs Outdated
Comment thread packages/stack-encrypt/src/dynamic/json_query.rs Outdated
Comment thread packages/stack-encrypt/src/target/pending.rs
Comment thread packages/eql/src/v3/json_tree/types.sql Outdated
Comment thread packages/eql/src/v3/json_tree/functions.sql Outdated
Comment thread packages/stack-encrypt/src/dynamic/json_query.rs Outdated
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Mutation testing (cargo-mutants, --in-diff, stack-auth + stack-encrypt)

caught missed unviable timeout
26 0 9 0

Every mutant in the changed lines was caught by a test.

…ee document

An equality and a range at two paths under one array could only be
asked as `@>` plus an ordering over `json_tree_path_query`, which two
different elements can answer: a superset of the plaintext jsonpath
`exists($.a[*] ? (@.x == $v && @.y > $w))`.

`json_tree_subtree` already computed `k`, the place in `tokens` of the
token that found each row, and dropped it. `json_tree_subtree_indexed`
returns it, and `json_tree_subtree` is now its projection, so the two
reads have one implementation. A client expands a wildcard in element
order to one bound, so reads of two fields of one array agree on `k`
for one element.

`eql_v4.json_tree_element_match(col, p eql_v4.query_json_elements)`
takes one operand: per field, its read tokens (probe included) and its
bounds as `query_json_leaf` operands. It opens the document once, finds
the node each token names by its self tag (the node the subtree read
returns at `d = 0`, with nothing beneath it read), pairs the members'
nodes by `k`, and compares with the existing entry/leaf operators. A
bound is checked by the same validator as the `query_json_leaf` CHECK. A token that names a node at another
selector than its member's bounds is the probe's hit on an array longer
than the bound, and raises `invalid_parameter_value` instead of
answering over part of the array.

The domain joins the catalog as the json_tree family's ElementsQuery
role, so the eql-bindings inventory and the Go `eql` package pick it up
from the generator (`eql.JSONSearchElementsQuery`).

Refs #1440
…ment field

`element_match` takes `{"path", "wildcard_bound"?, "predicates"}`: an
array's elements by a path with a wildcard, and predicates on fields of
an element by a member path relative to it. Its operand is
`eql_v4.query_json_elements`: per predicate, the `subtree` tokens of the
member's full path at the bound, and the leaf operands the orderings
derive for its values. `eq` is one leaf as both `gte` and `lte`, so its
equality is the ordering term's (folded text, numbers as float64), and
`between` is `between_at`'s two. The elements' read is derived once and
each member's extends its tokens by the member's steps
(`JsonSubtreeKey::below`, the member and element rules the full path's
key applies). No new derivation.

Refused before anything is derived: a path with no wildcard, a
`wildcard_bound` of 0, a position in the path or a member, a wildcard in
a member, an empty predicate list, an unknown `op`, a value no ordering
takes, and a member whose full path the field does not order. The operator is listed only on a
field that orders a path and whose type names the elements domain
(`TargetDescriptor::with_elements_query_sql_domain`), so a host that
does not name it, such as the Go guest today, sees no new operator.

The heap hygiene suite's `json_open (subtree)` watch fails on this
branch, and passes on the base, with `load_keysets`' 256-byte future box
freed holding a retrieved data key and stack addresses (macOS arm64
debug build). Boxing the keyset loads' `join_all` makes the residue go
away; which write copies it in is not identified, so this is a
workaround, recorded as an observation at the call site.

Refs #1440
…PostgreSQL

Seals contact lists with the JSON index, derives `element_match` through
a data plan over eql-bindings' target table, and queries the column:
two contacts each holding half of the predicate are returned by the
superset query (`@>` and an ordering over `json_tree_path_query`) and
not by `json_tree_element_match`; one contact holding both is returned
by both; a folded spelling ties under the element predicate and not
under exact containment; a bound below the longest array raises; and
`json_tree_subtree` equals the indexed read without `k` under every
budget, the sealed-root fallback at `k = 0`.

The rest of the SQL's contract is pinned over the same documents and
operands: the operand domain's CHECK member by member, over a derived
operand and its parts; one element must satisfy every member under the
sealed root and the open one; each bound, `between` and `eq` compare as
the entry operators do, and a field with no ordering term or no field
satisfies none; a probe's hit raises, including a token whose node was
moved to the element's selector; and `k` is the place of the token
whose node a row sits in. EQL tests run over real encrypted data, and
the SQLx suite has no way to produce a JSON tree document, so these
live here.

Refs #1440
@coderdan
coderdan force-pushed the feat/eql-v4-json-tree-element-match branch from 8c14324 to 15e9c56 Compare October 30, 2026 04:47
@coderdan coderdan closed this Oct 30, 2026
@coderdan coderdan reopened this Oct 30, 2026
@coderdan

Copy link
Copy Markdown
Contributor Author

Rebased onto #1444's new head (0883fb1); new head 15e9c56.

Why:

  • fix(eql): block native jsonb functions on the v4 JSON tree domains #1444 took its review feedback: its blocker tests moved from a SQLx file with a hand-written envelope to the encryption test crate, over a document Stack Encrypt seals (EQL tests must use real encrypted data, and the SQLx suite cannot produce a JSON tree document), plus upgrade note U-004 and doc and changeset fixes.
  • This PR's SQLx file v4_json_tree_element_match_tests.rs hand-built its documents the same way, so its five tests moved into packages/eql/tests/encryption/tests/json_tree/elements.rs, over documents Stack Encrypt seals and operands element_match derives (the SQL commit no longer adds the SQLx file; the test commit carries them).
  • The clippy failure in fmt, clippy, nextest, doctests, rustdoc and WASI check, guests and Go (Linux): JsonSubtreeKey::below and its test now carry #[cfg(feature = "dynamic")], the feature of its only caller, folded into the stack-encrypt commit. Clippy passes under default features and --all-features, and mise run wasm:wasi-check passes.

@coderdan coderdan closed this Oct 30, 2026
@coderdan coderdan reopened this Oct 30, 2026
@coderdan
coderdan removed this pull request from stack #1449 October 30, 2026 10:32
@coderdan
coderdan marked this pull request as ready for review October 30, 2026 10:42
@coderdan
coderdan requested a review from a team as a code owner October 30, 2026 10:42
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T10:45:08.159755Z 15e9c56 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-30T10:46:18.480273Z 15e9c56 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cipherstash-agent cipherstash-agent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review attestation: code-review (medium) + cross-check against existing feedback

Reviewed commit: 15e9c56 (base fix/eql-v4-json-function-blockers @ 0883fb1)
Result: no critical or blocking issues. No new findings.

Read in full:

  • elements.sql
  • the types.sql and functions.sql diffs
  • the json_query.rs operator, input and operand derivation
  • JsonSubtreeKey::below in derive.rs
  • the query.rs and pending.rs diffs
  • the catalog, binding and changeset changes

Not read in depth: the large new test files (elements.rs, json_operators.rs). I did not run the test suites; I relied on the PR's stated results.

Checked:

  • k pairing and the probe.
    • The count-per-k pairing is sound. The CHECK requires equal token counts, so one k is one element, including with nested wildcards.
    • Probe detection by selector holds. A non-probe token's node carries the member's field selector, and the probe's carries the array's.
    • A 22023 raise on a probe hit is deterministic per row.
  • json_tree_subtree as a projection of _indexed. The wrapper drops k and has one implementation, so the two reads cannot disagree.
  • Leaf-validator reuse. query_json_leaf and the new elements CHECK share json_tree_is_valid_leaf_query_payload.
  • Existing domain on upgrade. The IF NOT EXISTS guard keeps an existing query_json_leaf domain on its old CHECK. The validation is equivalent, so I found no behavioural difference.
  • Rust refusals and offsets. The refusal ordering is consistent. member_path offset shifting is correct and saturating. below keeps probes as they are and refuses wildcards.
  • Fidelity. ElementMatch fidelity matches the orderings.
  • Skills and changesets.
    • No skills/*/SKILL.md references EQL v4 json_tree or its operands, so there is no skill drift.
    • The @cipherstash/eql minor changeset is present.
    • The stack-encrypt and eql-bindings crates are published through release-plz, so they need no changeset.

Cross-check: all 9 existing review threads (coderdan's efficiency, fidelity, refusal, offset, reuse, double-sort, per-member re-derivation and Box::pin items) are resolved and addressed at head, and I did not re-raise any of them.

Open for the author (already flagged in the PR notes, not a new finding): the pending.rs Box::pin is a workaround with an unidentified mechanism and adds one allocation per dispatch. The author asked for a decision. A future layout change could re-expose the heap-hygiene watch failure.

Still running: the Codex code and security reviews on this commit.


Generated by Claude Code

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 15e9c56039

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +161 to +165
pub fn elements_query_sql_domain(&self) -> Option<&'static str> {
use crate::v4::DomainType;
document(self.name)
.map(|_| crate::v4::json_tree::JsonTreeElementsQuery::sql_domain_static())
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire the element predicate domain into the Go guest

For Go callers using JsonSearch, the new element_match operation remains unavailable: languages/golang/encrypt/guest/src/targets.rs::describe copies leaf_query_sql_domain() but never copies this new domain into TargetDescriptor. Consequently, dynamic/query.rs::answers filters out ElementMatch, and attempting to derive its operand returns operator_not_answered, despite the newly generated JSONSearchElementsQuery type. Propagate the domain through the production guest descriptor and update the Go checker's operator/input readers to accept element_match and path_predicates; the new Rust tests currently supply the descriptor metadata themselves and therefore bypass this integration gap.

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants