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
Why this card is pm:blocked rather than pm:dispatched — added by the domain:services seat (session session_01AUF1NoViznQK32gqpK8wS8), 2026-09-03 03:34Z. The work is done: PR #14528 is reviewed, ACCEPTed, and mergeable_state: clean with all its own checks green on head 645b14e9e. What blocks it is an external gate defect, and the state machine reserves pm:blocked for exactly that shape rather than a new label.
Measured before flipping, not assumed:
5 merge-queue ejections, every one on the same signature — test/run-dev-unbuilt-workspace.e2e.test.ts, AssertionError: expected 'SIGKILL' to be null (latest queue-triage comment 2026-09-03T03:33:13Z).
The head never changed across all five (645b14e9e throughout), so nothing about this PR is being re-tested — the same artefact is failing on someone else's defect.
git merge-tree --write-tree origin/main 645b14e9e exits 0: no conflict with main.
⛔ Not re-queueing this PR on that signature. The merge-queue-triage bot's own checklist says a failure matching a known aggregation issue is not fixed by re-queueing, and each attempt rebuilds the whole queue behind it. This card returns to the queue when #14648 is closed, via the Unlock-action line above.
⚠️ Stated against the counter-evidence rather than around it: PR #14750 crossed this same queue on its own after 2 ejections, so the queue is lossy, not deadlocked. The judgement here rests on 5 ejections with an unchanged head plus a refuted fix direction, not on ejection count alone.
现象
一个用「审批流改状态 + 按状态共享」这个常见组合搭起来的模块:员工提交请假 → 主管在审批收件箱批准 → 记录变
approved。批准之后,同团队的另一位员工看不到这条记录;而更早的几条已批准记录却看得到。连续观察 2 分 47 秒(每 15s 一次共 12 次,每次都是重新发起的独立服务端查询,不是盯着一个已加载的页面)状态不变——不是异步延迟。
对该共享规则调一次
POST /api/v1/sharing/rules/<id>/evaluate(以 admin 身份)后,再发一次全新的查询即恢复正常:根因(代码级判定点,发行包
@objectstack/plugin-sharing/dist/index.mjs)平台本来就支持逐记录实时物化:
bindRuleHooks()为每个有活跃规则的对象注册afterInsert/afterUpdate/afterDelete(:5109/:5125,priority 180),逐记录调用service.evaluateAllForRecord();该方法自己的注释即写着「the per-record pass the afterInsert/afterUpdate hooks run」(:3859)。但两个钩子的第一行就把系统写挡掉,且不做任何补偿:
跳过后只发一条 info 通知(
:5059),原文逐字:而审批回写恰恰是系统写:审批节点以平台身份写
approvalStatusField,且lockRecord: true决定了此时只有平台写能落地。链条:批准 → 系统身份写状态字段 → 共享物化被跳过 → 团队看不见 → 直到有人手动
evaluate或重启服务。⚠ 影响面取决于观察者的角色(2026-08-31 补,见评论区)
本单现象只对「不持
viewAllRecords、依赖共享规则看他人已批准记录」的角色可观测。 持viewAllRecords: true的主体——包括本例中的审批人本人与 admin——不受影响,因为他们的读路径根本不经过共享规则。这对复现有直接影响:用审批人或管理员视角去复现,会看不到问题。 必须用一个只能看自己、靠共享规则看他人的普通成员身份。
为什么值得单独看,而不是「用法不对」
spec/security/sharing.zod.ts无相关字段;全包内无OS_SHARING*之类配置,也没有「让系统写参与重算」的选项;content/docs/、docs/、test/全仓检索不到「审批后何时可见」的任何说法,也搜不到那条通知语;待裁的方向(供参考,不预设结论)
邻近既有单(已查,非重复)
grant()skips the ADR-0111 D7 inert-grant guard entirely for SYSTEM callers, so the sharing-rule evaluator can still materialise rows no gate consults #8207grant()skips the ADR-0111 D7 inert-grant guard for SYSTEM callers(同样是 SYSTEM 路径,但方向相反:那条是系统调用绕过了守卫,本条是系统写被守卫挡掉)复现最小路径
type:'approval'节点 +approvalStatusField+lockRecord:true;status == 'approved'),收件人为某真实 position;POST /api/v1/approvals/requests/<id>/approve;viewAllRecords的普通成员,且每次重新发起查询(不要盯着一个已加载的页面)——查询该对象 → 看不到刚批准的记录;evaluate,再重新查询一次 → 立即可见。Blocked-by: #14648
Unlock-action: re-check PR #14528
Why this card is
pm:blockedrather thanpm:dispatched— added by thedomain:servicesseat (sessionsession_01AUF1NoViznQK32gqpK8wS8), 2026-09-03 03:34Z. The work is done: PR #14528 is reviewed, ACCEPTed, andmergeable_state: cleanwith all its own checks green on head645b14e9e. What blocks it is an external gate defect, and the state machine reservespm:blockedfor exactly that shape rather than a new label.Measured before flipping, not assumed:
test/run-dev-unbuilt-workspace.e2e.test.ts,AssertionError: expected 'SIGKILL' to be null(latest queue-triage comment 2026-09-03T03:33:13Z).645b14e9ethroughout), so nothing about this PR is being re-tested — the same artefact is failing on someone else's defect.git merge-tree --write-tree origin/main 645b14e9eexits 0: no conflict withmain.domain:cli,p1). Its candidate fix PR test(cli): make the unread-reader ceiling a load-independent constant at RUN_TIMEOUT_MS #14715 was refuted on 2026-09-03T02:24Z: raising the ceiling to 180000 ms still failed, with the child running 180105 ms against a 6125 ms baseline on the same runner minutes earlier — a stall, not a margin, which no constant ceiling closes.⛔ Not re-queueing this PR on that signature. The merge-queue-triage bot's own checklist says a failure matching a known aggregation issue is not fixed by re-queueing, and each attempt rebuilds the whole queue behind it. This card returns to the queue when #14648 is closed, via the
Unlock-actionline above.Generated by Claude Code