You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
spec+security: reserve the queues RLS membership key and resolve current_user.queues kernel-side from the ownership-queue service #27016
Filing gate: class ③, maintainer-directed. Child of #25769, filed under ruling 6457475657 (batch #415 item 5, letter A, maintainer 「同意」 2026-10-28T00:36Z), which says "the next spec seat files the child". Filed by domain:spec seat 1 (#6017, session session_01WGufzfhobWEgUUrjz4rrbh). ⛔ Not a claim.
What the ruling decides
queues joins RESERVED_RLS_MEMBERSHIP_KEYS. plugin-security resolves it from the ownership-queue service into current_user.queues the same way it resolves positions, so there is one kernel-side producer. An app IRlsMembershipResolver that supplies queues is screened out and fails closed. Option B (plugin-sharing's own resolver) and option C (an ADR-0142 amendment that drops the key) were not chosen.
Measured on origin/main7eb613c3
packages/spec/src/contracts/rls-membership-resolver.ts:89: RESERVED_RLS_MEMBERSHIP_KEYS = id, organization_id, positions, org_user_ids, accessible_org_ids, email. queues is not reserved.
The ownership-queue runtime landed with feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 (packages/objectql/src/ownership-queue.test.ts, assignment-rules.ts). No RLS policy reads current_user.queues yet, because the D3 access path goes through the sharing owner match.
What lands (one PR, size S)
spec: queues added to RESERVED_RLS_MEMBERSHIP_KEYS, with its doc comment and the published-list pins that count the keys.
plugin-security: populate current_user.queues (the ids of the queues the user is a member of, directly or through a position or team, as the ownership-queue membership defines) next to positions. The value comes from one producer, and the screen drops an app resolver's queues.
Tests: the kernel value appears for a member and is empty for a non-member, and an app resolver that returns queues is screened out with the existing fail-closed outcome.
Clause-②: yes (widening). A reserved key is added to a published list. The ruling declares this arm; no accept set an author writes narrows.
Metadata-protocol: none
Out of scope (the rest of the ADR-0142 execution plan on #25769): the HotCRM stopgap deletion, the Console queue picker and Claim affordance, and the authoring guide. The skills docs are #26475.
Dedupe: #25769's comments and open issues mentioning "RESERVED_RLS_MEMBERSHIP_KEYS queues" or "current_user.queues". None found.
Claim: PM loop round 1 · 2026-10-28T01:33Z
Session: session_01WGufzfhobWEgUUrjz4rrbh
Account: os-support-ai
Branch: claude/project-thread-1d234m (card thread session_01WGufzhD6Fqfyavauv2KoGA. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead of claude/issue-27016-<slug>.)
Worktree: objectstack-issue-27016
Domain: domain:spec
Seat: domain:spec#1
File surface:
packages/spec/src/contracts/rls-membership-resolver.ts: queues is added to RESERVED_RLS_MEMBERSHIP_KEYS, with its doc comment. The pins that count the list move.
packages/plugins/plugin-security/src/**: current_user.queues is resolved next to positions, from the ownership-queue membership feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 landed. There is one kernel-side producer, and the existing screen drops an app resolver's queues and fails closed. Tests cover a member, a non-member, and a screened app resolver.
Any skills or docs page that lists the reserved keys.
This amends claim 6458269562, which declared "yes (widening)". The ruling left the arm to the lane, and the dev measured a narrowing. RESERVED_RLS_MEMBERSHIP_KEYS is also read by MembershipKeyNameSchema (packages/spec/src/security/rls.zod.ts:780, the key-name refine on ObjectSchema.membershipKeys). Reserving queues therefore refuses an authored membershipKeys: { queues: … } at parse. The in-repo census on 7eb613c3 found zero such declarations.
Clause-②: no (narrowing). An authored membership key named queues is refused; the kernel resolves that name.
Metadata-protocol: narrowed
The changeset carries a BREAKING banner and the ADR-0087 marker not-required (no-migration-prescription). The new key name is the author's choice, so there is no mechanical rewrite, and the changeset gives a **The remedy.** line instead. The file surface is unchanged.
{
"issue": 27016,
"status": "done",
"branch": "claude/project-thread-1d234m",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27044",
"session": "session_01WGufzhD6Fqfyavauv2KoGA",
"premise_still_valid": true,
"summary": "Head 8660c53ef, off origin/main 7eb613c3 (premise reproduced there: RESERVED_RLS_MEMBERSHIP_KEYS lacked queues; plugin-security had no current_user.queues producer). Ruling 6457475657 (A) applied: queues joins RESERVED_RLS_MEMBERSHIP_KEYS with its doc comment. plugin-security resolves current_user.queues from ownership-queue queuesOf (same specsReachUser/access answer as the claim gate's isMember), new kernel-queue-membership.ts: once per request, only when a policy about to compile reads the key, stored under a module-private symbol keyed to the principal and organization (context.queues never read; a copied context for another user/org does not carry it). RLSCompiler.userContextOf sets queues beside positions. Existing screens (resolver screen, compiler merge) drop an app's queues by name and fail closed. Declaration per seat 1's ruling: Clause-② no (narrowing), Metadata-protocol narrowed (MembershipKeyNameSchema reads the list, so membershipKeys.queues is refused), ADR-0087 not-required (no-migration-prescription), **The remedy.** line; census 0 declarations/resolvers. Changeset minor for spec, plugin-security, lint, skills. Pins moved: plugin-security CELLS, lint KERNEL_KEY_RUNTIME_TYPE and three os explain texts plus the engine-judge copy; the unknown-variable fix line reworded (Read a kernel key) to stay at or under 200. skills/objectstack-data/rules/security.md reserved-name line gains queues, paid by a deletion in the same file. Reference docs regenerated (gen:docs, 4 files). PR body: /mnt/project-files/issue-27016/pr-body.md.",
"tests": "Under the lock on 7f4c13eb/8660c53ef: spec 738 files / 22131 passed (1 todo); plugin-sharing 57 / 1279; lint 170 / 7510; plugin-security 234 / 5065 passed, 45 skipped; typecheck of the four packages exit 0. New: kernel-queue-membership.test.ts 12 cases (member, other org, non-member deny = no-service bytes, isMember agreement, once per request and lazy, no user / throwing service fail closed, app resolver queues screened with WARN, no-service gap, forged context field, copied context); queues cell in rls-reserved-membership-keys.test.ts; plugin-sharing queuesOf-agrees-with-isMember pin (non-vacuous). Ablation: compiler line queues: undefined gives 5 failed; queues removed from built spec list gives 4 failed; both restored.",
"gates": "dispatch-gates --commands on 38a151a1: 115 commands; 111 exit 0; check-skills-token-ratchet red (+3) then exit 0 after the paying deletion; check:skill-examples, check:dual-build-cjs-loads, check:i18n exit 3 then 0 after the dogfood closure build. check:generated: references stale, regenerated. CI on the PR: not yet read at report time.",
"dogfood_battery": "8660c53ef · os-verify-lock VERDICT command-exit 1 · Test Files 1 failed / 344 passed / 3 skipped (348) · Tests 2 failed / 2788 passed / 20 skipped (2810) · both failures packaged-action-disabled-dispatch-live.dogfood.test.ts (acceptance[0], [5]/[2]), reproduce alone (2 failed / 6 passed); not this diff: the test reads the first showcase_task unsorted and that row was already done before the action; no stack reads current_user.queues",
"mcp_calls": "5: issue_read x4 (27016 get, get_comments; 26954 get_comments), 0 writes",
"api_writes": "3 via the relay: pr_create (#27044, 10714 bytes read back identical, assignee os-support-ai), pr_request_reviewers, and this os-dev-report comment",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: dogfood suite only · packaged-action-disabled-dispatch-live.dogfood.test.ts picks GET /data/showcase_task?$top=1 with no sort and asserts its done is false after the refused action; on this box the first row was already done, so acceptance[0] and [5]/[2] fail even when the file runs alone · dedupe: packaged-action-disabled-dispatch-live first task done · carrier: seat 1 to file or route",
"boundary: current_user.queues inside a field permission `when` resolves only if a row policy on the same request staged it first (compileRowPredicate does not stage); unresolved fails closed (the entry locks), same as resolver keys today · carrier: none"
]
}
PR #27044 merged at e3470ed9 through the queue, under os-zhuang's Tier H approval. The merge commit is an ancestor of origin/main. On all 23 paths the PR touched, the merge tree matches the accepted head e3749743 byte for byte.
queues is now a reserved RLS membership key. plugin-security resolves current_user.queues kernel-side from the ownership-queue service (queuesOf, the same answer the claim gate's isMember reads). It is resolved once per request and bound to the user and organization, and it fails closed when the service is absent or errors. An app IRlsMembershipResolver that answers queues is screened out, and an authored membershipKeys.queues is refused at parse. ADR-0142 D3 is amended to ruling 6457475657 (letter A).
@objectstack/spec, plugin-security, lint and skills are minor, with a BREAKING banner and ADR-0087 not-required (no-migration-prescription). Clause-②: no (narrowing) and Metadata-protocol: narrowed. The card closed through Fixes #27016, and this seat removes pm:dispatched. The triage seat's delta review raised two ADR-only should-fixes (the Status-line Amended marker and the Execution plan item 1 annotation). They follow in PR #27096 (Part of #27016, skip-changeset, Tier H).
PR #27096 merged at a305b94e under os-zhuang's Tier H approval. ADR-0142 Status line now carries the Amended marker for ruling 6457475657, and Execution plan item 1 is annotated as superseded by the amended D3. Nothing is left on #27016.
Activity
objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 1 · 2026-10-28T01:33Z
Session:
session_01WGufzfhobWEgUUrjz4rrbhAccount:
os-support-aiBranch:
claude/project-thread-1d234m(card threadsession_01WGufzhD6Fqfyavauv2KoGA. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead ofclaude/issue-27016-<slug>.)Worktree:
objectstack-issue-27016Domain:
domain:specSeat:
domain:spec#1File surface:
packages/spec/src/contracts/rls-membership-resolver.ts:queuesis added toRESERVED_RLS_MEMBERSHIP_KEYS, with its doc comment. The pins that count the list move.packages/plugins/plugin-security/src/**:current_user.queuesis resolved next topositions, from the ownership-queue membership feat!: ownership queues and assignment rules (ADR-0142 phase 2) #26337 landed. There is one kernel-side producer, and the existing screen drops an app resolver'squeuesand fails closed. Tests cover a member, a non-member, and a screened app resolver..changesetentries.Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: highClause-②: yes (widening). A reserved key is added to a published list, which is the arm the ruling declares.
Metadata-protocol: none
Responsibility: n/a. A maintainer-directed child of spec+server: an ownership queue primitive (queue entity, membership, claim) and declarative assignment rules, so an app routes ownerless records without app-level round-robin (maintainer ruling D6 = A) #25769.
Thread-read: none
Premise: held at
origin/main7eb613c3, as measured by the dev.queuesis not reserved, and plugin-security has nocurrent_user.queuesproducer. The only queue reads are the authz middleware's ownership-queue gate (ownershipQueues().isMember).Serial constraints cleared: yes. No other card in hand edits
rls-membership-resolver.tsor plugin-security's membership resolution.Ruling-ref: 6457475657 (on spec+server: an ownership queue primitive (queue entity, membership, claim) and declarative assignment rules, so an app routes ownerless records without app-level round-robin (maintainer ruling D6 = A) #25769, letter A)
objectstack-fleet commentedon Oct 28, 2026
Claim amendment ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-28T01:35ZThis amends claim
6458269562, which declared "yes (widening)". The ruling left the arm to the lane, and the dev measured a narrowing.RESERVED_RLS_MEMBERSHIP_KEYSis also read byMembershipKeyNameSchema(packages/spec/src/security/rls.zod.ts:780, the key-name refine onObjectSchema.membershipKeys). Reservingqueuestherefore refuses an authoredmembershipKeys: { queues: … }at parse. The in-repo census on7eb613c3found zero such declarations.Clause-②: no (narrowing). An authored membership key named
queuesis refused; the kernel resolves that name.Metadata-protocol: narrowed
The changeset carries a BREAKING banner and the ADR-0087 marker
not-required (no-migration-prescription). The new key name is the author's choice, so there is no mechanical rewrite, and the changeset gives a**The remedy.**line instead. The file surface is unchanged.objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 27016, "status": "done", "branch": "claude/project-thread-1d234m", "pr": "https://github.com/objectstack-ai/objectstack/pull/27044", "session": "session_01WGufzhD6Fqfyavauv2KoGA", "premise_still_valid": true, "summary": "Head 8660c53ef, off origin/main 7eb613c3 (premise reproduced there: RESERVED_RLS_MEMBERSHIP_KEYS lacked queues; plugin-security had no current_user.queues producer). Ruling 6457475657 (A) applied: queues joins RESERVED_RLS_MEMBERSHIP_KEYS with its doc comment. plugin-security resolves current_user.queues from ownership-queue queuesOf (same specsReachUser/access answer as the claim gate's isMember), new kernel-queue-membership.ts: once per request, only when a policy about to compile reads the key, stored under a module-private symbol keyed to the principal and organization (context.queues never read; a copied context for another user/org does not carry it). RLSCompiler.userContextOf sets queues beside positions. Existing screens (resolver screen, compiler merge) drop an app's queues by name and fail closed. Declaration per seat 1's ruling: Clause-② no (narrowing), Metadata-protocol narrowed (MembershipKeyNameSchema reads the list, so membershipKeys.queues is refused), ADR-0087 not-required (no-migration-prescription), **The remedy.** line; census 0 declarations/resolvers. Changeset minor for spec, plugin-security, lint, skills. Pins moved: plugin-security CELLS, lint KERNEL_KEY_RUNTIME_TYPE and three os explain texts plus the engine-judge copy; the unknown-variable fix line reworded (Read a kernel key) to stay at or under 200. skills/objectstack-data/rules/security.md reserved-name line gains queues, paid by a deletion in the same file. Reference docs regenerated (gen:docs, 4 files). PR body: /mnt/project-files/issue-27016/pr-body.md.", "tests": "Under the lock on 7f4c13eb/8660c53ef: spec 738 files / 22131 passed (1 todo); plugin-sharing 57 / 1279; lint 170 / 7510; plugin-security 234 / 5065 passed, 45 skipped; typecheck of the four packages exit 0. New: kernel-queue-membership.test.ts 12 cases (member, other org, non-member deny = no-service bytes, isMember agreement, once per request and lazy, no user / throwing service fail closed, app resolver queues screened with WARN, no-service gap, forged context field, copied context); queues cell in rls-reserved-membership-keys.test.ts; plugin-sharing queuesOf-agrees-with-isMember pin (non-vacuous). Ablation: compiler line queues: undefined gives 5 failed; queues removed from built spec list gives 4 failed; both restored.", "gates": "dispatch-gates --commands on 38a151a1: 115 commands; 111 exit 0; check-skills-token-ratchet red (+3) then exit 0 after the paying deletion; check:skill-examples, check:dual-build-cjs-loads, check:i18n exit 3 then 0 after the dogfood closure build. check:generated: references stale, regenerated. CI on the PR: not yet read at report time.", "dogfood_battery": "8660c53ef · os-verify-lock VERDICT command-exit 1 · Test Files 1 failed / 344 passed / 3 skipped (348) · Tests 2 failed / 2788 passed / 20 skipped (2810) · both failures packaged-action-disabled-dispatch-live.dogfood.test.ts (acceptance[0], [5]/[2]), reproduce alone (2 failed / 6 passed); not this diff: the test reads the first showcase_task unsorted and that row was already done before the action; no stack reads current_user.queues", "mcp_calls": "5: issue_read x4 (27016 get, get_comments; 26954 get_comments), 0 writes", "api_writes": "3 via the relay: pr_create (#27044, 10714 bytes read back identical, assignee os-support-ai), pr_request_reviewers, and this os-dev-report comment", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: dogfood suite only · packaged-action-disabled-dispatch-live.dogfood.test.ts picks GET /data/showcase_task?$top=1 with no sort and asserts its done is false after the refused action; on this box the first row was already done, so acceptance[0] and [5]/[2] fail even when the file runs alone · dedupe: packaged-action-disabled-dispatch-live first task done · carrier: seat 1 to file or route", "boundary: current_user.queues inside a field permission `when` resolves only if a row policy on the same request staged it first (compileRowPredicate does not stage); unresolved fails closed (the entry locks), same as resolver keys today · carrier: none" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Landed ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-28T05:37ZPR #27044 merged at
e3470ed9through the queue, under os-zhuang's Tier H approval. The merge commit is an ancestor oforigin/main. On all 23 paths the PR touched, the merge tree matches the accepted heade3749743byte for byte.queuesis now a reserved RLS membership key. plugin-security resolvescurrent_user.queueskernel-side from the ownership-queue service (queuesOf, the same answer the claim gate'sisMemberreads). It is resolved once per request and bound to the user and organization, and it fails closed when the service is absent or errors. An appIRlsMembershipResolverthat answersqueuesis screened out, and an authoredmembershipKeys.queuesis refused at parse. ADR-0142 D3 is amended to ruling6457475657(letter A).@objectstack/spec,plugin-security,lintandskillsare minor, with a BREAKING banner and ADR-0087not-required (no-migration-prescription).Clause-②: no (narrowing)andMetadata-protocol: narrowed. The card closed throughFixes #27016, and this seat removespm:dispatched. The triage seat's delta review raised two ADR-only should-fixes (the Status-line Amended marker and the Execution plan item 1 annotation). They follow in PR #27096 (Part of #27016, skip-changeset, Tier H).objectstack-fleet commentedon Oct 28, 2026
Follow-up landed ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-28T06:34ZPR #27096 merged at
a305b94eunder os-zhuang's Tier H approval. ADR-0142 Status line now carries the Amended marker for ruling6457475657, and Execution plan item 1 is annotated as superseded by the amended D3. Nothing is left on #27016.