The agent.* family (16 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.
Feedagent.activity.feed
| Property | Value |
|---|---|
| Capability | agenttask.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
: the NESTED agent_task delegation tree for ONE chat (the single-chat activity view, design w7ff586iu). Rooted at a CoS turn (rootTaskId) or a matter; each node carries the HANDOFF (parent), the agent (created_by + tier=depth), the REASONING (rationale + autonomy_exercised, CC-OPBOX 104), the TOOL-USE (verb calls attributed EXACTLY via event.task_id, migration 0113), and its children. A regenerable VIEW over agent_task + event (Steering #2), RLS-fenced (INV-17). No new trust boundary - it reshapes reads the caller already has via agenttask.feed/get + the audit feed.
Call POST /v/agent.activity.feed with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Setagent.autonomy.set
| Property | Value |
|---|---|
| Capability | agent.grant.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Owner |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
(autonomy in 0..3). WRITE/OWNER (CC-OPBOX 65 Fork 3). Sets a roster agent’s STANDING
actor.autonomy_level (the floor the resolver’s min(actor, token ceiling) can never exceed,
ADR-0040 §6 / INV-12). NO SELF-RAISE: a caller may not raise its OWN autonomy (an agent cannot lift
its own ceiling - the privilege-escalation fence); it MAY lower its own. The conferred level may not
exceed the SETTER’s own per-request autonomy (no-amplification, the standing twin of INV-15 - a setter
cannot grant a ceiling it does not itself hold). RLS-scoped.
Input { agentId, autonomy } (fields ending in ? are optional)
Call POST /v/agent.autonomy.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.autonomy.set.
Getagent.context.get
| Property | Value |
|---|---|
| Capability | agent.context |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
AR-5: the acting agent reads its OWN persistent reasoning context (the per-(workspace, agent) scratch the
agent loop loads at task-start). RLS-scoped to the workspace; actor_id is the CALLER (ctx.actor.id), so an
agent can never read another’s memory. Returns {} when none is set yet.
Call POST /v/agent.context.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.context.get.
Setagent.context.set
| Property | Value |
|---|---|
| Capability | agent.context |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
AR-5: the acting agent upserts its OWN context (the scratch it saves at task-end). actor_id is ALWAYS the caller (an agent cannot write another’s memory); the 64KB ck_agent_context_size bound (migration 0106) refuses a runaway blob (surfaced as a DB error, INV-9). Upsert-by-replace: one row per (workspace, agent).
Call POST /v/agent.context.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.context.set.
Conveneagent.convene
| Property | Value |
|---|---|
| Capability | agent.convene |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Mints a convening (shape=SINGLE) + ONE subset-seat. The seat is a strict subset of the convener on
every axis (INV-15): autonomy ≤ convener, scope ⊆ convener-grantable ∩ READ-only, workspace inherited.
Returns the convening + the seat token secret ONCE (the seat presents it; TokenIdentityProvider
resolves it to a capped AuthContext).
Input { seatLabel?, seatBrief?, capabilityScope: [verb,...], autonomy?, budgetMicro?, ttlSecs?, matterId?, boardIssueId?, parentTaskId?, budgetPoolId? } (fields ending in ? are optional)
Call POST /v/agent.convene with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.convene.
Panelagent.convene.panel
| Property | Value |
|---|---|
| Capability | agent.convene |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
{ seats: [{ label, brief? }, ...], capabilityScope: [verb,...], autonomy?, budgetMicro?, ttlSecs?, matterId?, boardIssueId?, parentTaskId?, budgetPoolId? }. WRITE/L1/MEMBER.
N seats (seat_count ≤ MAX_CONVENE_FANOUT=5), each a distinct-lens subset-instance (the council shape), sharing ONE budget pool - fanning out cannot amplify spend (INV-15 §2). Labels MUST be distinct (uq_convening_seat_label). Returns the convening + each seat’s token secret ONCE.
Call POST /v/agent.convene.panel with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.convene.panel.
Getagent.convening.get
| Property | Value |
|---|---|
| Capability | agent.convening.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
The queryable, attributed hand-off surface (one SELECT over
convening + its seats; INV-14 no second store). IDOR-scoped to the workspace (predicate + RLS).
Input { conveningId } (fields ending in ? are optional)
Call POST /v/agent.convening.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.convening.get.
Listagent.convening.list
| Property | Value |
|---|---|
| Capability | agent.convening.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
(ADMIN for cross-actor). One SELECT over convening
(INV-14). IDOR-scoped to the workspace (predicate + RLS backstop).
Input { status?, convenerId? } (fields ending in ? are optional)
Call POST /v/agent.convening.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.convening.list.
Dissolveagent.dissolve
| Property | Value |
|---|---|
| Capability | agent.convene |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
·ADMIN. Revokes EACH seat token (REUSE the token revoke SQL) + sets EACH seat actor status=REVOKED + persists dissolve_summary onto the convening + status=DISSOLVED. The dispatch appends the terminal AuditEvent (INV-8). Destroys the ACTOR, never the outcome/audit (INV-16 - no CASCADE reaches the append-only event chain / the terminal agent_task rows).
Input { conveningId, summary? } (fields ending in ? are optional)
Call POST /v/agent.dissolve with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Getagent.grant.get
| Property | Value |
|---|---|
| Capability | org.agent.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Reads the standing agent_grant matrix (the packs x agents view): one
row per roster agent with its conferred capability_scope, autonomy_ceiling, and org_pack flag. With
agentId it returns the ONE agent’s grant (or a null grant for a node with none authored yet); without
it the whole workspace matrix (RLS-scoped - ws B never sees ws A’s grants). One SELECT over actor
(role IS NOT NULL) LEFT-JOIN agent_grant (the org-chart projection’s grant-only twin, no new store).
Input { agentId? } (fields ending in ? are optional)
Call POST /v/agent.grant.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.grant.get.
Setagent.grant.set
| Property | Value |
|---|---|
| Capability | agent.grant.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Owner |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Upserts the standing grant for a roster agent: conferred capability_scope ⊆ the GRANTOR’s own scope AND conferred autonomy_ceiling ≤ the grantor’s autonomy (no-amplification, ADR-0026 - grantor ⊇ conferred). The org.* pack flag is OWNER-only (the dispatch tier gate already restricts the verb to OWNER; the flag is additionally rejected unless the grantor itself carries it). One grant row per (workspace, agent).
Input { agentId, capabilityScope?, autonomy?, orgPack? } (fields ending in ? are optional)
Call POST /v/agent.grant.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.grant.set.
Getagent.persona.get
| Property | Value |
|---|---|
| Capability | org.agent.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Projects a roster agent’s persona: the soul_ref (the BASE SOUL the
reconcile projects from) + the actor.spec jsonb (the OVERLAY - the authored persona config) merged
into the EFFECTIVE persona. The base is { soulRef }; the overlay is the spec blob; the effective is
the overlay with the base folded in under a soulRef key (the spec wins where it sets a key, the SOUL
ref is the floor). RLS-scoped - ws B never reads ws A’s persona.
Input { agentId } (fields ending in ? are optional)
Call POST /v/agent.persona.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.persona.get.
Runagent.run
| Property | Value |
|---|---|
| Capability | agent.run |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
the carrier-label guard. SENSITIVE/MEMBER, capability agent.run, NOT idempotent, tier
AdminOnly (registered for INV-11, never MCP-advertised - the caged seat CLAIMS the agenttask, it does not
dispatch this verb). See the module docs + [2026] VJS-CC-OPBOX 22.
Call POST /v/agent.run with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Attachagent.skill.attach
| Property | Value |
|---|---|
| Capability | org.agent.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
(skill is a non-empty catalogue key) { skillRef?, params? }. WRITE/ADMIN.
Attaches a catalogue SKILL into the roster agent’s actor.spec jsonb under a skills array (the
typed persona config, ADR-0006 typed-not-blob: the structured role/autonomy live in real columns,
this is the persona overlay slice). Idempotent on the skill KEY - re-attaching the same skill updates
its entry in place (one entry per skill), never a duplicate. The mutation is a read-modify-write of
the spec jsonb on the same tx (one write path, INV-1). RLS-scoped.
Input { agentId, skill } (fields ending in ? are optional)
Call POST /v/agent.skill.attach with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool agent.skill.attach.
Mark Notifiedagent.toolcatalogue.markNotified
| Property | Value |
|---|---|
| Capability | agent.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Stamp notified_at on one snapshot by id, or bootstrap
every un-notified row. { id? } | { allUnnotified:true }. Idempotent.
Call POST /v/agent.toolcatalogue.markNotified with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Snapshotagent.toolcatalogue.snapshot
| Property | Value |
|---|---|
| Capability | agent.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Idempotent create-if-absent of a tool-catalogue fingerprint
snapshot. { fingerprint, toolsJson, toolCount, releaseSha? }. INSERT ON CONFLICT(fingerprint) DO NOTHING.
Call POST /v/agent.toolcatalogue.snapshot with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.