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
plugins: a queue sharing recipient still revokes grants on a member-table outage, because the queue expander answers "nobody" for every consumer; refuse for the sharing-grant pass and the approver slate (ADR-0142 amendment first) #29604
Filing gate: ③ open question 1 of the #29503 dev (os-dev-report 6588119628, site 4), ruled by the seat (6588178193): A on PR #29602, and direction B filed here. Filed by domain:server seat 3. ⛔ Not a claim. Suggested-grade: p2 (same defect class as #29362 / #29503: on an outage, a recompute revokes share grants it should keep).
What happens
packages/plugins/plugin-sharing/src/ownership-queue-service.ts catches any member-table read failure during expansion, warns "contributes nobody until it can", and answers [] (isMember answers false). The file header declares that posture: "a failed read of a member table contributes nobody for that specification (fail closed for every admission that reads it)". ADR-0142 itself does not declare it. D2 says "an empty expansion is a fact, not a fault". D5 says a failed read during assignment "leaves the row as it was … and logs at warn".
After PR #29602 (#29503), every other sharing and approvals recipient read refuses on a failed read. The queue expander is the last one that answers "nobody". So a queue sharing recipient (ADR-0142 D7) is still diffed against a set that is missing its members on an outage, through reconcile (revokeRuleGrantsForRetiredRecipients) and through the per-user recompute via isMember, and its grants are revoked. The approver slate (D6) can likewise route to a shrunk set. Source reading, not reproduced through a public door.
Wanted (direction ruled B)
ADR-0142 amendment first (a governed path; its own PR, approved by GOVERNED_APPROVERS before code relies on it). It adds a line to D2 saying the one expander keeps "nobody" as its fail-closed answer for admission consumers (the access path, claim admission and the assignment pool), while the sharing-recipient grant pass (D7) and the approver slate (D6) refuse on a failed read. Use the repo's ADR amendment-note recipe.
Pins: a failed member read keeps queue-recipient grants on reconcile and on the per-user recompute (red on main); the access path still answers no access on the same failure (control); the approver slate refuses instead of shrinking.
Level: the D6/D7 doors narrow (a recompute that used to revoke now refuses), so expect !, Clause-②: no (narrowing) and the full dogfood battery.
Serial: after PR #29602 merges (same files; its holderCheck wrapper is the seam this card changes).
Dedupe: searched ADR-0142 queue outage, contributes nobody until it can; nearest #29503. New.
The consequence: the queue's sharing-recipient pass through isMember now revokes on a sys_user_position outage, where main kept the transition-source holders.
Add to Wanted: the D7 refusal covers this case. The queue posture pin in ownership-queue.test.ts seeds one sys_member transition row, so the pin can see the answer on both sides of the change.
Measured reading for this card, carried from #29606 (os-dev-report 6591481172, item 2; seat ruling A on its open question 2). Recorded 2026-11-03T00:01Z.
QUEUE_READ_LIMIT (packages/plugins/plugin-sharing/src/ownership-queue-service.ts) drops holders silently. Measured on a real engine (scratch, not committed):
One queue with 10,001 user member rows: expandMembers answers 10,000; the 10,001st user gets isMember false and queuesOf[]. No warning.
10,001 authored queues: queuesOf does not list the last one.
queuesNaming misses a queue past 10,000 rows of one kind.
PR #29647 (#29606) completes the business-unit member reads in plugin-sharing and plugin-approvals but leaves this file alone, because this card owns it and the queue posture. Whoever takes this card should cover the queue reads' 10,000 bound in the same change, or split it out with a measured reason.
It is narrowing (!), with the full dogfood battery.
QUEUE_READ_LIMIT's silent drop past 10,000 rows (6591670782) is the seat's call. It is covered in step 2 if it fits the same diff; otherwise it is split out with the reason recorded here.
Ruling B: when a directory read behind a queue, team or position approver fails, the approval node refuses to open, under every onEmptyApprovers policy alike (admin_rescue, auto_approve, fail, fallback). It is not routed to administrators, not auto-approved, and not opened on a fallback slate.
Retryable: the node fails loudly with its own error class (not NO_APPROVERS, not "expanded to nobody") and names the read that failed. The run can be re-triggered once the directory reads again. A parked or auto-retry state is not part of this ruling; if one is wanted, it gets a separate card.
Carried to the code half · from contract review 6600699486 (PR #29865, round 2, PASS) · 2026-11-03T10:07Z
D2's read list should also name sys_member, which a position specification reads through the ADR-0057 D4 transition limb (expandPositionUsers → expandRoleUsers; holdsPosition → holdsRole). The code half should treat a failed sys_member read as a failed read. It should also decide, and say, whether the activation-ledger read (switchedOff, answered "on" when the read fails) keeps that posture.
Ruling B (6599731698) covers every slate the node resolves, including a fallback policy's declared fallback slate, which openNodeRequest resolves through the same expandApprovers.
Implementation notes from the review: the resolver's try also wraps the cross-org read filter (bounded), so a failure there refuses the node under the same seam. expandApprovers returns a flat string[], so "openNodeRequest sees it" means either the resolver throws or the contract grows a carrier. The queue branch's early return currently runs before the directoryFailure check and must be reordered. QueueExpansionPurpose (access | addressing) is an independent axis; refuse-vs-nobody must not overload it.
Activity
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Filing addendum · #29604 · 2026-11-02T21:06Z
Carried from should-fix 1 of the
CONTRACT_REVIEW_TIERrecord on PR #29602 (#29503, head38c62472, PASS). This card owns the queue position case:sys_user_positionread madeholdsPositionfall through toholdsRole, andexpandPositionUsersfell through to thesys_member.roletransition limb. So on that outage a queuepositionspecification contributed the transition-source holders.holderCheckandexpandSpecanswerfalseand[]. That is the service header's declared "nobody", now reached for the first time.isMembernow revokes on asys_user_positionoutage, where main kept the transition-source holders.ownership-queue.test.tsseeds onesys_membertransition row, so the pin can see the answer on both sides of the change.objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:server·pm:queue· 2026-11-02T21:56Z⛔ Not a claim.
expandRoleand approvals role-tier recipients read sys_member at a 10,000-row bound and turn a failed read into an empty list, so a large or unreadable membership silently shrinks the set #29362 and plugins: the rest of the sharing and approvals recipient reads still truncate at 10,000 rows or turn a failed read into "nobody" (sys_team_member, sys_user_position, holdsRole/teamHasMember, queue expandSpec) — #29362 close-out #29503. p2, as suggested. ⛔ The card puts an ADR-0142 amendment first. That is governed Tier H text, so its approval is the maintainer's before the code half lands.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Measured reading for this card, carried from #29606 (os-dev-report 6591481172, item 2; seat ruling A on its open question 2). Recorded 2026-11-03T00:01Z.
QUEUE_READ_LIMIT(packages/plugins/plugin-sharing/src/ownership-queue-service.ts) drops holders silently. Measured on a real engine (scratch, not committed):expandMembersanswers 10,000; the 10,001st user getsisMemberfalse andqueuesOf[]. No warning.queuesOfdoes not list the last one.queuesNamingmisses a queue past 10,000 rows of one kind.PR #29647 (#29606) completes the business-unit member reads in plugin-sharing and plugin-approvals but leaves this file alone, because this card owns it and the queue posture. Whoever takes this card should cover the queue reads' 10,000 bound in the same change, or split it out with a measured reason.
objectstack-fleet commentedon Nov 3, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Ruling recorded · B · 2026-11-03T03:07Z
Blocked-by: #29738
Unlock-action: dispatch this card's code half when #29738's PR merges
expandRoleand approvals role-tier recipients read sys_member at a 10,000-row bound and turn a failed read into an empty list, so a large or unreadable membership silently shrinks the set #29362).!), with the full dogfood battery.QUEUE_READ_LIMIT's silent drop past 10,000 rows (6591670782) is the seat's call. It is covered in step 2 if it fits the same diff; otherwise it is split out with the reason recorded here.pm:queue→pm:blocked.objectstack-fleet commentedon Nov 3, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Ruling recorded · B (directory outage at an approval node) · 2026-11-03T09:13Z
queue,teamorpositionapprover fails, the approval node refuses to open, under everyonEmptyApproverspolicy alike (admin_rescue,auto_approve,fail,fallback). It is not routed to administrators, not auto-approved, and not opened on a fallback slate.NO_APPROVERS, not "expanded to nobody") and names the read that failed. The run can be re-triggered once the directory reads again. A parked or auto-retry state is not part of this ruling; if one is wanted, it gets a separate card.openNodeRequestmust see the resolver'sdirectoryFailure, and thequeuebranch's early "expanded to nobody" return must consult it first. The admission consumers (D3/D4/D5) and D7 are unchanged from that ruling.pm:blockedbehind docs(adr-0142): amend D2 — a failed member read refuses for the D7 grant recompute and the D6 approver slate, and still answers nobody for admission consumers #29738 and is not dispatched this shift.objectstack-fleet commentedon Nov 3, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Carried to the code half · from contract review 6600699486 (PR #29865, round 2, PASS) · 2026-11-03T10:07Z
sys_member, which apositionspecification reads through the ADR-0057 D4 transition limb (expandPositionUsers→expandRoleUsers;holdsPosition→holdsRole). The code half should treat a failedsys_memberread as a failed read. It should also decide, and say, whether the activation-ledger read (switchedOff, answered "on" when the read fails) keeps that posture.fallbackpolicy's declared fallback slate, whichopenNodeRequestresolves through the sameexpandApprovers.bounded), so a failure there refuses the node under the same seam.expandApproversreturns a flatstring[], so "openNodeRequest sees it" means either the resolver throws or the contract grows a carrier. Thequeuebranch's early return currently runs before thedirectoryFailurecheck and must be reordered.QueueExpansionPurpose(access|addressing) is an independent axis; refuse-vs-nobody must not overload it.