Fixtures and visibility
This is the exercise where the identity boundary stops being theory. Three prepared accounts, one pending approval, and you get to watch two of them be refused.
No directory access required.
Gate G4 — required implementation. The prepared fixture exercise is executable once the supplied starter and its pinned dependencies pass their own checks.
Gate G9 — required implementation. The richer, relationship-aware authorization is not finished. What you see here is the provider and membership check, which is.
Create three accounts: a requester, an approver, and a blocked one.
Give the approver the principal the pending step expects. Give the blocked account a subject that looks similar but carries no matching membership — same shape, different provider or different key. That near-miss is the interesting case; an obviously unrelated account proves much less.
Start the workflow as the requester.
The approver sees the pending step. The blocked account does not. Complete it as the approver and keep the resulting state and events.
Then test the other direction, which people forget: a query that is allowed but returns nothing. An empty result is a real answer, not a sign that something was bypassed — and it should be recorded as such.
Record a receipt only once the G9 work above is actually available.
This exercise is the required one. It shows the boundary; it does not imply access to any customer directory. To continue the workflow sequence, go back to Day 2: Multi-role approval.
Someone leaves the team. Their membership is refreshed away.
What changes: who may act from now on. What does not change: any event already recorded. The past is not rewritten to match the present — the approval they gave last week still happened and still says so.
The check happens when someone tries to act. Keep the before and after, and confirm that an actor who lost the required membership is refused at the step they could have completed an hour earlier.