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

# Observe runs, usage, and governance evidence

> Build a Praxa operations view from run projections, resumable events, usage evidence, webhook deliveries, traces, skills, and coverage.

Praxa has two observability planes. Execution Fabric exposes personal-tenant
v1 run, event, usage, and webhook-delivery projections. A deployment-specific
Integration Gateway exposes mission events, traces, skills, context, world
certificates, and reference coverage through `@praxa/sdk`.

## Prerequisites

Before you begin, prepare:

* a written success criterion and proof boundary for the integration under test;
* synthetic tenants, subjects, credentials, and lifecycle fixtures;
* redacted observability fields and a secure location for test evidence;
* an owner for rollback, cleanup, and unresolved qualification gaps;
* an acceptance assertion that proves run, event, usage, delivery, and trace evidence correlate without leaking tenant data.

## Execution Fabric dashboard

### Read one run

```js theme={null}
const response = await fetch(`https://api.praxa.io/v1/runs/${runId}`, {
  headers: { authorization: `Bearer ${process.env.PRAXA_API_KEY}` },
});
if (!response.ok) throw new Error(await response.text());
const run = await response.json();
```

Treat `queued`, `running`, and `awaiting_approval` as non-terminal. Treat only
`completed`, `failed`, and `cancelled` as terminal.

### Resume the event stream

```js theme={null}
const response = await fetch(
  `https://api.praxa.io/v1/runs/${runId}/events`,
  {
    headers: {
      authorization: `Bearer ${process.env.PRAXA_API_KEY}`,
      accept: "text/event-stream",
      ...(lastEventId === undefined ? {} : { "last-event-id": lastEventId }),
    },
  },
);

if (!response.ok || !response.body) throw new Error(await response.text());
// Parse SSE frames, require numeric increasing IDs, and persist each cursor.
```

Use a tested SSE parser rather than splitting arbitrary network chunks on
newlines. One SSE frame may span chunks, and one chunk may contain several
frames.

### Read usage evidence

```bash theme={null}
curl --get https://api.praxa.io/v1/usage \
  -H "Authorization: Bearer $PRAXA_API_KEY" \
  --data-urlencode "from=2026-08-01T00:00:00.000Z" \
  --data-urlencode "to=2026-09-01T00:00:00.000Z" \
  --data-urlencode "group_by=day"
```

Usage reports tenant-scoped requests, runs, tokens, model calls, tool calls,
and billable amount. `toolCalls` remains zero until a trustworthy public
per-task tool-call source exists.

### Inspect webhook deliveries

```bash theme={null}
curl --get https://api.praxa.io/v1/webhook-deliveries \
  -H "Authorization: Bearer $PRAXA_API_KEY" \
  --data-urlencode "run_id=$RUN_ID" \
  --data-urlencode "limit=50"
```

Page with `nextCursor`. Delivery status is `pending`, `delivering`,
`succeeded`, `retrying`, or `dead_letter`.

## Integration Gateway diagnostics

```ts theme={null}
const [mission, trace, skill, coverage] = await Promise.all([
  client.getMission(runId),
  client.getTrace(traceId),
  client.getSkill(skillId),
  client.getReferenceCoverage(),
]);
```

Use the narrowest OAuth scopes:

| Read                              | Scope           |
| --------------------------------- | --------------- |
| Mission and mission events        | `missions:read` |
| Redacted trace                    | `traces:read`   |
| Governed skill and evidence state | `skills:read`   |
| Context goals                     | `context:read`  |
| World-model certificates          | `world:read`    |
| Reference coverage                | `coverage:read` |

Coverage describes registered reference behavior and evidence. It is not a
production-readiness guarantee for your deployment.

## Recommended data model

Persist identifiers and immutable evidence, not credentials:

```ts theme={null}
type ObservedRun = {
  plane: "execution_fabric" | "integration_gateway";
  tenantKey: string;
  runId: string;
  status: string;
  lastEventId?: string;
  lastSequence?: number;
  updatedAt: string;
  terminal: boolean;
};
```

Keep tenant authority server-derived. Do not let a browser choose an arbitrary
tenant ID for a backend read.

## End-to-end verification

1. Create a disposable run and save its returned identifier.
2. Read that exact run and reject unknown or foreign IDs.
3. Stream, persist a cursor, disconnect, and resume without regressing sequence.
4. Require one terminal state or explicitly record a timed-out verification.
5. Query a range containing the run and confirm usage remains tenant scoped.
6. If using webhooks, correlate delivery `run_id` with the run and deduplicate by `event_id`.
7. For the Integration Gateway, compare trace, skill, and coverage outputs only within their documented scope and deployment.
8. Revoke the disposable credential and require all subsequent reads to fail closed.

## Troubleshooting

| Symptom                                       | Resolution                                                                                   |
| --------------------------------------------- | -------------------------------------------------------------------------------------------- |
| Dashboard says success but outcome is unknown | Require terminal readback or an explicit incomplete verification state.                      |
| Metrics cannot be correlated                  | Carry safe request, run, event, delivery, trace, and test identifiers across boundaries.     |
| Logs contain sensitive data                   | Stop collection, rotate exposed credentials, and replace raw payloads with bounded metadata. |
| One green test is treated as production proof | Track package, mock, authenticated runtime, deployment, and user verification separately.    |

## Best practices

* Define the expected observable result before running the test.
* Separate positive, denial, isolation, replay, degraded-state, and cleanup lanes.
* Use synthetic data and credential fingerprints rather than secrets.
* Record unresolved checks as pending instead of inferring success.
* Keep rollback and owner information beside the release evidence.

## Optimize for production

* Run cheap contract and fake tests before authenticated canaries.
* Parallelize only independent test lanes and cap external side effects.
* Sample high-volume telemetry while retaining every denial, conflict, and terminal failure.
* Measure pass rate, p50/p95 latency, retry budget, isolation failures, cleanup completion, and time to diagnose.

Optimize only after the correctness and isolation matrix passes. Lower latency or cost is not an improvement if verified outcomes, authority checks, or recovery rates regress.

## Cleanup and next steps

1. Revoke every disposable key and OAuth grant.
2. Remove test endpoints, provider records, candidates, and local artifacts.
3. Close or explicitly record unresolved runs and verification gaps.
4. Publish only redacted results, exact versions, timestamps, and rollback instructions.

After cleanup, run the [shared integration test matrix](/tutorials/test-your-integration) and record any environment-specific check that remains pending.

## Frequently asked questions

### What proves this tutorial works?

The minimum observable result is that run, event, usage, delivery, and trace evidence correlate without leaking tenant data. A compile, package import, mocked response, or initial admission alone does not prove the complete workflow.

### Can a browser, mobile app, or model prompt hold the credential?

No. Evidence contains credential fingerprints and safe identifiers, never live credentials or raw sensitive payloads.

### How should an ambiguous mutation be retried?

Persist the exact logical input and idempotency key before the first attempt. Reconcile through authoritative readback or replay the exact request with that same key before creating new work.

### What should we monitor after release?

Monitor test pass rate, p50/p95 latency, authorization denials, replay conflicts, isolation failures, cleanup completion, and diagnosis time. Alert on authorization bypass, cross-tenant disclosure, repeated conflicts, or cleanup failure.
