Skip to content

test: conjoin $or/$and with sibling filters in twelve driver doubles - #8493

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7620-remaining-lanes-or-conjoin
Aug 13, 2026
Merged

test: conjoin $or/$and with sibling filters in twelve driver doubles#8493
os-zhuang merged 1 commit into
mainfrom
claude/issue-7620-remaining-lanes-or-conjoin

Conversation

@os-zhuang

@os-zhuang os-zhuang commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Part of #7620 — the last of three lanes (objectql's six landed in #7846).

What

Twelve in-memory WHERE matchers across packages/plugins/plugin-sharing,
packages/plugins/plugin-security and packages/runtime returned early on
$or (and usually $and), discarding every sibling equality key in the
same filter object:

if (Array.isArray(filter.$or)) return filter.$or.some((f) => matches(row, f));
// sibling equality keys below this line are never reached

A real driver ANDs them. Corrected to the same "conjoin, don't short-circuit"
shape #7846 already landed for packages/objectql's six, and that several
sibling files in these same two packages already carried.

Re-grepped at this branch's ref — the issue's file list is stale

Per the issue thread's own correction: plugin-sharing/src/sharing-rule.test.ts
was already fixed before this PR (confirmed unchanged here). Re-grepping $or
across plugin-sharing/src/*.test.ts and plugin-security/src/*.test.ts
turned up three files the issue never named, which this PR also fixes:

  • plugin-sharing/src/sharing-service.test.ts
  • plugin-security/src/check-only-write-scope.test.ts
  • plugin-security/src/select-only-write-visibility.test.ts

Files corrected (12 total):

  • packages/plugins/plugin-sharing/src/: authored-row-write-deferral.test.ts,
    boot-backfill.test.ts, bulk-recompute.test.ts, record-share-cascade.test.ts,
    sharing-service.test.ts, system-write-skip-notice.test.ts
  • packages/plugins/plugin-security/src/: authored-row-write-verdict.test.ts,
    check-only-write-scope.test.ts, row-write-widener-composition.test.ts,
    select-only-write-visibility.test.ts, vama-write-path-convergence.test.ts
  • packages/runtime/src/domains/: share-links-enforcement-context.test.ts

Files already correct and not touched: plugin-sharing/src/
bu-tree-recompute.test.ts, business-unit-graph.test.ts, recipient-width.test.ts,
sharing-rule.test.ts, system-caller-inert-grant.test.ts.
packages/runtime/src/domains/meta-published-runtime-publish.test.ts also builds
a $or-handling matcher (found by the same re-grep) and already uses the correct
conjoining form — confirmed, not touched.

Left alone, but flagged: matchers with no combinator branch at all

Three matches instances — plugin-security/src/security-plugin.test.ts (two
separate local functions, one in the explainAccessForCaller describe block, one
in ADR-0090 D10 agent intersection) and plugin-security/src/explain-engine.test.ts
(one, in a helper explicitly commented Minimal where-honouring ObjectQL stand-in: scalar equality and $in) — use an Object.entries(where).every(...) shape that
does not recognize $or/$and as combinators at all. This is a different
shape from the bug this card names (there is no early-return branch to fix), so
this PR does not touch them.

Confirmed via full-file grep that none of the describe blocks using these three
instances currently passes $or/$and — so today they are inert, not silently
wrong. But the failure mode the day someone does add one is worse than the
early-return bug, not better: with no combinator branch, Object.entries treats
$or as an ordinary field name, compares row.$or (normally undefined)
against the $or array, gets no match, and the row is silently excluded — the
suite would then assert on an empty result set with no visible error, which is
exactly the risk the issue's own words describe: "dormant is still worth
closing, because the next test that adds an $or inherits a double that lies."

Not fixed here deliberately — a matcher that has no combinator handling at all
is a different defect shape than "conjoin instead of short-circuit," and
bundling a fix for it into this PR would blur what this PR actually measured.
Flagging it here rather than filing a separate issue, since it is speculative
(never exercised) and inert today; if a future change starts sending $or/$and
through either helper, this comment is the pointer to why the result would look
wrong without erroring.

Live-vs-dormant — measured, not assumed

Same fs.appendFileSync probe discipline as #7846 (a console.log attempt
first returned nothing and was correctly distrusted rather than read as "zero
calls"). All twelve are dormant, for two different reasons:

  • plugin-sharing's six: 0 combinator calls across ~1.52M matcher
    invocations in the six suites. Positive control: the same probe temporarily
    placed in the already-fixed sharing-rule.test.ts (then reverted) recorded
    151 $or / 3 $and calls in the same kind of run — proof the zero above is
    a real absence, not a dead probe.
  • plugin-security's five + the one runtime file: not all-zero —
    $and fires 23–71 times per file, and $or fires twice in
    authored-row-write-verdict.test.ts. But every single occurrence carried
    the combinator as the only key in its filter object (no sibling ever
    present alongside), so early-return and conjoin produce identical results
    in every case observed. Dormant for a different reason than
    objectql/sharing: invoked, but never mixed with a sibling key.

No test outcome changes anywhere. plugin-sharing (21 files / 569 tests),
plugin-security (52 files / 1037 tests) and runtime (151 files / 2317
tests) are green before and after, byte-identical assertions.

Operator-support measurement

Unlike the objectql six (measured byte-identical operator support), these
twelve are not a single lowest common denominator — plugin-sharing's
matchers vary between $in-only and $in+$ne+$gte/$gt depending on
the file; plugin-security's five and the runtime one are the most
uniform subset ($in only). This inverts what the objectql lane found
(byte-identical across all six) and materially changes the shared-helper
question. Detail and rationale for not extracting a shared helper (same
reasoning #7846 used, plus this operator-support gap) is in the changeset.

Two questions this lane does not answer

Both are deliberately left to the PM now that all three lanes have landed:
whether a regression guard is worth adding (none exists today — reinstating
an early return would fail nothing, in any of the sixteen files across all
three lanes), and where a shared matchesWhere helper would live.

Tests

  • pnpm --filter @objectstack/plugin-sharing test — 21 files / 569 tests, all pass
  • pnpm --filter @objectstack/plugin-security test — 52 files / 1037 tests, all pass
  • pnpm --filter @objectstack/runtime test — 151 files / 2317 tests, all pass
  • pnpm --filter @objectstack/plugin-sharing --filter @objectstack/plugin-security --filter @objectstack/runtime typecheck — clean
  • eslint on the 12 changed files — clean

Gates

node scripts/pm/dispatch-gates.mjs named: check:changeset-gate-self-tests,
check:cross-package-test-inputs, check:docs-audit-scope, check:objectui-changeset,
check:objectui-pin-fresh, check:route-envelope, check:test-source-alias,
check:type-source-resolution, check-changeset-no-major.mjs, check-dev-prereqs.mjs,
check-objectui-pin-fresh.mjs, plus convention-triggered check:query-options-erasure,
check:type-check-coverage/check:type-check-debt (new test files) and check:i18n
(both touched packages own an i18n-extract config). Plus check:nul-bytes per AGENTS.md.
All green except check:objectui-pin-fresh, which is pre-existing repo state
(.objectui-sha behind objectui main) unrelated to this diff — it only matched
because the gate derivation triggers on any .changeset/ path, and PR #8483 hit
the identical thing, which confirms this is repo state rather than either PR's
problem.

Watching for two ratchets that fire on what the change IS rather than which paths
moved — check:slot-lookup and check:type-check-debt — since a sibling PR in
this same sweep saw both trigger outside their derived list; if either goes red
on these new test files in CI, the fix is correcting the errors, not raising the
ledger.


Generated by Claude Code

…(part of #7620)

Twelve in-memory WHERE matchers across packages/plugins/plugin-sharing,
packages/plugins/plugin-security and packages/runtime returned early on
$or/$and, discarding every sibling equality key in the same filter object —
a real driver ANDs them. Corrected to the same conjoin-with-siblings shape
already used by packages/objectql's six (#7846) and by several
already-fixed siblings in these two packages.

Measured live-vs-dormant per file via an fs.appendFileSync probe (with a
positive control proving it would catch a live case): all twelve are
dormant today, for two different reasons. plugin-sharing's six never
receive $or/$and at all. plugin-security's five and the one runtime file
do receive them, but always as the sole key in their filter object (no
sibling ever present alongside), so early-return and conjoin produce
identical results in every observed call. No test outcome changes.

Re-grepped the issue's file enumeration at this branch's base ref rather
than trusting it: plugin-sharing/src/sharing-rule.test.ts was already
fixed, and three files this commit touches were never named in the issue
(plugin-sharing/src/sharing-service.test.ts,
plugin-security/src/check-only-write-scope.test.ts,
plugin-security/src/select-only-write-visibility.test.ts).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDTnVvsgA6cUZ4xFVtPZRy
@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 13, 2026 4:00pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

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

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants