Human In The Loop
The humans in the loop are users
Everyone who approves or submits is a user of the station: customers in product,
employees in process. An admin never approves a business action: at
run time, they only see incidents (action.failed, delivery.failed, policy.disputed), which they handle
in the console.
who | the user | how they are reached |
|---|---|---|
owner | the room's owner | in the room, on their portal |
principal | the person who sent the agent | through the agent itself: it asks its user to confirm (MCP confirmation, link) |
user.approver | the authority above the user | product: the approver the customer organisation set on the sub-identity, on the channel it declared; process: their manager in the directory |
{role: x} | a role the station designates: finance, IT | an inbox of the station |
user.approver is the same concept in both kinds: the office manager of Cabinet
Diallo and the manager of a support employee approve above the user. Only the source changes.
submitted_by:
- {who: agent, when: "total <= 50 and agent.mode == 'autonomous'"}
- {who: user.approver, when: "total > identity.limits.max_amount"}
- {who: {role: finance}, when: "total > 1000"}
- {who: owner}
The layers add up and the strictest wins: an order above the sub-identity's cap and the station's threshold is approved by both, each for what it protects.
Who owns the room
The owner is always a user: the customer who opens a session, or — when an event
or an automation opens the room — the role the config names. The person it is about is
not its owner: the customer of a ticket is concerned (concerns). They can be notified, their
data is protected; they act on nothing.
room: {key: "$event.ticket_id", owner: {role: support}, concerns: "$event.requester"}
owner: {role: support} means "the support employee who takes it": each one joins the room with
their own identity, and the log says who did what.
Where a role's decision lands
When a policy asks for a role, the action goes pending in that role's inbox.
inboxes:
support-manager: {channel: teams, deadline: 4h, escalate_to: head-of-support}
it: {channel: teams, deadline: 1d, escalate_to: it-lead}
rh: {channel: console, deadline: 2d}
An inbox is not a portal: it is the station calling a user to decide.
The approver sees the final action (approval is the last guard, after the price), the reads it rests on, and — when a smart policy asked for their opinion — why.
Reminders are automations on approval.requested, with
older_than.
Explain and dispute
Every refusal and every "a human must decide" carries a reason a person can read. A decision that affects a person and involves a model has a human recourse.
Separating roles
Rules can cite the other actors of the journey:
- {approval: {role: support-manager, not: "$run.requester"}}
By default, the approver is different from the requester. A manager who requests their own refund goes through another manager.
Reserve and submit: two people
A write can be reserved by one user and submitted by another. When an employee joins, HR reserves the account creation; only IT can submit it:
submit_guard:
submitted_by:
- {who: {role: it}, when: "any(skill == 'create-workspace-account')"}
- {who: {role: rh}}