Repository navigation
Commit 49a6a5c
test(plugin-sharing): seam ObjectQL double holds the caller limit (#28670)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"}
-->
_Requested by **Leehom** · [project
thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1XE31U2cwvwmv9HjQt5Dax7Z)_
Fixes #28608
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:plugin-sharing 测试用的内存 ObjectQL 替身(`makeSeamQl().find`)现在会遵守调用方传入的
`limit`,先按 `where` 过滤、再按 `limit` 截断。
- 为什么改:真实引擎会遵守 `limit`,`resolveAuthzContext` 读这个替身时也确实传了
`limit`(如选默认组织时的 1 和 2);替身丢掉它,测试看到的行比运行时多,可能在运行时不会出现的结果上变绿。
- 风险与回滚:只改测试文件,`dist` 不含这个 testkit,不发版;回滚即 revert 本 PR。
-
先看:`packages/plugins/plugin-sharing/src/exec-context-seam.testkit.ts`(`find`
的 return
一行),`packages/plugins/plugin-sharing/src/exec-context-seam.limit.test.ts`。
- 两分钟验证:`pnpm --filter @objectstack/plugin-sharing exec vitest run
src/exec-context-seam.limit.test.ts`,预期 3 passed。
- 需要你做的:无,席位落地。
## What changes
- `makeSeamQl().find` in `exec-context-seam.testkit.ts` now applies the
caller's bound after the `where` filter, by presence: `typeof
opts?.limit === 'number' ? matched.slice(0, opts.limit) : matched`. That
is the first of the two shapes `scripts/check-objectql-double-limit.mjs`
prescribes for a compliant double. It was picked over "throw on a bound
it does not implement" because `resolveAuthzContext` really does read
through this double with bounds (`limit: 1`, `limit: 2`, `limit: 200`
and others), so a throwing double would break every importer. `where`
handling is unchanged.
- `makeSeamQl` is now exported, only so its own pin can drive it
directly.
- New pin `exec-context-seam.limit.test.ts`: `limit: 1` over two
matching rows answers one row; the bound applies after the filter, not
before it; no `limit` answers every match.
## Why
The double silently dropped `limit`, so a test running through the seam
could see more rows than the real engine would hand the resolver. Card
#28608 question 1 (triage record 6557807357). Question 2 (widening the
two double gates to walk `*.testkit.ts`) is graded out and not touched:
neither gate script is edited.
## Tests
- Red first (export applied, fix not yet applied): `answers at most
limit rows when more match` fails, `expected [ Array(2) ] to deeply
equal [ { id: 'a', …(1) } ]`, Tests 1 failed, 2 passed (3).
- Green on the fix: Tests 3 passed (3).
- Ablation through `scripts/ablation-replace.mjs`: the limit line
replaced by `return matched;` (anchor x1 to x0, blob d27c845 to
17d1ac7833f6), the same case reds (1 failed, 2 passed), then restored:
blob after restore equals the HEAD blob d27c845 and `git diff HEAD`
is empty. The testkit is source imported relatively by the test, so no
dist leg applies.
- Whole `@objectstack/plugin-sharing` suite on head e410091: Test Files
59 passed (59), Tests 1299 passed (1299). The three test files that
import the seam (`sharing-service.test.ts`,
`share-link-enforcement-context.test.ts`,
`share-link-tenancy-posture-admission.test.ts`, plus the type-only
import in `exec-context-annotation.pin.ts`) pass unchanged.
- `pnpm --filter @objectstack/plugin-sharing typecheck`: exit 0 (test
layer compiles, debt held). `eslint --no-inline-config
packages/plugins/plugin-sharing`: exit 0.
## Acceptance notes
- Gate-walk probe the card cites, re-run read-only:
`check-objectql-double-limit.mjs` copied with its `testFilesUnder` regex
widened to `(test|testkit).ts`, never committed and deleted after. On
head: `OK ObjectQL double limit conformance holds: 643 double(s)
graded`, no plugin-sharing row. On the base testkit blob, same probe:
`exec-context-seam.testkit.ts ... (1 blind ...) line 58: BLIND`, exit 1.
Restore proven by blob equality and an empty `git diff HEAD`.
- `skip-changeset`: plugin-sharing's `files[]` is `dist`, `README.md`,
`CHANGELOG.md`. After a build, `makeSeamQl` and `bootRequestContext`
have 0 hits there, while the positive control `SharingService` has 4
files in `dist`.
## Verification
Local subset on head e410091 (`node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack`, 52 derived families),
each exit captured before any pipe; reconciled with `--ran`: `52 derived
famil(ies) accounted for — 51 run, 1 NOT-MEASURED`.
- 51 families exit 0, including `check:objectql-double-limit`,
`check:engine-double-contract`, `check:where-matcher`,
`check:query-options-erasure`, `check:test-source-alias`,
`check:type-check-debt`, `check:published-files` and `check:nul-bytes`.
- `check-plugin-teardown-shape.mjs --self-test`: exit 3 on the shallow
clone first, exit 0 after fetching its pinned fixture commit.
- `check:i18n`: exit 3 (CLI not built) first, exit 0 after its
one-command prerequisite build (`all bundles in sync`).
- NOT MEASURED: `check:dual-build-cjs-loads`, exit 3 PREREQUISITE NOT
MET (needs every package dist in this fresh worktree); CI runs it.
- Full dogfood not run: no `!` in the title and no `(narrowing)` arm.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes (scoped to
plugin-sharing).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset. (nothing
publishes: `skip-changeset`)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (not touched)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English. (the maintainer brief
above is Chinese by the dispatch contract)
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01FEkQ5kA7pasGpR4Pf7mtNb
---
_Generated by [Claude
Code](https://claude.ai/code/session_01FEkQ5kA7pasGpR4Pf7mtNb)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1404938 commit 49a6a5c
2 files changed
Lines changed: 49 additions & 3 deletions
File tree
- packages/plugins/plugin-sharing/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
56 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
57 | 60 | | |
58 | 61 | | |
59 | 62 | | |
60 | 63 | | |
61 | | - | |
| 64 | + | |
62 | 65 | | |
63 | 66 | | |
64 | 67 | | |
65 | 68 | | |
66 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
67 | 73 | | |
68 | 74 | | |
69 | 75 | | |
| |||
0 commit comments