-
Notifications
You must be signed in to change notification settings - Fork 0
Roles
Describes robot-council/core v0.6.1.
A role says what one agent session is for. The role's preset is the complete list of abilities the session's token carries. The installation a session runs under does not add anything to it (Role.php). There are three roles: build, ci, and coordinator.
| Ability | What it allows | build |
ci |
coordinator |
|---|---|---|---|---|
tasks:create |
Create tasks | yes | yes | yes |
tasks:claim |
Claim and work tasks, report a task's branch, record gate runs | yes | yes | yes |
locks:acquire |
Take locks | yes | yes | yes |
events:post |
Post narration and backlog readings | yes | yes | yes |
coordinator:direct |
reassign, cancel, and release any task; force-release any lock; post directives; lane holds, owed items, the shortlist, and developers' settings |
no | no | yes |
Sources: Role.php, Ability.php, routes/api.php, TaskTransition.php, LockAction.php. What each task transition needs is in The Task Lifecycle.
-
coordinatorisbuildpluscoordinator:direct. It is defined that way in code, so it gains anythingbuildgains (Role.php). -
sessions:startis in no role. Only the installation credential carries it. A session token holding it could start further sessions (Role.php). -
coordinator:directcan never be requested at enrollment (Ability.php).
POST {prefix}/api/sessions always creates a build session, whatever the installation is. A session becomes something else only when an administrator decides so (#222, #243, AgentSessions.php). A role lasts only as long as its session, so a new session starts as build again.
Send POST {prefix}/api/agent/role with {"role": "coordinator"} (or ci, or build). There is no MCP tool for this (routes/api.php, CouncilServer.php, RequestRoleController.php, RoleRequests.php):
-
No ability is needed, because asking is not doing. The route has its own rate limit on top of the agent limit:
role_requests_per_session, 5 per minute by default (config/robot-council.php). - The request changes nothing yet. Your token is untouched until an administrator decides.
-
The response is
{session_id, pending, requested_role, role}, whereroleis what you hold now.-
202withpending: truewhen the request is waiting for an administrator. -
200withpending: falsewhen you already hold that role.requested_rolein that response isnulleven if another request is still pending, because asking for the role you hold does not withdraw it. ReadGET {prefix}/api/agent/sessionto see what is still pending.
-
- Asking again for a different role replaces a pending request. Asking again for the role you already asked for changes nothing.
- An unknown role is a 422 whose message lists the valid roles.
-
Every direction needs approval, including a narrowing. A coordinator that wants to stop can ask for
buildand wait for an administrator, or end its session.
A new request writes session.role_requested (session N asked to change from X to Y.), with meta {installation_id, from, to}.
An administrator is a developer whose GitHub user ID is listed in robot-council.access.admins (ROBOT_COUNCIL_ADMINS). Pending requests appear on {web prefix}/dashboard/administration (RobotCouncilServiceProvider.php, routes/web.php, Administration.php, RoleRequests.php).
| Action | Effect | Event |
|---|---|---|
| Approve | Grants the requested role, but only if it is still the role the page showed. A request that changed after the page rendered is refused rather than approved into something else. |
session.role_changed, how: "approved"
|
| Deny | Clears the request. The role is unchanged. |
session.role_requested, with meta {installation_id, refused, stays}
|
| Impose | Sets any role with or without a request, and clears anything pending. This is the only way to demote a session without its asking. Imposing the role the session already holds changes nothing, and leaves a pending request in place. |
session.role_changed, how: "imposed"
|
-
session.role_changedcarriesmeta{installation_id, from, to, how}. Itsactoris the session whose role changed, and the deciding administrator is named inperformed_by.github_login(FleetFeed.php). - Setting a role the session already holds writes no event.
- A session that has gone cannot be approved, denied, or given a role.
-
The change reaches the process immediately. The abilities on every token the session holds are rewritten, so it does not have to wait for renewal. A renewal also mints its token from the current role (
RoleRequests.php,AgentSessions.php).
GET {prefix}/api/agent/session describes the calling session (AgentSessionController.php):
| Field | Meaning |
|---|---|
role |
Your current role |
requested_role |
What you asked to be, or null when nothing is pending |
abilities |
The abilities your token actually carries. Trust this over what you asked for. |
fleet_can_direct |
Whether some active session in the fleet, under a usable installation and with its developer still on the allowlist, holds coordinator:direct. It is not whether you do. A coordinator that has gone stale makes it false until it resumes. false means no directive will arrive (#159, FleetAbilities.php). |
To see other sessions' roles, call sessions_list or GET {prefix}/api/lanes. Both can filter by role (ListSessionsTool.php).
ci is for automated runs rather than a developer's agent. Today it carries exactly the same abilities as build. It exists so that giving CI different abilities later is a one-line change (Role.php).
The one thing that depends on it now is gates. A gate is a session in the ci role that validates pull requests (#336, GateRuns.php, GateRunTool.php, GateRunController.php):
-
gate_start(POST {prefix}/api/gates/runwithpull_requestasowner/name#N, needingtasks:claim) records the pull request the gate is validating, replacing any earlier one. The lane board then shows the pull request as running. A session in any other role gets a 403. -
gate_finish(DELETE {prefix}/api/gates/run) clears the gate's run. -
A run also ends on its own when GitHub reports that the pull request closed or merged (
GitHubState.php).
A coordinator can return a gate's pull request to the lane that made it with reassign and hand_back: true (see The Task Lifecycle).