Skip to content

Commit 29420c9

Browse files
committed
docs(approvals): an entry that resolves to nobody leaves a slate per its kind, and onEmptyApprovers decides an empty one
The lifecycle step said an entry that resolves to nobody opens an empty pending_approvers that nothing can move, so the run parks forever. The runtime does neither: a person entry (manager, field) adds no slot, a group entry keeps its type:value literal (a position literal decided by a later holder, any other only by an administrator), and an empty or literal-only slate goes to the node's onEmptyApprovers policy (admin_rescue by default). The queue-filter note now says a GROUP entry falls back to the literal, which the rewrite made the only true reading. Claude-Session: https://claude.ai/code/session_01Q7Fy4uVkvBWgj9CLihdATJ Co-authored-by: Claude <noreply@anthropic.com>
1 parent cc305a3 commit 29420c9

1 file changed

Lines changed: 23 additions & 5 deletions

File tree

‎content/docs/automation/approvals.mdx‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,27 @@ a queue entry resolves to nobody. Route to a `team`, `department`, or
383383
Set Manager** — see [the `manager` callout above](#3-the-approval-node). `position`, `department`,
384384
`org_membership_level` and `expression` may additionally name which
385385
organization's directory resolves them — see
386-
[Approving across organizations](#cross-org-approvers). An entry that resolves
387-
to nobody is not an error: the request opens with an empty `pending_approvers`
388-
and nothing can move it, so the run parks forever.
386+
[Approving across organizations](#cross-org-approvers).
387+
388+
What an entry that resolves to nobody leaves on the slate depends on its kind:
389+
390+
- **A person entry** (`manager`, `field`) adds no slot. Nor does an
391+
`expression` that yields no ids. A `user` entry never resolves to nobody: its
392+
value is the slot.
393+
- **A group entry** (`position`, `team`, `department`, `org_membership_level`)
394+
keeps its `<type>:<value>` literal as a slot, and so do a `queue` entry and an
395+
`expression` value that `resolveAs` re-expands into a group with nobody in it.
396+
A `position:<name>` slot is decided by whoever is staffed into that position
397+
later. No person ever holds any other literal, so only an administrator can
398+
decide it (the admin-override callout under
399+
[Acting on requests in the console](#acting-on-requests-in-the-console)).
400+
Beside entries that do resolve, a literal is a slot like any other, so a
401+
`behavior` that needs every slot (`unanimous`) waits on it too.
402+
- **A slate left empty, or holding only literals,** goes to the node's
403+
`onEmptyApprovers` policy, listed at the end of
404+
[Approving across organizations](#cross-org-approvers). Under the default,
405+
`admin_rescue`, the request opens on that slate and waits for an
406+
administrator, or for a holder of a `position:` literal on it.
389407

390408
### The approver finds it in their queue
391409

@@ -420,8 +438,8 @@ curl -b cookies.txt \
420438
```
421439

422440
`approverId` accepts a user id, an email, or a `<type>:<value>` approver literal
423-
(`position:finance_manager` — the form an entry falls back to when it resolves
424-
to no users) — and takes several values (comma-separated or repeated) to cover
441+
(`position:finance_manager` — the form a group entry falls back to when it
442+
resolves to no users) — and takes several values (comma-separated or repeated) to cover
425443
a person's identities in one call. A position literal matches under
426444
`position:<name>`, the one spelling the service admits a holder of that
427445
position under as their own identity. The deprecated pre-rename prefix is no

0 commit comments

Comments
 (0)