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

# Governance

> The underlying class. Use the decorator API for most code.

```python theme={null}
from rubric import Governance
```

`Governance` owns the agent's signed identity, the bundle cache, the audit sink, and the trace uploader. Most application code should use the [decorator API](/sdk-python/init) instead — `rubric.init()` once, `@rubric.tool` per function. Reach for `Governance` directly when you need:

* **Multiple agents in one process.** The singleton supports one identity at a time; `Governance` instances are independent.
* **Tests.** Construct a `Governance` per test for isolation.
* **Library code.** Don't claim the process-wide singleton on a consumer's behalf — accept a `Governance` via dependency injection.

## `Governance.bootstrap(...)`

Class method that builds a fully-initialized instance.

```python theme={null}
@classmethod
def bootstrap(
    cls,
    *,
    enrollment_token: str | None = None,
    agent_name: str | None = None,
    api_url: str | None = None,
    bundle_poll_seconds: float = 30.0,
    autostart: bool = True,
    dlp: bool | DlpMode | Detector | None = None,
) -> "Governance":
```

### Parameters

| Param                 | Type                                  | Default                   | Notes                                                                                                |
| --------------------- | ------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- |
| `enrollment_token`    | `str \| None`                         | `AG_ENROLLMENT_TOKEN` env | **Required.** Long-lived org token. Mint one in **Enrollment**.                                      |
| `agent_name`          | `str \| None`                         | `AG_AGENT_NAME` env       | **Required.** Stable name → stable identity. Same name across restarts reuses the same identity row. |
| `api_url`             | `str \| None`                         | `AG_API_URL` env          | The Rubric API URL we gave you during onboarding.                                                    |
| `bundle_poll_seconds` | `float`                               | `30.0`                    | How often to poll for new bundle versions.                                                           |
| `autostart`           | `bool`                                | `True`                    | Start the audit sink and bundle poller immediately.                                                  |
| `dlp`                 | `bool \| DlpMode \| Detector \| None` | `AG_DLP` env or `None`    | DLP detector. See [DLP](/concepts/dlp).                                                              |

### Bootstrap resolution

Both `enrollment_token` and `agent_name` are required. If either is missing (after env-var fallback), `bootstrap()` raises `ValueError` — the SDK will not start unauthenticated.

### Example

```python theme={null}
from rubric import Governance

with Governance.bootstrap(agent_name="payments-bot") as gov:
    # AG_ENROLLMENT_TOKEN read from env automatically
    ...
```

## Lifecycle

`Governance` is a context manager. The recommended pattern:

```python theme={null}
with Governance.bootstrap(agent_name="my-bot") as gov:
    # Optional: block until first bundle pull completes
    gov.wait_until_ready(timeout=10.0)

    # ...your agent loop...
```

The `with` block calls `gov.shutdown()` automatically on exit, which:

* Stops the bundle poller.
* Flushes any queued audit events.
* Closes the trace uploader's HTTP session.
* Stops the JWT refresh thread.

## Properties

### `agent_id: str`

The stable id bound to the JWT's `sub` claim. Set on bootstrap; never changes.

```python theme={null}
print(gov.agent_id)
# payments-bot
```

### `current_bundle: Bundle | None`

The most recently pulled policy bundle. `None` until the first pull completes.

```python theme={null}
gov.wait_until_ready(timeout=10.0)
b = gov.current_bundle
print(f"v{b.bundleVersion} with {len(b.policies)} policies")
```

## Methods

### `wait_until_ready(timeout=10.0) -> bool`

Block until the first bundle pull completes (success or failure). Returns `True` if a bundle was pulled, `False` on timeout.

Optional — `evaluate()` is safe to call before the first pull (default-allow). But if you want your agent to stop and wait for policies, call this first.

### `evaluate(tool_name, *, session_id, ...) -> EvaluationResult`

Evaluate a tool call against the current bundle and ship an audit event. See [`evaluate()`](/sdk-python/evaluate) for the full signature.

### `start() / shutdown()`

Manual lifecycle for cases where the `with` block doesn't fit (e.g., long-lived service classes). Don't call `start()` more than once.

## Without `bootstrap`

For tests and advanced flows, you can pass a pre-built `TokenStore`:

```python theme={null}
from rubric import Governance
from rubric.identity import TokenStore

store = TokenStore(...)  # already initialized
gov = Governance(token_store=store, api_url="https://api.your-rubric-url.example.com")
```

Reserve this for tests. In application code, always use `bootstrap()`.
