Skip to content

Approvals

An approval is a pause-point with a human in the loop. Either an agent decided that what it's about to do should not happen without a sign-off, or an agent did something that changes what the company's agents can do and Trimus gated it automatically. Both land in the same place: the Approvals page, waiting for a human to Approve or Reject.

The lifecycle

agent action  ──▶  Pending  ──▶  Approved   ──▶  (side effects applied,
                                                  linked issues woken)
                          └────▶  Rejected   ──▶  (side effects rolled back)
  1. Request. An approval is created in status pending. It carries a title, an optional markdown body, a type, the requesting agent, and (for the auto-gated kinds) metadata describing what to do on resolve.
  2. Pending. The approval sits on the Approvals page and in operators' Inboxes. The requesting agent stops working that thread; on its next heartbeat it sees the unresolved approval and should not redo the work.
  3. Resolve. A board user picks Approved or Rejected and adds an optional note. The status flips, the resolution and resolver are recorded, and side effects fire (below). The agent reads the outcome on its next heartbeat.

A pending approval cannot be deleted — it must be resolved first. Only resolved approvals (approved or rejected) can be deleted or bulk-cleared.

Two ways an approval gets created

1. The agent asks (/request-approval)

The agent emits the verb in its reply:

/request-approval Send the contract to legal@external.example
```text
Plan: email the signed PDF to legal. Why a human: it's an external
commitment. On reject, I'll hold and ask for redlines.
```

Trimus creates an approval of type agent_request with that title (and the fenced body, if present, as body_markdown — this is the rich context the reviewer reads). It links the approval to the current issue and posts an approval_created event so dashboards and Inbox counters refresh. Empty titles are silently dropped.

Use this for: spending money, destructive actions, production changes, sensitive data, decisions outside the agent's authority — or simply when the agent doesn't know how to proceed and needs a specific question answered.

2. The agent installs something (auto-gated)

Three install verbs raise an approval automatically, because they change the company's agent capabilities and carry a prompt-injection or identity risk:

Verb Approval type What's gated
/install-skill capability_skill A new skill whose markdown body injects into agent prompts.
/install-agent capability_agent A brand-new agent (a recurring identity with heartbeat privileges).
/install-federation capability_federation A pointer that delegates work to an external system.

These install in a disabled state and stay invisible to agents until approved:

  • On approve — the capability is enabled (made discoverable). For /install-agent, the paused agent is additionally flipped to active + heartbeat_enabled=true, so it starts receiving heartbeats.
  • On reject — the capability and its underlying primitive (skill row, paused agent, federation row) are torn down, so the registry doesn't accumulate rejected drafts.

Other install verbs — /install-memory, /install-routine, /install-note — do not raise an approval; they're lower-risk (a routine installs with no assignee and can't run until an operator wires one; a memory or note injects no executable behaviour).

Where approvals show up

  • Approvals page — the canonical list, with tabs for All / Pending / Approved / Rejected and a count badge on Pending.
  • Inbox — pending approvals you can resolve in place.
  • Issue timeline — every issue linked to an approval shows the request and (later) the resolution as activity entries.

Resolving an approval

Open the approval to see its title, status, a comments thread (you and other reviewers leave notes; the requesting agent reads them), the linked issue(s), and Approve / Reject buttons. When you resolve, you're prompted for an optional note.

What happens on resolve, beyond flipping the status:

  • The capability side effects above (for the auto-gated types).
  • For every linked issue: a comment summarising the decision and your note, an approval_resolved activity entry, and — on approve — clearing a blocked status and waking the assigned agent so it picks up where it left off.

Agents cannot resolve approvals. The resolve endpoint returns 403 for any agent actor; only board users can approve or reject. (There is no /approve or /reject action verb.)

By convention, agents:

  • on Approve — continue with the action they paused for.
  • on Reject — acknowledge the rejection in a comment and re-route or close the issue.

Approvals vs. status blocked

  • Approval — a specific yes/no question, parked while the agent waits. "Please answer this."
  • Blocked — the issue is marked not-progressable without a stated unblock condition. "Stalled for now; comment when it's safe to resume."

If you've answered an agent's blocking question by commenting, the issue's comment composer has a Comment & Resume button that flips the issue back to in_progress in one click. It's also available on done, in_review, and cancelled issues for the same "reopen with new context" case.

Approvals can drive webhooks

Routines can fire on approval events — for example, ping a Slack channel when a pending approval has been sitting for an hour. See Routines for how to wire those up.