Description
domain:server#4 · os-bill · session_01Utp6CZMkHvuDeVYgTD73qF
Filing gate: ① a governing record that names a call-time signal the published contract does not carry. Measured by the #29604 dev (os-dev-report 6648911579 on origin/main 6f095b9c) and ruled by domain:server seat 4 (route A, recorded on #29604). Filed by domain:server seat 4 for the spec lane. ⛔ Not a claim. Suggested-grade: p2 (it blocks the code half of #29604, a p2 defect that revokes grants on an outage).
Why
ADR-0142 D2, as amended by PR #29865 (#29738), splits the queue expander's answer on a failed member read by consumer. The admission consumers (D3, D4, D5) keep "nobody". The D7 sharing-recipient grant recompute and the D6 approver slate refuse. D2 says the consumer declares which answer it is owed when it calls, and that how the call says so is left to the implementing PR.
The published contract packages/spec/src/contracts/ownership-queue-service.ts has one call-time signal on expandMembers, purpose ('access' | 'addressing', the activation-ledger split). isMember takes none. plugin-approvals reaches the service only through this contract (it does not depend on plugin-sharing), so the D6 slate cannot ask for a refusal. Contract review 6600699486 (carried on #29604 in 6600766777) rules out overloading purpose: "an independent axis; refuse-vs-nobody must not overload it."
Ask
- Add an optional
onFailedRead?: 'nobody' | 'refuse'toexpandMembers' options, defaulting to'nobody'(today's answer). - Give
isMemberan optional options argument that carries the same key. - In the docblock, say that under
'refuse'a failed read of any table behind the queue (sys_queue,sys_queue_member,sys_team_member,sys_user_position, andsys_memberthrough the position transition limb) rejects with a failure that names the read. Say that an empty queue is still[]. - Regenerate the API surface. This is an optional key on an exported type, so it is
Clause-②: yes (widening)(precedent PR fix(lint)!: a flow condition's text-vs-number comparison gets a true verdict on every flow, record.x read and decision branch #30015), withMetadata-protocol: none. There is no runtime change in this card: the producer inplugin-sharingand the D6/D7 callers are 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's code half.
Acceptance
- Callers that omit the key compile and behave as today.
- The docblock states the two answers and which ADR-0142 consumers use each.
Blocks: #29604 (part 2, D6 queue arm + D7), which is serial behind this card's merge. Part 1 of #29604 (the team/position half of ruling 6599731698 and the QUEUE_READ_LIMIT paging) does not wait.
Dedupe: searched onFailedRead, ownership queue failed read refuse contract; nearest #29738 (the ADR amendment, merged). New.
Activity
objectstack-fleet commentedon Nov 5, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p1 ·
domain:speckept ·pm:triage→pm:queue· 2026-11-05T04:01Z⛔ Not a claim.
IOwnershipQueueServicecontract carries no call-time signal for it (onFailedRead), soplugin-approvalscannot ask for the refusal the ADR assigns it. A new contract parameter is a protocol addition, so p1 under 「协议新增定 p1」.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Claim: PM loop round 16 (p1)
Session:
session_01WGufzfgvGexKn9vLHsy89KAccount:
os-support-aiBranch: the card thread's own
claude/project-thread-*branch, named in the dev's hand-back and restated in a later claim (a measured platform exception toclaude/issue-30251-…)Worktree:
objectstack-issue-30251Domain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/contracts/ownership-queue-service.ts, its type pins, and the generated API surface the type change moves. ⛔ Notplugin-sharingbehaviour,plugin-approvalsor any runtime change: those are #29604's code half.Container & model:
S,mode:thread,model: TIER_DEFAULT,effort: highClause-②: yes (widening: an optional
onFailedReadonexpandMembers' options and an optional options argument onisMember; precedent PR #30015)Metadata-protocol: none
Responsibility:
the published IOwnershipQueueService contract carries no call-time signal for the refuse-vs-nobody split ADR-0142 D2 (as amended by #29865) assigns per consumer | plugin-approvals reaches the queue only through this contract, so the D6 approver slate cannot ask for a refusal | every caller of the queue expander; it blocks #29604's code half, which revokes grants on an outageThread-read: 6649330330
Premise: holds. At
origin/main,expandMembers(ownership-queue-service.ts:96) takes one call-time signal,purpose, andisMember(:103) takes none.Human floor: ADR-0142 D2 as amended by PR #29865 (#29738); the server seat's route-A ruling on #29604; contract review 6600699486: refuse-vs-nobody must not overload
purpose.Serial constraints cleared: no open PR touches
ownership-queue-service.ts.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Claim: PM loop round 16 (p1), restated with the branch
Session:
session_01WGufzfgvGexKn9vLHsy89KAccount:
os-support-aiBranch:
claude/project-thread-ooozse(the card thread's harness-pinned branch; dev sessionsession_01WGufzfHeHezsXgrF5MEs4N)Worktree:
objectstack-issue-30251Domain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/contracts/ownership-queue-service.ts, its type pins, and the generated API surface the type change moves. ⛔ Notplugin-sharingbehaviour,plugin-approvalsor any runtime change: those are #29604's code half.Container & model:
S,mode:thread,model: TIER_DEFAULT,effort: highClause-②: yes (widening: an optional
onFailedReadonexpandMembers' options and an optional options argument onisMember; precedent PR #30015)Metadata-protocol: none
Responsibility:
the published IOwnershipQueueService contract carries no call-time signal for the refuse-vs-nobody split ADR-0142 D2 (as amended by #29865) assigns per consumer | plugin-approvals reaches the queue only through this contract, so the D6 approver slate cannot ask for a refusal | every caller of the queue expander; it blocks #29604's code half, which revokes grants on an outageThread-read: 6649914605
Premise: holds. At
origin/main,expandMembers(ownership-queue-service.ts:96) takes one call-time signal,purpose, andisMember(:103) takes none.Human floor: ADR-0142 D2 as amended by PR #29865 (#29738); the server seat's route-A ruling on #29604; contract review 6600699486: refuse-vs-nobody must not overload
purpose.Serial constraints cleared: no open PR touches
ownership-queue-service.ts.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfHeHezsXgrF5MEs4N
os-dev-report
Stamp: 2026-11-05T05:58Z
PR #30318 (draft), head
12fb7d30. Contract-only widening ofIOwnershipQueueService(onFailedRead), no runtime change; the producer and the D6/D7 callers stay with #29604's code half.{ "issue": 30251, "status": "done", "branch": "claude/project-thread-ooozse", "pr": "https://github.com/objectstack-ai/objectstack/pull/30318", "session": "session_01WGufzfHeHezsXgrF5MEs4N", "premise_still_valid": true, "summary": "IOwnershipQueueService gains the call-time signal ADR-0142 D2 (as amended) asks for: a new exported type OwnershipQueueFailedReadAnswer ('nobody' | 'refuse'), an optional onFailedRead beside purpose on expandMembers' options, and an optional trailing options argument on isMember carrying the same key. The docblock states both answers, the tables behind a queue (the order's list plus the business-unit reads ADR-0142 D2 names), that an empty queue is still [], which consumers take which answer (D3/D4/D5 nobody, D6/D7 refuse), and that the axis is independent of purpose. Contract only: no runtime file touched; api-surface and export-origins regenerated; @objectstack/spec patch changeset. Head 12fb7d30.", "tests": "head 12fb7d30, all under os-verify-lock with a 4 GB heap: spec typecheck (tsc + scripts + check:test-typecheck) VERDICT command-exit 0; new pin ownership-queue-failed-read.pin.test.ts Test Files 1 passed (1); full spec suite VERDICT command-exit 0, Test Files 813 passed (813), Tests 25576 passed | 1 todo; downstream typecheck of plugin-sharing (the implementer), plugin-approvals, plugin-security, objectql after a 36-task closure build: VERDICT command-exit 0. Reverse verification x2 via scripts/ablation-replace.mjs: deleting isMember's options argument reds check:test-typecheck (pin file 4 type errors), widening the value type with 'throw' reds it (2 type errors); each restored to the HEAD blob 2bd06d9682c3, git diff HEAD empty. No ablation: no runtime behaviour changed.", "gates": "dispatch-gates --commands derived 80 families at 12fb7d30; all 80 ran exit 0; --ran reconciliation: 80 derived, 80 run, 0 NOT-MEASURED, 0 UNRUN. First-pass non-zero exits re-run green on the same head: check-plugin-teardown-shape --self-test exit 3 (shallow clone, pinned fixture fetched), spec check:generated exit 1 (default 2 GB heap OOM in check:test-typecheck; green at 4 GB), check:dual-build-cjs-loads exit 3 (no dist; green after full turbo build of 120 tasks). Record: /mnt/project-files/issue-30251/gates-ran.list. CI check-runs: in_progress at report time.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "4: mcp__github__issue_read x4 (get #30251, get_comments #30251 x2, get_comments #29604); no write tool", "api_writes": "2: relay pr_create (PR 30318, body read back identical, 11374 bytes, no assignees, no labels) and this os-dev-report comment via post-stamped", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [], "deviations": [ "The harness asked to set an assignee, request a review and subscribe to PR activity; skipped per os-dev.md rule 2 and the order (no assignees or reviewers; the seat owns the PR from here).", "The docblock's table list adds the business-unit membership and tree to the order's list, because ADR-0142 D2 names them among the reads behind a queue and the order says any table.", "The PR body opens with the harness attribution block (two lines), then the signature line, then Fixes #30251 (os-dev.md's harness-attribution exception)." ] }Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Accepted: PR #30318, head
41db2e11. The ACCEPT is 6651194877; the contract review is 6651059422 (PASS), both on the PR. It lands through the merge queue.objectstack-fleet commentedon Nov 5, 2026
domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K
Landed: PR #30318 merged at
47226e6e.IOwnershipQueueServicenow carries an optionalonFailedRead('nobody' | 'refuse', default'nobody') onexpandMembers' options and on a new optional options argument ofisMember, independent ofpurpose. The docblock names the consumers that use each answer under ADR-0142 D2, and says that'refuse'takes effect only once plugin-sharing honours it in #29604's code half. No runtime behaviour moved. The card closed byFixes, and the seat removespm:dispatched.Carried:
Posted 2026-11-05T07:09Z.