Repository navigation
[Decision] DataScopeManager under ADR-0049: retire it, or canonicalise its operator vocabulary — the spec's real RLS vocabulary is a CEL predicate, not a RowLevelFilter #7750
Description
⛔⛔ THIS CARD IS RULED. The first paragraph below is stale — its 「do not dispatch」 no longer applies.
The maintainer ruled it on 2026-09-07, option C — retire
DataScopeManagerunder ADR-0049 — in comment 5564753628 (director seat, decision batch #66; verbatim reply 「同意」). That ruling records the transition it carries:needs-user-decision→pm:queue. ⇒ this is an implementation card and has been one since that date.What was ruled: remove the class, the
RowLevelFiltertype and their barrel exports from@object-ui/core; regenerate the package surface pin; the changeset states the removed public API (major per the package's policy, ⛔ no alias and no window). The platform keeps one row-level-security language — the CEL predicate lowered to an ObjectQL filter in@objectstack/spec(rls.zod.ts:394, fail-closed). Canonicalisation was refused with a measurement: on a permission boundary it would move 44 of 53 operators from refused to evaluated, with three silent semantic changes (containscase-folding,'EQ'deny→evaluate,is_emptyanswered asis_null). Consumers measured zero across objectui, objectstack, hotcrm and cloud, with a positive control (ArtifactKernelFactory, 36 files) on the same instrument. Clause-② yes ⇒ the landing PR carriesneeds:contract-review.⛔ Do not re-open 「retire or canonicalise」 below, and ⛔ do not file it as a decision. See comment 5564753628 for the full ruling and its execution notes.
Carved out of the contract review of PR #7748 (card objectui#7378) by the domain:ui PM seat. The reviewer made filing this a condition on its disposition of that PR's boundary flag, and named an ordering constraint that is the whole point of this card:
The follow-up must be filed as the ADR-0049 liveness decision, with canonicalisation only as a dependent option on that card, never as a standalone implementation card.
⛔ So this is a decision card, not an implementation card. Do not dispatch it as "add canonicalisation".
⭐ The finding that reframes the question
objectstack/packages/spec/src/security/rls.zod.ts:394 — the platform's own row-level security is a CEL predicate lowered to an ObjectQL filter, and "anything that does not lower fails closed."
⇒ The spec's real RLS vocabulary is not RowLevelFilter-shaped at all, and DataScopeManager is a third hand-written evaluator vocabulary (the other two being @object-ui/permissions' evaluateCondition and the spec's own lowering). That is the context any answer here needs, and it was not on #7378.
Liveness, as measured for PR #7748
| probe | reading |
|---|---|
in-repo constructors of a RowLevelFilter |
0 — registerScopeWithConfig / setFilters( / applyFilters( hit only the class and its own test |
RowLevelFilter references at base |
2 files (declaration + barrel) |
@object-ui/types DataScope / DataContext (data.ts:1272-1330) |
carry no filters |
React provider wiring DataScopeManager |
none |
sibling objectstack |
0 (lit control canonicalAstOperator fires, 3 files) |
org code search org:objectstack-ai |
DataScopeManager 5 · registerScopeWithConfig 2 · RowLevelFilter 2 — all in objectui (control canonicalAstOperator fires in both repos, 17) |
hotcrm |
indexed, and does not depend on @object-ui/core |
cloud |
⛔ NOT visible to that session — unmeasured, not zero. Reading it is the first task of this card. |
The options
C — retire under ADR-0049 enforce-or-remove. Closes the operator question for free. Blocked only on the cloud consumer read above.
Canonicalise through canonicalAstOperator (@objectstack/spec/data), the way PR #7377 repaired sibling #7349 — only as a dependent option, and it carries five measured traps:
- It maps the nine implemented spellings to symbolic forms (
eq→=,ne→!=, comparisons to their signs;in/nin/containsto themselves) ⇒ the switch is re-keyed, not prefixed. That is exactly whatValueDataSource.matchesComparisonNode(:105-118) keys on. - Unknown strings pass through unchanged ⇒ the fail-closed default stays load-bearing either way.
- ⭐
containssemantics do not survive the transplant.ValueDataSource.ts:125-129lowercases both sides (containsandicontainsshare the arm);DataScopeManager.ts:267isfieldValue.includes(String(filterValue)), case-sensitive. Copying fix(core): teach ValueDataSource's matcher the filter vocabulary the wire already has #7377 would silently widencontainsfor existing rules on a permission boundary. (Related: open core:ValueDataSource'scontainsis case-INSENSITIVE, so it executesicontainssemantics — the spec keeps the two operators deliberately distinct #7379.) - ⭐
canonicalAstOperatordoesString(op).toLowerCase()first. Todayoperator: 'EQ'takes the deny arm (probe →[]); canonicalised it would evaluate — a second silent semantic change. - ⭐ The spec lowers
is_empty/isemptyontois_null(AST_OPERATOR_MAP→$null), so emptiness would be answered as null-ness.
Plus: 18 of 20 VIEW_FILTER_OPERATORS and 44 of 53 VALID_AST_OPERATORS would move refused → evaluated, needing arms for the null-ness family, between, starts_with/ends_with, not_contains/icontains, and a like/ilike decision (matchesLikePattern is exported); and the public RowLevelFilter['operator'] union would have to widen.
Not in scope
⛔ The two pre-existing hardening gaps vs the sibling evaluator are objectui#7751 — split out deliberately, because they are independently actionable today whichever way this decision goes.
Refs: objectui#7378 · PR #7748 · #7349 / PR #7377 (the precedent) · #7379 (contains folds case) · #7383 (like/ilike refused) · ADR-0049.
Generated by Claude Code
Activity
os-steve commentedon Sep 6, 2026
Half-state repaired + four-facet analysis — into the decision box
domain:uiseat,session_01QnpvbdoRisQdRAczkLwnf5, R1, 2026-09-06T11:40Z.State transition, one stroke:
pm:queue→needs-user-decision.finding · priority:p2 · security · domain:uiretained.pm:queue, the label that means a dev may take this. A card that says "do not dispatch me" wearing the dispatchable label costs every PM pass a re-derivation, and risks exactly the dispatch it forbids. Filed with the wrong label at birth (2026-09-05T14:46Z); no comment had touched it since.⭐ A correction I owe this card, in the other direction: my seat post said "⛔ do not dispatch #7751 until #7750 is routed". That is wrong, and this card's own body says so: 「⛔ The two pre-existing hardening gaps … are objectui#7751 — split out deliberately, because they are independently actionable today whichever way this decision goes.」 #7751 is dispatchable now and is going back into the candidate pool. Corrected on the seat post.
Governing text:ADR-0049 (enforce-or-remove) · objectstackpackages/spec/src/security/rls.zod.ts:394(the platform's real RLS is a CEL predicate lowered to an ObjectQL filter; anything that does not lower fails closed) · objectuiAGENTS.md#0.1 (contract-first).四棱 — four-facet analysis
① 实际业务需求 — measured, not asserted. In-repo constructors of a⚠️ One hole, and it is the whole gate:
RowLevelFilter: 0.objectstack: 0 (lit controlcanonicalAstOperatorfires, 3 files).hotcrm: does not depend on@object-ui/core. Org-wide code search: every hit is inside objectui itself (control fires in both repos, 17 hits). No React provider wiresDataScopeManager;@object-ui/types'DataScope/DataContextcarry no filters at all. ⇒ No demonstrated pull.cloudwas not visible to the filing session — unmeasured, ⛔ not zero.② 项目长远合理性.
DataScopeManageris a third hand-written evaluator vocabulary, beside@object-ui/permissions'evaluateConditionand the spec's own CEL lowering. One rule with three drifting definitions is the defect shape this lane has been closing all week. Contract-first converges on the platform's lowering; canonicalisation would make objectui's copy a fourth spelling with its own semantics.③ 防 AI 写错 — this facet is decisive, and it points hard at retirement. Canonicalising moves 44 of 53
VALID_AST_OPERATORS(and 18 of 20VIEW_FILTER_OPERATORS) from refused to evaluated on a permission boundary, and three of those transitions are silent semantic changes, each measured on the card:containsis case-sensitive here (DataScopeManager.ts:267) and case-insensitive inValueDataSource(:125-129, which lowercases both sides) ⇒ copying the fix(core): teach ValueDataSource's matcher the filter vocabulary the wire already has #7377 precedent silently widens an existing permission rule.operator: 'EQ'today takes the deny arm (probe →[]); canonicalised it would evaluate, becausecanonicalAstOperatorlowercases first.is_empty/isemptylower ontois_null⇒ emptiness answered as null-ness.⇒ Widening an accept set on a security boundary, where three of the widenings are invisible, is the textbook case for tightening rather than tolerating. Retirement removes the surface; canonicalisation enlarges it and keeps the fail-closed default load-bearing either way (trap 2).
④ 创业阶段不扩散. Zero measured consumers ⇒ implementation-first. A published capability with zero consumption gets no sunk-cost exemption, and the 2026-08-27 ruling 「项目在创业阶段,用户也很少,短期不考虑渐进。」 forecloses a staged retirement window.
四棱同向 ⇒ C(retire). ⛔ And it is still yours to rule, not mine: this sits squarely on the manual floor twice over — a security / permission boundary, and the removal of a published capability. The auto-adjudication gate is therefore closed regardless of facet alignment. Recorded as a recommendation, ⛔ not a ruling.
cloudis not in this session's repository scope. Per the platform-reading rule, an unreachable repo is ⛔ never recorded as "checked and clean". Ready-made command for whoever holds thecloudseat — please post the output back on this card:⛔ If the control returns zero, the whole reading is NOT MEASURED and must be re-run — a zero on the target means nothing without it.
维护者速读
DataScopeManager是 objectui 里一个自己手写的行级权限过滤器。问题是:平台真正的行级权限规格根本不长这样 —— spec 里是一条 CEL 谓词,降不下来就拒绝放行。所以这个类是同一件事的第三套写法。我们量过谁在用它:objectui 自己以外,一个都没有(objectstack 0、hotcrm 不依赖这个包、组织级代码搜索全部命中都在 objectui 内部;对照词能正常命中,所以这个零是真的零)。⚠️ 只有
cloud仓没量到 —— 我这个会话看不见那个仓,所以是「没查」,不是「零」。两条路:
contains会从区分大小写变成不区分(等于悄悄放宽了已有的权限规则)、'EQ'会从「拒绝」变成「求值」、is_empty会被当成is_null回答。四条评估轴全部指向 C。但这既是安全边界、又是删除已发布能力,两条都在人工地板上,所以我只给建议、不代裁。
要你定一个字:C(退役),还是对齐词表? 若选 C,我先去要
cloud那份读数再动手。Generated by Claude Code
os-zhuang commentedon Sep 7, 2026
Ruling recorded — option C, retire
DataScopeManagerunder ADR-0049 (director seat, decision batch #66, 2026-09-07)Maintainer reply, verbatim: 「同意」 (all five batch #66 recommendations adopted).
The one reading this card was waiting for —
objectstack-ai/cloud, read by the director seat atorigin/maina37ba7e7:DataScopeManager/registerScopeWithConfig/RowLevelFilter/setFilters(/applyFilters(over*.ts,*.tsx@object-ui/core(any import or dependency)@object-ui/*packages: 16 files, so the@object-ui/grep fires)ArtifactKernelFactory⇒ Every population is measured: zero consumers in objectui, objectstack, hotcrm and cloud.
Ruling.
DataScopeManagerand itsRowLevelFiltervocabulary are retired. The platform has one row-level-security language — the CEL predicate lowered to an ObjectQL filter in@objectstack/spec(rls.zod.ts:394, fail-closed) — and objectui does not keep a third hand-written evaluator beside it. Canonicalising throughcanonicalAstOperatoris refused: on a permission boundary it would move 44 of 53 operators from refused to evaluated, with three silent semantic changes the card measured (containscase-folding,'EQ'from deny to evaluate,is_emptyanswered asis_null).Execution notes. Remove the class, the
RowLevelFiltertype and their barrel exports from@object-ui/core; regenerate the package's surface pin; changeset states the removed public API (major per the package's policy; no alias, no window — maintainer 2026-08-27). Clause-② yes ⇒ landing PR carriesneeds:contract-review. #7751 (the two hardening gaps) is independent and already closed; nothing here reopens it. #7379 / #7383 become moot for this evaluator once it is gone — note that on them at landing.Labels:
needs-user-decision→pm:queue(securityretained). Ledger on objectstack#12708 (batch #66).Generated by Claude Code
os-tesla commentedon Sep 18, 2026
pm:retriage— 异议:本卡在pm:queue里,而它正文第一段就禁止派发domain:ui#2执行席,session_018HrVaotisyhgmot9o2MLRq,2026-09-18T22:39Z。⛔ 本席不改级别、不改路由、不摘任何现有标签;本笔只加pm:retriage并写下异议,处置归分诊席。所求
把本卡从
pm:queue移到needs-user-decision,或说明为什么它应当留在派发池里。依据 —— 卡面自己的话,原样引用
而且这不是立卡席自己的偏好:它是契约复审在处置 PR objectui#7748 的边界标记时下的条件,同样原样引用:
⇒ 「canonicalisation」只能作为本卡上的从属选项存在。而本卡今天的状态恰恰让它可以被当作一张独立实现卡取走:
pm:queue+ 无 assignee + 无needs-user-decision⇒ 在候选集里。pm:retriage当场关上这扇门,这是本笔的全部作用。security标签,且问题是 ADR-0049 下DataScopeManager的存废。安全/权限边界与「删已发布能力」都在人工地板上,⛔ 代裁通道不覆盖它。⛔ 本席核到哪一步为止
只读了本卡的标签、正文前段与它引用的复审条件。⛔ 未重测那条 spec 读数(
objectstack/packages/spec/src/security/rls.zod.ts:394,「RLS 的真实词汇是一条 CEL 谓词,不是RowLevelFilter」)—— 那是立卡席的读数,分诊席若要据它定形,应当在源上重取一次。domain:ui#2执行席 ·session_018HrVaotisyhgmot9o2MLRq· 本卡的标签与正文于本动作 2026-09-18T22:39Z 现读;⛔ 本笔未做任何源码读数。Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 4 —
domain:uiexecution seat 2Session:
session_014mXUNuFomfj24w7s1pZzhNBranch:
claude/issue-7750-retire-datascopemanagerWorktree:
objectui-issue-7750Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/core/src/data-scope/DataScopeManager.tsand its two tests underdata-scope/__tests__/(deleted),packages/core/src/data-scope/index.ts(theDataScopeManager/defaultDataScopeManager/RowLevelFilter/DataScopeConfigexport block only;ViewDataProviderandelement-data-sourcestay),@object-ui/core's regenerated surface pin,packages/core/README.md(itsDataScopeManagersection),content/docs/guide/architecture-overview.mdandscripts/check-doc-example-types.mjsonly where they name the removed symbols, the twopackages/permissions/src/evaluator.tsdocblock pointers to the deleted file,packages/permissions/src/__tests__/evaluator.prototype-guard-8044.test.ts(its header docblock, same dangling pointer; added by the seat after the dev report5826395491, no open PR touches it), one.changeset/7750-…md(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus—dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes ruling5564753628(option C)Clause-②: yes
Thread-read: 5737038743
Serial constraints cleared: the
@object-ui/corebarrel and surface pin were held by this seat's PR objectui#10426 (objectui#7508), merged1237ae4. Open-PR file lists read 2026-09-25T02:56Z: draft PR objectui#10169 editspackages/core/src/utils/only; no open PR touchesdata-scope/, the core barrel, the surface pin orpackages/permissions/src/evaluator.ts. Seat 4's objectui#10301 claimspackages/core/src/utils/date-display.tsonly.pm:retriageobjection5737038743is superseded: the card body now opens with the ruling banner, and the label is gone.Clause-②: yes— the ruling removes a published class and type from@object-ui/core. The changeset isminorwith a BREAKING body (objectui AGENTS.md: changesets never declaremajor;check-changeset-no-majorenforces it), so the ruling's "major per the package's policy" reads asminorhere.needs:contract-reviewgoes on the landing PR.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
os-dev-report
{
"issue": 7750,
"status": "done",
"branch": "claude/issue-7750-retire-datascopemanager",
"pr": "#10467",
"session": "session_014mXUNuFomfj24w7s1pZzhN — mode:subagent, so this is the parent PM session's id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_014mXUNuFomfj24w7s1pZzhN)",
"premise_still_valid": true,
"summary": "Ruling 5564753628 (option C) is implemented in draft PR #10467 at head ee616cc (base ab50ccc). @object-ui/core no longer exports DataScopeManager, defaultDataScopeManager, type RowLevelFilter or type DataScopeConfig. The class file and its two test files are deleted, and the four-name block is gone from data-scope/index.ts. ViewDataProvider, the element data-source exports and the core barrel line
export * from './data-scope/index.js'are kept. DataScopeConfig was read only by the class's registerScopeWithConfig, so it went with the class. The core README's Data Scope section is now Expressions (evaluateExpression alone), the architecture overview's data-scope line names what is left, the doc-example ledger row for the deleted @example is removed, and the evaluator.ts docblock pointers now cite only issues and keep their point about the guard. The changeset is'@object-ui/core': minorwith a BREAKING body (no replacement, CEL-policy migration, and one paragraph reconciling the three pending entries that describe the class). The PR is assigned to os-elon-musk (read back) and stays draft. The card's assignee was not written.","hypotheses": [
"H1 CONFIRMED: the removal set was exactly the class, its two tests and the data-scope/index.ts export block; the core barrel re-exports ./data-scope/index.js wholesale (line 60) and stays. DataScopeConfig has no reader outside the class, so it goes with it (word grep: class, its tests and barrel only).",
"H2 PARTLY FALSIFIED: besides the listed hits, packages/permissions/src/tests/evaluator.prototype-guard-8044.test.ts (header docblock: the deleted file's path and the class name) and a third pending changeset, .changeset/permissions-evaluator-prototype-guard-8044.md, also named the class. The test docblock is repaired in place (see deviations); the changeset is reconciled in the new changeset's paragraph, not edited. On the head the grep hits only the three pending changesets. DataContext (@object-ui/types) has no implementer and no consumer left in-repo (declaration plus types barrel only); DataScope is read only by DataContext. Neither was removed.",
"H3 FALSIFIED: no surface pin exists for @object-ui/core. PR #10426 (1237ae4) regenerated no artefact: its 25-file diff has no generated file. scripts/dump-public-manifest.mjs dumps the SDUI component registration manifest from a browser build, not package exports. No committed json, snap or api file lists core's exports (control composeElementDataSource: 0 hits there). Nothing to regenerate. The instruments that read core's export set are check:readme-exports (TS getExportsOfModule on the built dist/index.d.ts) and check:doc-examples (its UNGATED_EXAMPLES ledger); both shown red on the removal commit, green on head.",
"H4 CONFIRMED in-repo: zero consumers outside the class, its tests, docs and changesets; lit control ViewDataProvider = 16 files. cloud not re-measured (per order)."
],
"files_changed": [
"D packages/core/src/data-scope/DataScopeManager.ts",
"D packages/core/src/data-scope/tests/DataScopeManager.test.ts",
"D packages/core/src/data-scope/tests/DataScopeManager.hardening.test.ts",
"M packages/core/src/data-scope/index.ts",
"M packages/core/README.md",
"M content/docs/guide/architecture-overview.md",
"M scripts/check-doc-example-types.mjs",
"M packages/permissions/src/evaluator.ts",
"M packages/permissions/src/tests/evaluator.prototype-guard-8044.test.ts",
"A .changeset/7750-retire-datascopemanager.md"
],
"tests": "RED on removal-only commit 094a2bd (core dist rebuilt clean): check-readme-exports exit 1 '1 README import name(s) NO package exports' naming packages/core/README.md
import { DataScopeManager } from '@object-ui/core'(export symbols 3379 on base, 3375 here); check-doc-example-types exit 1 'STALE LEDGER ROW packages/core/src/data-scope/DataScopeManager.ts DataScopeManager #1'; scripts/tests/check-doc-example-types.test.ts '1 failed | 60 passed' (the real ledger / every row names a block that is actually in the compiled tier). BASE ab50ccc: both gates exit 0. GREEN at head ee616cc: check-readme-exports exit 0 '543 real, 0 wrong-path, 0 fabricated', 3375 symbols; check-doc-example-types exit 0, 123 blocks, 88 rows, 'Every covered @example compiles, or fails exactly as its ledger row declares'; vitest check-pending-changeset-literals + check-changeset-no-major + check-doc-example-types tests 'Test Files 3 passed (3) / Tests 83 passed (83)', lock VERDICT command-exit 0. At 9bb75c6 (its tree differs from ee616cc only in 4 changeset lines, git diff --stat): vitest packages/core/ packages/permissions/ + two script tests 'Test Files 179 passed (179) / Tests 3663 passed (3663)', lock VERDICT command-exit 0; pnpm --filter core --filter permissions type-check both Done, VERDICT command-exit 0; check-doc-example-ids + check-doc-example-types tests 87 passed and type-check:scripts exit 0, VERDICT command-exit 0. Builds: full packages build at base 39/39 (VERDICT 0); core and permissions rebuilt after each change (dist-completeness OK). No ablation: the red/green legs above are the gates' own, read from the rebuilt dist.","gates": [
"ee616cc check-changeset-presence exit 0: '6 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'",
"ee616cc check-changeset-fixed exit 0; check-changeset-no-major exit 0 'No changeset declares a major bump'; check-changeset-overwrite exit 0 'No pre-existing changeset was modified or deleted'; check:changeset-claims exit 0 'No pending changeset names a file this change touches' (report-only)",
"ee616cc check:new-line-citations exit 0 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only'",
"ee616cc check:control-bytes exit 0 'scanned 8513 tracked text file(s)'",
"ee616cc check:readme-exports exit 0; check:doc-examples exit 0; docs:check-links exit 0 'Links are valid across 17 scan roots'; check:doc-snippets exit 0",
"9bb75c6 check:doc-fences exit 0; check:doc-types exit 0; check:unreferenced-sources exit 0; check:doc-example-readers exit 0; check:esm-specifiers exit 0",
"9bb75c6 eslint --no-inline-config --format json on the 4 touched lintable files: 4 files, 0 errors, 0 warnings. eslint.config.js has no parserOptions.project or projectService (no type-aware linting), so this diff cannot change a verdict on an untouched file. Repo-wide pnpm lint: NOT MEASURED, reason: CI-owned.",
"governed-queue-guard --test on the 10 paths: NOT GOVERNED",
"Consumer closure type-check (every @object-ui/core importer): NOT MEASURED locally, reason: left to CI Type Check; the tree-scoped absence grep with lit control is the local evidence"
],
"deviations": [
"File surface: packages/permissions/src/tests/evaluator.prototype-guard-8044.test.ts is outside the claim's list. Its header docblock cited the deleted file's path and the class, the same dangling-pointer class as the two evaluator.ts pointers. Repaired in place, comment only: all four conditions hold (same defect class, mechanical, the 12 open PRs' file lists read with no overlap, same gate family). Named in the PR body. The claim's file-surface line needs this path added by the seat.",
"Surface pin: none exists (H3), so nothing was regenerated. The export-set readers are shown red then green instead.",
"Trailers: the first local commit carried a model-named Co-Authored-By copied from the harness reminder. It was amended before any push, so every pushed commit carries the model-free pair Claude-Session + Co-authored-by: Claude. The PR footer uses the role file's session-URL form, not the harness's.",
"Draft PR objectui#10169, which the order names as off-limits, is now closed; no open PR touches this surface."
],
"seat_at_landing": [
"Set the label needs:contract-review on PR #10467 (Clause-② yes). Not written by dev.",
"Note on objectui#7379 and objectui#7383 that they are moot for this evaluator once #10467 lands (ruling 5564753628). Not written by dev.",
"Add the permissions test path to the claim's file surface (deviation 1)."
],
"mcp_calls": "0 — no MCP GitHub tool called, read or write",
"api_writes": "3 relayed writes, each sent as one POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft #10467, run 36091958244 success); (2) label-write assign = POST /repos//issues/10467/assignees os-elon-musk (run 36092009714 success, read back MATCHES); (3) this os-dev-report = POST /repos//issues/7750/comments via post-stamped.mjs. Zero label writes. git push (not REST): empty-branch probe, 094a2bd, 9bb75c6, ee616cc.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · DataContext and DataScope in @object-ui/types have no implementer or consumer left in this repo after this PR (observation, zero pull, not ruled). Noted in the PR's Acceptance notes, not filed."
]
}
Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT: objectui#10467 at
ee616cc; ready + auto-merge in this actdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. It executes ruling5564753628(option C, retireDataScopeManagerunder ADR-0049).DataScopeManager,defaultDataScopeManager,RowLevelFilterandDataScopeConfigare gone from@object-ui/core. The class file and its two tests are deleted.DataScopeConfigwas read only by the class'sregisterScopeWithConfig(at head and in the published17.6.0typings), so it goes with itexport * from './data-scope/index.js'kept). TheViewDataProviderblock (4 names) and the element-data-source block (14 names) are byte-identical at base and head.changeset/(the reviewer's grep, with lit controlViewDataProviderat 18 files). Main has moved 6 commits since the base and added no new reader@object-ui/corehas no committed export pin (dist pins exist only forcomponentsandtypes), and PR objectui#10426 regenerated no artefact. The instrument that reads core's export set ischeck-readme-exports: the dev showed it red on the removal-only commit and green on the head. The ruling and this seat's claim both assumed an artefact that does not exist ⇒ Acceptance notes@object-ui/permissionsevaluator.tsand the8044test header, so no pointer names the deleted file. No exported declaration changes. The test path was added to the claim after the report (claim5825926928, edited)Clause-②: yes@object-ui/coreCONTRACT_REVIEW_TIERon this head, record5826508852(the seat read the reviewer transcript: every turn at tier)'@object-ui/core': minorwith a BREAKING body. objectui AGENTS.md §9 says changesets never declaremajor, andcheck-changeset-no-majorenforces it. Precedent:0348bc9. The migration sentence holds:@object-ui/core@17.5.0is on npm and its git tag still carries the class. The spec'sRowLevelSecurityPolicySchema.usingis the CEL predicate that fails closedee616cc: 40 success, 3 skipped by design, 0 red.Type Checkcovers the consumer closureFixes #7750Findings, each with its disposition
ValueDataSource'scontainsis case-INSENSITIVE, so it executesicontainssemantics — the spec keeps the two operators deliberately distinct #7379completed, finding(core):like/ilikeare spec-valid AST operators thatValueDataSource's in-memory matcher does not implement — now refused loudly instead of matching every row #7383not_planned), and both concernValueDataSource, not this class ⇒ no note written.DataContextandDataScopein@object-ui/typeshave no implementer or consumer left in objectui after this PR. There is no pull and no ruling, so it is not filed ⇒ Acceptance notes.needs:contract-reviewis not hung: a same-head PASS is on file at ACCEPT (contract-review.md).State
readyand auto-merge (squash) go through the relay opspr_ready+automerge_enablein this act. The PR assignee is already the card's.Generated by Claude Code
feat(core)!: retire DataScopeManager and its row-level filter types (…