Skip to content

json-rules 3.4.1: bridged sources over-fetch and re-check - #31

Merged
agreenspan merged 1 commit into
mainfrom
fix/bridged-source-recheck
Oct 8, 2026
Merged

agreenspan merged 1 commit into
mainfrom
fix/bridged-source-recheck

Conversation

@agreenspan

Copy link
Copy Markdown
Contributor

Per Aron (2026-10-08): "when you're doing an in-memory check, you have to overfetch. You shouldn't be pre-filtering because that way the rules break."

Change

  • toSourceQueries returns a real query for a source across a bridge. Its where, a carried grant, its label or an axis can be what crosses. What reads across the bridge compiles to TRUE, so the rows are a superset. The query carries recheck: the conjuncts of composedWhere that read across a bridge, or true when only the label or an axis does. Every bridged query carries recheck, and non-bridged queries carry none.
  • The query selects only local columns: the value, the local label and axes, the local columns recheck reads, and each bridge's local on key. It has no distinct.
  • A source past a bridge has its grants above carried back across the bridge, through the far model's bridge field, into recheck.
  • materializeSourceQuery(query, rows, { lens, …CheckOptions }) applies recheck to candidate rows that hold the far side inline. It reads a bridged label or axis from the far side, in both row shapes. If the far side is missing or partial, or is a list where the bridge names one row, it throws UsageError; so does a call without lens.
  • SourceQuery.prisma is non-null again (reverts the 3.4.0 null).
  • materializeSources now refuses every pointer, bridged ones included, because they all have a query.
  • Updated: README "Sources across a bridge", docs/LENS.md, CHANGELOG 3.4.1, version.

First consumer: rules-builder / Kingdom source pickers over bridged lenses. Before this they got prisma: null and had no query.

Tests

test/lens.bridgeRecheck.test.ts uses PGlite users with in-memory CRM profiles. It runs both the Prisma and SQL rails and covers:

  • a bridged notEquals where;
  • a bridged where with a local conjunct, which the DB still decides;
  • a label across the bridge;
  • an axis across the bridge;
  • a bridged pointer;
  • a path source past the bridge.

In each case the DB rows are a superset, and candidates plus far side plus recheck equal the hand oracle. materializeSources agrees. A non-bridged source has no recheck and is unchanged. Misuse cases each throw UsageError: no lens, far side not loaded, far side partial, far side as a list.

The bridged tests in rounds 9, 10 and 11 and in sourceFromMapDefaults were updated to the new contract. bun run check: 2647 pass.

🤖 Generated with Claude Code

A source across a bridge (where, carried grant, label or axis) now gets a
real query for the local side, with the bridged parts folded to TRUE, plus
a `recheck` condition the caller runs over candidate rows once the far side
is loaded. materializeSourceQuery({ lens }) applies it, with the round-11/12
misuse detection. SourceQuery.prisma is non-null again.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@agreenspan
agreenspan merged commit fa7d3d3 into main Oct 8, 2026
1 check passed
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