Repository navigation
fix(plugin-approvals): a field approver id or an out-of-office delegate that names no account adds no phantom slot - #27852
Conversation
…te that names no account adds no phantom slot A `field` approver id no account carries now warns "expanded to nobody" and adds no slot, as a `user` approver does since #27397; a slate it empties reaches the node's onEmptyApprovers. A delegation chain ending on a delegate no account carries falls back to the original approver, warned and with no substitution recorded. A failed directory read keeps the slot either way. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4cwhsfZfJRshUTzrYYT
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 6 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin fcdf0dd811ab6954654f5b745077b60ce0049aed && git checkout fcdf0dd811ab6954654f5b745077b60ce0049aed
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 637cfc67362933c7c04b8784247e2b39d4e68acf 5382a18163375726e54bc25b6612c3c9824415a7 && git checkout -B drift-repro 637cfc67362933c7c04b8784247e2b39d4e68acf && git merge --no-ff 5382a18163375726e54bc25b6612c3c9824415a7
node scripts/docs-audit/affected-docs.mjs --json 637cfc67362933c7c04b8784247e2b39d4e68acf
|
|
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia Seat ACCEPT · PR #27852 · head
|
Requested by Elon · project thread
Fixes #27752
维护者速读
field)如果对应的账号不存在,不再生成一个没人能处理的空槽位;外出委托指向一个已删除的账号时,审批退回给原审批人本人。user)的这种情况修好了,这两条兄弟路径还是老样子,审批单会卡在一个不存在的人身上,日志里也没有任何提示。plugin-approvals的审批人展开;目录读取失败时一律保留原槽位,不会因为一次读失败清空审批人。回滚即还原这一个提交。approval-service.ts里resolveApproverSpec的field分支和applyOooDelegation末尾的退回逻辑。pnpm --filter @objectstack/plugin-approvals exec vitest run src/approval-service.test.ts -t 27752,9 条用例全绿。What changes
type: 'field'(resolveApproverSpec): each id the record field holds now takes fix(plugin-approvals): a user approver naming no account expands to nobody and takes onEmptyApprovers #27749'susertreatment. The id is a slot only when an account carries it, asked through the same predicate (reassignTargetRefusalwith no organization). An id no account carries logs the shared "expanded to nobody" warning (naming the field and the id), adds no slot, and a slate it empties reaches the node'sonEmptyApprovers. A failed directory read keeps the slot.applyOooDelegation): a chain that ends on a delegate no account carries routes the slot back to the original approver, per the triage ruling (6510482313). It logs an "expanded to nobody" warning naming delegator and delegate, and the chain's hops are taken back out of the substitution collector, so noooo_substituteaction or notification is written for a reroute that did not happen. A failed read keeps the delegate. A removed delegator with a live delegate still routes to the delegate (plugin-approvals: the out-of-office notifications name the absent approver and the delegate by rawsys_userid ("… while u_ooo is out of office", "… was routed to u_bob …") — the person half of the approval-notification wording #24065). The fallback lives inapplyOooDelegation, so it covers every caller:user,field,managerandexpressionwithresolveAs: 'user'.namesNoAccount(value)wraps the predicate plus its fail-open catch, and theuserbranch now uses it too (same behaviour).Why
#27749 (#27397) closed the phantom-slot path for
userapprovers. Thefieldbranch and the delegation step still handed an id no account carries straight to the slate: the request opened on a slot nobody could take, with no warning and noonEmptyApprovers.Verification
mainfirst: of the 9 new cases, 5 were red (the twofieldcases and the three dead-delegate cases) and the 4 pins (live ids quiet, failed-read keeps the slot for both paths, live delegate routes with its substitution) were green.fieldcheck reds the 2fieldcases. Disabling the delegate check reds the 3 delegate cases. Keeping the check but dropping the collector rollback reds the 2 cases that assert no substitution. Restored: all green.plugin-approvalsfull suite: 105 files, 1347 tests pass. Four existing cases routed to ids their test double's directory did not carry (u4,u7,bob). Their fixtures now staff those accounts, test-only, as fix(plugin-approvals): a user approver naming no account expands to nobody and takes onEmptyApprovers #27749 did foruser.dispatch-gates --commandsfamily pluspnpm lint: reported on the card thread.Clause-②: no
Metadata-protocol: none
Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4cwhsfZfJRshUTzrYYT