# Runtime revision routing for CAS lookups CAS routing preserves `jn:open`'s timestamp and `jn:doc`'s integer revision as an expression evaluated for each input tuple. The timestamp lookup uses the resource session's revision-by-instant lookup. Its bounded memo belongs to the query context, not a cached plan, is synchronized across workers, and is invalidated when the resource publishes another revision. Revision arguments retain Brackit's original function conversion and cardinality rules, including untyped atomic values and integer range checks. Literal field equalities in a FLWOR `where` or array filter can select a CAS row source for integer business-key probes between -16,777,215 and 16,777,215, including a document whose root is an array. Other probe types and values retain generic execution. The full predicate stays in place: the other conjuncts still filter the selected objects. At the evaluated revision, routing rechecks the index catalogue and falls back to the original source if the index is unavailable or its numeric-domain evidence no longer permits the lookup. Only repeatable revision operands are eligible for a rewrite because fallback can evaluate the original source again. Legacy path, name and CAS rewrites also retain the revision operand and validate their compiled index definitions at execution. Numeric CAS construction and maintenance retain numeric values during integer conversion. Integral representations such as `1.0` share the integer key `1`; fractional values are never truncated into integer postings. Revisioned catalogue evidence records whether indexed fields are numeric and whether conversion covers every value. Integer point equality uses the numeric-domain evidence; residual-free ranges and non-integer numeric indexes require complete coverage and otherwise retain the original query. Residual-free numeric routes also fall back when the equality probe or either range bound is zero, preserving the interpreter's signed-zero comparisons. Evidence is conservative after incompatible writes until the index is rebuilt and remains revision-specific across writer reuse, synchronous and asynchronous commits, and session close/reopen. Direct scans retain the declared index type's representable domain. Filters that use position or sequence size keep their original source. CAS row sources resolve the actual array through the original first-field dereference semantics at the requested revision and exclude postings from duplicate arrays. Legacy CAS equality and range routes fall back to the original expression if a matching posting is shadowed by an earlier field with the same name, including at ancestor steps. Otherwise they publish each result node once. Direct CAS scans continue to expose all indexed postings. Field renames remove old-path postings and insert new-path postings, including all descendants of populated arrays and objects. Path matching uses the path-summary reader's invalidated cache, so an in-place rename is recognized even when the path node key stays the same. Shared path classes and existing destination classes remap only the renamed subtree. The revisioned postings and numeric evidence remain available after commit and reopen. Multiple matching rows retain array order. Dewey IDs supply document order when enabled; otherwise the existing revisioned valid-time array evidence can certify that sorted node keys have array order. Without either proof, the original array source runs. This conservative fallback matters after inserts and moves. Single point matches do not require an ordering proof. Without an ordering proof, collection stops after two inspected postings and evaluates the original source. Independently, two postings outside the selected array trigger fallback even when ordering is known, bounding candidate work when duplicate arrays contribute unrelated postings. Revision memoization bounds both sessions and instants per session to 256 entries. By default, the SH1 loader creates the integer CAS path `/[]/id` on contracts and products at E0, after automatic valid-time index creation; declaration overrides are owned by the [loader comparison controls](../bundles/sirix-query/bench/bitemporal/README.md#loader-comparison-controls). The half-open valid-time rewrite and its residual handling remain independent. ## Verification The full-suite counts and mutation results below are author-reported evidence from before the review fixes. The regression coverage descriptions also include tests added during review; the outer pipeline owns final validation of the corrected tree. The author-reported Gradle and Java invocations used the task's two-slot `heavy` limiter, which admits a JVM only with at least 6 GiB available. That validation used an initially empty private Maven repository at `build/runtime-cas/m2-private`, never `~/.m2`. The resolved Brackit snapshot jar has SHA-1 `c9dc857dedcfda2bc92c61a45796db58b58847e1` and a Maven build timestamp of 2026-10-06 15:22:13 UTC. It matches the [published checksum for snapshot 93](https://central.sonatype.com/repository/maven-snapshots/io/sirix/brackit/1.0-alpha10-SNAPSHOT/brackit-1.0-alpha10-20261006.152144-93.jar.sha1). Author-reported Gradle flags: `--no-daemon --max-workers=2 -Dorg.gradle.jvmargs=-Xmx2g -Dmaven.repo.local=/build/runtime-cas/m2-private -PtestHeapMin=256m -PtestHeapMax=2g`. - `RuntimeRevisionCASTest`: historical filter and correlated FLWOR queries on all four versioning types, prolog and integer operands, pre-index revisions, and array order after insertion, function argument conversions and invalid inputs, with executable optimized-plan assertions. Review regression coverage also checks nested tuple-relative projections, public CAS plan metadata, interleaved worker cursor navigation, parallel historical queries, and concurrent memo invalidation. - `BitemporalBusinessKeyIndexTest`: persisted catalogues keep only the required business-key `id` path on contracts and products, omit `pid` and supplier business-key CAS indexes, and preserve automatic valid-time indexes for all three relations. - The [work-budget inventory](../bundles/sirix-core/src/test/java/io/sirix/budget/README.md#what-is-here) owns the CAS lookup and multi-match budgets. - `CASSourceSemanticsTest`, `CASLegacySignedZeroTest`, and the core numeric CAS tests cover numeric conversion and mutation evidence, signed-zero comparisons, positional focus, and first-field source identity against generic execution. - `CASCoverageEpochTest`: all four versioning types preserve coverage through synchronous and asynchronous writer reuse, commit and fresh-session reopen, and compare historical query answers with generic execution. - `CASMixedNameMutationTest` and `CASMixedValidTimeMutationTest`: mixed-index insert/update/delete/move histories preserve NAME postings and first-field valid-time semantics after commit and fresh reopen; routed valid-time answers are compared with fallback. - `CASLegacyDuplicateFieldTest`, `CASPathRenameTest`, and `CASContainerRenameTest`: first-field publication and scalar, empty-container, and populated-container renames are compared with generic execution at historical revisions and after reopen across all four versioning types. Container cases also check direct CAS scans and sibling NAME, PATH, and VALIDTIME maintenance. - `CASScalarBulkImportTest`: CAS-only bulk imports over scalar fields preserve numeric coverage and routed equality answers without extra scalar path observations. - Full `:sirix-core:test`: 13,156 tests, 78 skipped, zero failures/errors. - Full `:sirix-query:test`: 3,005 tests, 12 skipped, zero failures/errors. Its separate generic reader-lifetime fork also passed all 16 tests. - All work budgets existing at the author-reported validation passed without changing their bounds. `spotlessJavaApply` completed for both modules; `:sirix-core:spotlessCheck :sirix-query:spotlessCheck` passed on that pre-review tree. - No-mistakes validation and shipping follow the committed implementation handoff. ## SH1 measurements The baseline is commit `842f48e080ef3897c4fc421d05650dc2a7c35e33` with the original kit indexes. The input is the campaign's t100k stream (234,884 events, 25 publications). All generated stores and outputs stay under `build/runtime-cas/`. Authoritative timing logs are `before-original.log` and `after-final.log`; every retained and discarded repetition matched the oracle. The after run uses the author's compiled production classes from the successful full-suite build before review fixes. A task-local copy of the loader permits that output directory; loading logic and JVM flags are unchanged. The before runtime uses an isolated overlay compiled from the initial commit's original versions of every changed production class. The recorded after measurements include the contracts `pid` CAS path subsequently removed during review. These timings have not been rerun on the corrected tree; they remain the accepted author-provided before/after evidence. Protocol: one warm process, ten repetitions for Q1/Q2/Q3/Q10 and three for Q5, discard the first, report medians. Each repetition compiles, fully consumes, serializes and canonicalizes the result. Every canonical TSV is byte-compared with the campaign oracle before admitting a timing. JVM flags are `-Xms512m -Xmx2g -XX:MaxDirectMemorySize=1g`, with preview and the vector module enabled. | Query | Before, total ms | After, total ms | After, execute ms | |---|---:|---:|---:| | Q1 | 90.839 | 13.214 | 3.797 | | Q2 | 63.895 | 6.921 | 2.212 | | Q3 | 246.391 | 8.980 | 4.640 | | Q5 | 1443.498 | 30.454 | 22.676 | | Q10 | 1059.407 | 1059.288 | 1050.943 | These baseline figures differ from the original profiling report because this checkout already includes subsequent optimizer and valid-time work. Q10 has no literal business-key equality; its joins and interval-overlap predicates remain outside this CAS point-lookup rewrite. The run does not reach a 1 ms total for Q1–Q3: query compilation alone takes several milliseconds, and point-query execution is approximately 2–5 ms. Q5 execution takes 28.720 and 16.632 ms in the two retained repetitions, a 22.676 ms execution median; its 30.454 ms total remains above the 10–25 ms target. The total includes compilation, serialization and canonicalization. Component medians are independent and need not sum to the total median. These runs share the laptop with other workers. No timing is a test assertion. The recorded acceptance decision accepts these results for this PR against the SH1-at-or-below-XTDB bar. The approximate 1 ms figure was the profiling report's engineering estimate. The remaining query compilation work is tracked as a separate follow-up; this PR does not require further latency work. Mutation verification uses separately compiled overlay classes, leaving the production source and running validation builds untouched. Removing CAS routing keeps the answer but changes 50 indexed transactions to zero; bypassing the memo keeps the answer but changes two revision-by-instant calls to 50. Substituting the latest revision makes the historical value 20 instead of 10 on all four versioning types. The healthy budget passes, and each mutation fails. A separate before/after run also reproduced rejection of a valid untyped timestamp when bypassing the original function conversion. Reusing Brackit's converter passes all 13 revision tests, including numeric narrowing and invalid argument checks.