Skip to content

Assignee Sources

Two ways to say who should approve something:

  • Name them. The workflow already knows the principal. Simple, and it’s what the tutorial uses.
  • Point at a group somewhere else. Membership is owned by another system and can change while your workflow is waiting. That’s an assignee source, refreshed by a signed change event.

Start with the first. Move to the second only when membership genuinely lives elsewhere.

Gate G4 — required implementation. The resolver API is current. The starter’s provider normalization is still being finished.

A pending step records the provider ID and the principal reference, and the engine compares both. The same text under a different provider is never a match.

For recipients you already know, this is all you need.

hooks.assignees.resolver('siam', { context, resolve }).

You give it a source reference; it returns who is in that group now. It runs at the refresh boundary — when a change event arrives — and never during replay. That separation is what keeps replay deterministic while still letting the answer change over time.

Four things to keep from every refresh: the source key, the source version, the signed event ID, and what happened to the step.

Two properties to rely on. A duplicate event must be harmless — you will get duplicates. And a changed source can change who is able to complete a step that is already pending, without touching any event that was already recorded.

The Day 1 vacation coverage exercise walks through exactly that.