> ## Documentation Index
> Fetch the complete documentation index at: https://usenaive.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Runtime & Brain Governance Tools

> The naive_teams_* and naive_brain_* governance MCP tools — the team's runtime, the belief queue, and how a refusal reaches a model.

Two families of MCP tools cover the parts of the platform an agent has to *reason about*
rather than merely call: the runtime its team actually runs on, and the queue in which a
proposed belief waits for a decision.

Both are listed **per tenant**. A tool you cannot see is one this tenant's Account Kit does
not enable — that is a product decision, and no call will change it. A tool you *can* see
may still refuse a specific call; that is authority, not scope, and the refusal tells you
what would change it.

<Warning>
  **The tool list is resolved once, when the session opens.** An Account Kit edit takes effect
  immediately at the gate but does not retract a tool already listed, so a long-lived session can
  show a tool whose primitive was switched off minutes ago. That drift is only ever *permissive* —
  the execution gate is re-evaluated on every call and denies — so the failure mode is a tool that
  refuses, never a tool that runs when it should not. Reconnect to refresh the list.
</Warning>

## Runtime tools

Every tool addresses one tenant user's runtime over **one control wire** — the same wire the REST
routes already drive, resolved to whichever runtime is registered for that tenant. There is no
carrier branch anywhere in these tools, and nothing you write should introduce one.

Requires the **`tasks`** primitive.

| Tool                  | Description                                                                                  | Notes                                   |
| --------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------- |
| `naive_teams_status`  | Which runtime this tenant is on, whether it is claimed, and a live reachability probe.       | read-only · degrades instead of failing |
| `naive_teams_board`   | The board: every task the runtime holds, with status and role. Filter by `status` or `role`. | read-only                               |
| `naive_teams_run`     | One run's status and transcript pointer, by `run_id`.                                        | read-only                               |
| `naive_teams_comment` | Post a comment onto a task, so the team can read it.                                         | queued through the outbox               |
| `naive_teams_unblock` | Clear a task's blocked state. `because` is required.                                         | queued through the outbox               |

<Note>
  **Writes are queued, not sent.** `naive_teams_comment` and `naive_teams_unblock` return when the
  command is durably held, which is not the same as the runtime having seen it. If the runtime
  is unreachable you receive a `wait_for_delivery` recovery step — **do not send the command
  again**. A second send is a second comment, or a second unblock.
</Note>

## Brain governance tools

The twenty-one `naive_brain_*` content tools cover *what the brains know*. These five cover
*how something comes to be known*: the writeback envelope a claim arrives on, the proposal it
becomes, and the decision that resolves it.

Requires the **`brain`** primitive, which is opt-in — an Account Kit with no `brain` entry is
a refusal, not a default.

| Tool                          | Description                                                                   | Notes                        |
| ----------------------------- | ----------------------------------------------------------------------------- | ---------------------------- |
| `naive_brain_proposals`       | The queue of proposed beliefs. Filter by `status`, `object_type` or `run_id`. | read-only                    |
| `naive_brain_proposal`        | One proposal, with its full decision trail.                                   | read-only                    |
| `naive_brain_decide_proposal` | Accept or reject a proposal. `because` is required.                           | accept is **approval-gated** |
| `naive_brain_writebacks`      | The envelopes proposals arrived on.                                           | read-only                    |
| `naive_brain_writeback`       | One envelope and every proposal it carried.                                   | read-only                    |

<Warning>
  `decision: "accept"` canonizes a claim into the company's source of truth, so an agent call
  **parks for a human**. You get an approval id, not a result. `decision: "reject"` applies
  immediately, with you recorded as the reviewer.
</Warning>

## How a refusal reaches you

A refused call does not return a bare error. It returns a **verdict envelope**, carried in
both `structuredContent` and the text block:

```json theme={"theme":"css-variables"}
{
  "ok": false,
  "verdict": "deny",
  "reason": "capability_denied",
  "action": "naive_teams_board",
  "layer": "company",
  "retryable": false,
  "repeat": 1,
  "message": "Not allowed by AccountKit \"Default\": primitive_disabled_by_kit",
  "error": { "code": "forbidden", "hint": "…", "details": { "reason": "primitive_disabled_by_kit" } },
  "recovery": [
    {
      "kind": "request_capability",
      "change": "Enable the 'tasks' primitive for this tenant.",
      "human_action": "Tell the user this capability is switched off for their account and stop."
    }
  ],
  "alternatives": []
}
```

Read three fields, in this order:

1. **`retryable`** — `true` only when the envelope also carries a `retry_after` recovery step,
   which happens only for `verdict: "unavailable"`. If it is `false`, calling again cannot
   help: the decision is a function of a policy snapshot your calls do not change.
2. **`recovery[]`** — the one thing that would change the outcome. It names a **tool** or a
   **human act**, never a shell command.
3. **`alternatives[]`** — other tools that would work right now.

### Verdicts

| Verdict       | `isError`   | What it means                                                                                        |
| ------------- | ----------- | ---------------------------------------------------------------------------------------------------- |
| `deny`        | `true`      | A decision. Retrying is a loop.                                                                      |
| `park`        | **`false`** | A human must approve. This is a successful deferral, not a failure.                                  |
| `unavailable` | `true`      | An outage. The only retryable verdict.                                                               |
| `attest`      | `false`     | Evidence is required before this may proceed. **Declared, never emitted on this build** — see below. |

<Note>
  `attest` is a member of the verdict union and **nothing produces it today**: measured across the
  API, the platform packages and the governor, the only occurrence of the string is the type
  declaration itself. Handle it if you are writing an exhaustive `switch` — the union is closed and
  will not grow silently — but do not build a flow that waits for one.
</Note>

<Note>
  **Three vocabularies, and they are not the same set.** The closed decision engine answers
  `allow | deny | freeze`. `POST /v1/policy/explain` answers `allow | deny | park`. This envelope
  adds `attest` and `unavailable` on top, because a model needs to tell an outage from a decision.
  Do not map one onto another by name alone.
</Note>

A `park` gives you `wait_for_approval` with an `approval_id`, an `expires_at`, and
`on_expiry: "deny"` — an approval window that elapses becomes a refusal. Poll
`naive_approvals_get`. You cannot approve your own request.

If you refuse the same call three times, the envelope stops offering choices: you get exactly
one `escalate_to_human` step and no alternatives. That is the signal to stop and tell the
user.

## Connections enumeration is filtered

`naive_connections_tools` now filters its output through the same Account Kit rule
`naive_connections_execute` obeys. A toolkit the kit does not permit is refused with a
`request_toolkit` recovery naming it, rather than enumerated; per-tool `enable`/`disable`
filters are applied to the result, and `withheld_by_policy` reports how many names were
removed. Calls that worked before still work — every kit ships permissive by default, so this
bites only where somebody deliberately narrowed one.
