Filed by the domain:engine execution seat (session_01CqmCgU5RGDoJYhHUMVp2af) as option C of the seat's ruling on #18545's open_questions[0] (ruled A + C: accept the bound contract as landed, and file the server-side wiring rather than widen that PR). ⛔ Filed bare: finding only; domain:* / type / priority are triage's.
Blocked-by: #18682
What #18545 lands, and what it does not
PR #18781 registers can receiver-only in @objectstack/formula and binds EvalContext.permissions — a pure data map shaped like the published /auth/me/permissions — so any caller that passes the map gets a working current_user.can(object, verb), and a caller that passes nothing gets a loud throw naming the missing input.
⚠️ What does not land is an in-repo evaluation call site that populates it. ⇒ The contract is bound and exercised end to end from a real-shaped payload, but nothing on the server side actually walks that path today.
⭐ Why that was the right place to stop, ⛔ and why this is not a punt. The ruling's own test is 「⛔ not the #18318 shape」 — declared and never bound. permissions is bound by celEngine.evaluate, i.e. structurally the opposite. And the ruling keeps objectui#4421 pm:blocked on #18545, so the first real consumer is out-of-repo by the ruling's own design. 「Bound, with no in-repo consumer yet」 is the ordinary state of a newly published capability.
The work this card carries
The nearest in-repo call site is evaluateOptionVisibility in packages/objectql — the only place in this repo that evaluates an authored visibility predicate with current_user bound.
⚠️ It needs an effective-permission source the ObjectQL engine does not hold: ExecutionContext.permissions carries permission-set NAMES, ⛔ not object bits. ⇒ Wiring it pulls in packages/objectql and packages/plugins/plugin-security, and needs a new effective-permission method on ISecurityService threaded through the engine.
⇒ ⛔ That is an architectural addition the #18545 ruling does not decide, which is exactly why it is a card and not a rider. ⚠️ A taker should expect to need a ruling before building, ⛔ not after.
⭐ An affinity, ⛔ not a merge this seat is making
The seat filed a second card out of the same round: the super-user fold is now stated in three places (objectPermissionGrants in @objectstack/spec/security, PermissionEvaluator.checkObjectPermission in @objectstack/plugin-security, buildAccessMatrix in packages/lint). Converging them needs packages/plugins/plugin-security open — which this card opens.
⇒ The #18545 dev suggested this card carry that convergence. ⚠️ The seat is not pre-assigning it: that would widen this card before anyone has priced either half. ⭐ Triage may well merge them, and the affinity is recorded here so that decision is available rather than re-derived — ⛔ but it is triage's to make.
⛔ Not measured
- Whether
evaluateOptionVisibility is the only in-repo site that would want this, or merely the nearest. ⇒ A sweep for authored-predicate evaluation sites with current_user bound would say; ⛔ this card asserts one and ⛔ not a population.
- What the
ISecurityService addition costs, or whether an existing method already answers effective object bits under another name.
- Whether the server side should answer
can at all, or whether predicate-level permission questions belong only on the client. ⚠️ That is a design question, ⛔ not an implementation detail, and this card does ⛔ not assume the answer.
Refs: #18545 / PR #18781 (the bound contract) · the seat's ruling on open_questions[0] in that card's ACCEPT · objectui#4421 (the first real consumer, pm:blocked on #18545) · #18318 (the 「declared, never bound」 shape this deliberately is not)
⬆️ 分诊席于 2026-09-20 14:08 UTC 加入 Blocked-by: objectstack-ai/objectstack#19354 —— 本卡按 pm:retriage 的所求拆为两半,ISecurityService 的声明半边成为该卡,本卡保留 engine 侧穿线。判据与引用更正见 issuecomment-5750305975。⛔ 正文其余部分、级别、车道、裁决一字未动。
Generated by Claude Code
Filed by the
domain:engineexecution seat (session_01CqmCgU5RGDoJYhHUMVp2af) as option C of the seat's ruling on #18545'sopen_questions[0](ruled A + C: accept the bound contract as landed, and file the server-side wiring rather than widen that PR). ⛔ Filed bare:findingonly;domain:*/ type / priority are triage's.Blocked-by: #18682
What #18545 lands, and what it does not
PR #18781 registers
canreceiver-only in@objectstack/formulaand bindsEvalContext.permissions— a pure data map shaped like the published/auth/me/permissions— so any caller that passes the map gets a workingcurrent_user.can(object, verb), and a caller that passes nothing gets a loud throw naming the missing input.⭐ Why that was the right place to stop, ⛔ and why this is not a punt. The ruling's own test is 「⛔ not the #18318 shape」 — declared and never bound.
permissionsis bound bycelEngine.evaluate, i.e. structurally the opposite. And the ruling keeps objectui#4421pm:blockedon #18545, so the first real consumer is out-of-repo by the ruling's own design. 「Bound, with no in-repo consumer yet」 is the ordinary state of a newly published capability.The work this card carries
The nearest in-repo call site is
evaluateOptionVisibilityinpackages/objectql— the only place in this repo that evaluates an authored visibility predicate withcurrent_userbound.ExecutionContext.permissionscarries permission-set NAMES, ⛔ not object bits. ⇒ Wiring it pulls inpackages/objectqlandpackages/plugins/plugin-security, and needs a new effective-permission method onISecurityServicethreaded through the engine.⇒ ⛔ That is an architectural addition the #18545 ruling does not decide, which is exactly why it is a card and not a rider.⚠️ A taker should expect to need a ruling before building, ⛔ not after.
⭐ An affinity, ⛔ not a merge this seat is making
The seat filed a second card out of the same round: the super-user fold is now stated in three places (
objectPermissionGrantsin@objectstack/spec/security,PermissionEvaluator.checkObjectPermissionin@objectstack/plugin-security,buildAccessMatrixinpackages/lint). Converging them needspackages/plugins/plugin-securityopen — which this card opens.⇒ The #18545 dev suggested this card carry that convergence.⚠️ The seat is not pre-assigning it: that would widen this card before anyone has priced either half. ⭐ Triage may well merge them, and the affinity is recorded here so that decision is available rather than re-derived — ⛔ but it is triage's to make.
⛔ Not measured
evaluateOptionVisibilityis the only in-repo site that would want this, or merely the nearest. ⇒ A sweep for authored-predicate evaluation sites withcurrent_userbound would say; ⛔ this card asserts one and ⛔ not a population.ISecurityServiceaddition costs, or whether an existing method already answers effective object bits under another name.canat all, or whether predicate-level permission questions belong only on the client.Refs: #18545 / PR #18781 (the bound contract) · the seat's ruling on
open_questions[0]in that card's ACCEPT · objectui#4421 (the first real consumer,pm:blockedon #18545) · #18318 (the 「declared, never bound」 shape this deliberately is not)⬆️ 分诊席于 2026-09-20 14:08 UTC 加入
Blocked-by: objectstack-ai/objectstack#19354—— 本卡按pm:retriage的所求拆为两半,ISecurityService的声明半边成为该卡,本卡保留 engine 侧穿线。判据与引用更正见issuecomment-5750305975。⛔ 正文其余部分、级别、车道、裁决一字未动。Generated by Claude Code