test(ingest): prove the Rust classifier and the SQL compiler agree - #435
Closed
JeremyFunk wants to merge 1 commit into
Closed
test(ingest): prove the Rust classifier and the SQL compiler agree#435JeremyFunk wants to merge 1 commit into
JeremyFunk wants to merge 1 commit into
Conversation
This was referenced Aug 11, 2026
JeremyFunk
force-pushed
the
ai/06-rust-sql-equivalence
branch
from
August 12, 2026 20:04
35a2cad to
1d3ab76
Compare
Adds the differential layer that makes the two evaluators of one registry checkable against each other: `ai_equivalence_fixtures.rs` drives the real row writer (`encode_traces`) over a branch-covering span set and emits `equivalence-spans.jsonl`, and the domain-side e2e suites replay those exact rows through a real ClickHouse and compare the compiled SQL's verdict to the Rust writer's, span for span. The fixtures are generated from the row writer rather than hand-written because the thing under test is the writer's canonicalization — including first-occurrence-wins duplicate-key resolution and present-but-empty versus absent — and a hand-written fixture would encode our belief about that rather than its behaviour. `fixture_is_reproducible` asserts the emitted bytes are stable, so a drifted classifier fails in Rust before the SQL leg ever runs. `hash-alignment` separately pins that ClickHouse's `cityHash64(value)` equals the Rust hash, including adversarial non-ASCII shapes, and keeps the multi-argument negative pin: `cityHash64(a, b)` combines per-argument hashes rather than hashing a concatenation, so any SQL recomputing this column must pass exactly one argument. The divergences that remain are enumerated in `PINNED_DIVERGENCES` and the suite fails if the set changes in either direction. The fixtures module hooks into `telemetry.rs` rather than its `tests` child because `encode_traces` is private there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
JeremyFunk
force-pushed
the
ai/06-rust-sql-equivalence
branch
from
August 12, 2026 21:05
1d3ab76 to
5fa7589
Compare
Collaborator
Author
🍁 Maple PR previewNote Preview resources were removed when this pull request closed. Final commit |
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.
What this layer contains
The differential proof that the two evaluators of one registry agree — no production behaviour changes.
apps/ingest/src/ai_equivalence_fixtures.rs— drives the real row writer (encode_traces) over a branch-covering span set and emits the fixture corpus, plustelemetry.rs's#[cfg(test)]hookup for it.packages/domain/src/ai-registry/__fixtures__/equivalence-spans.jsonl(+ README) — the emitted rows.equivalence-support.ts,equivalence.clickhouse.e2e.test.ts,hash-alignment.clickhouse.e2e.test.ts,corpus-equivalence.clickhouse.e2e.test.ts— replay those rows through a real ClickHouse and compare the compiled SQL's verdict to the Rust writer's, span for span.Why it is shaped this way
The fixtures are generated from the row writer rather than hand-written because the thing under test is the writer's canonicalization — first-occurrence-wins duplicate-key resolution, present-but-empty versus absent,
AnyValue → Stringcoercion. A hand-written fixture would encode our belief about that behaviour instead of the behaviour itself, and would keep agreeing with the SQL after the writer drifted.fixture_is_reproducibleasserts the emitted bytes are stable, so a drifted classifier fails in Rust before the SQL leg runs at all.The remaining known divergences are enumerated in
PINNED_DIVERGENCES, and the suite fails if that set changes in either direction — a silently-fixed divergence is as much a signal as a new one.hash-alignmentseparately pins that ClickHouse'scityHash64(value)equals the Rust hash, including adversarial non-ASCII shapes and the negative case that multi-argumentcityHash64is a different function. The fixtures module hooks intotelemetry.rsrather than itstestschild becauseencode_tracesis private there.Gates run at this level
cargo test --locked(+TRACE_CAPTURE_DIR) — 136 lib + 75 bin, 0 failures, includingfixture_is_reproducibleandfixture_covers_every_branch.packages/domainvitest underCLICKHOUSE_E2E=1—equivalence6 passed,hash-alignment5 passed.bun typecheck— 37/37 tasks pass.corpus-equivalence.clickhouse.e2e.test.tsskips without a local trace-capture corpus, by the same on-demand design as the Rust corpus replay.Dependencies
Requires #434 — the fixtures drive the wired row writer, and the replay inserts into the
tracesschema that PR adds. Requires #433 for the SQL compiler and #432 for the classifier.🤖 Generated with Claude Code
Stack created with GitHub Stacks CLI • Give Feedback 💬
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.