# Understand (/docs/govern/understand)

Understand is the first move of the Trust Loop. Once an agent is
[connected](/docs/govern/connect-your-agents), every run lands as a trace.
AISquare extracts the reasoning behind it, so you see why the agent decided
what it did, not just what it returned. A transcript tells you what was said. The
reasoning graph tells you what the agent believed, what it leaned on, and how it
got from one to the other.

## Your agent's reasoning, as a graph [#your-agents-reasoning-as-a-graph]

This is one refund-agent run, laid out as the graph AISquare records. It
shows the question, the context the agent fetched, the evidence and the one
assumption it leaned on, the policy it cleared, and the decision it reached. Drag the canvas to pan, scroll to zoom, and follow the
solid line for the timeline and the dashed lines for what each step produced and
consumed.

The recorded run, step by step: user question ("Can I get a refund on order
\#4821?") to refund agent; the agent fetches context (get\_order); two pieces of
evidence (order #4821, $39, placed 6 days ago; the 30-day refund window) and one
assumption (customer tier resolved to standard, confidence 0.72) feed the
reasoning step (claude-opus 4.8); a policy check (refund-auto-approve) passes;
the agent makes its claim (the refund is within policy limits) and reaches a
decision (auto-approve), which is then queued for optional human review because
the tier was assumed rather than confirmed.

## Read it over the API [#read-it-over-the-api]

Everything the graph above shows is also a plain HTTP read, so your own tooling
(a script, a CI job, a coding agent) can pull the same reasoning the dashboard
renders. Three calls cover this page: list the runs, fetch the graph, fetch the
reasoning.

```bash title="Setup (every read on the Trust Loop pages uses these)"
export EXPLAINABILITY_GATEWAY_URL="https://<your-workspace>.aisquare.studio"
export EXPLAINABILITY_API_KEY="AIS_..."        # studio API key
export STUDIO_ID="<your-studio-id>"
```

<Callout intent="info" title="Reads need a studio key">
  Reads are studio-scoped, so use a **studio API key**. A workspace ingest key
  sends traces but answers every read with `403 Studio ID mismatch`. That is the
  key type, not your permissions; mint a studio key from the dashboard or ask
  your AISquare contact for one.
</Callout>

```bash title="List recent runs"
curl -s -H "X-API-KEY: $EXPLAINABILITY_API_KEY" \
  "$EXPLAINABILITY_GATEWAY_URL/v1/studios/$STUDIO_ID/ui/runs?limit=10"
```

```json title="Response (trimmed)"
{
  "status": "ok",
  "total_count": 66,
  "runs": [
    {
      "run_id": "8b41f0c2f4a340d2b7f9d3e6a1c25b90",
      "status": "ready",
      "agent_name": "refund-agent",
      "title": "Refund Agent · Aug 19 09:12",
      "started_at": "2026-08-19T09:12:41Z",
      "duration_ms": 1840.0,
      "node_count": 6,
      "error_count": 0
    }
  ],
  "next_offset": 10
}
```

The run id is the trace id your agent logged, so an agent that just finished a
run can jump straight to its own record.

Request parameters for the run list:

| Parameter              | Type               | Default        | Notes                                                                          |
| ---------------------- | ------------------ | -------------- | ------------------------------------------------------------------------------ |
| `limit`                | integer            | `100`          | 1 to 500                                                                       |
| `offset`               | integer            | `0`            | Pass the previous response's `next_offset` to page                             |
| `sort`                 | string             | `updated_desc` | `updated`, `duration`, `cost`, `tokens`, `errors`, each with `_desc` or `_asc` |
| `q`                    | string             | none           | Free-text search                                                               |
| `agent`                | string             | none           | Exact agent name                                                               |
| `status`               | string, repeatable | none           | Filter by run status, for example `ready`                                      |
| `has_errors`           | boolean            | none           | `true` returns only runs with errors                                           |
| `has_policies`         | boolean            | none           | `true` returns only runs with policy hits                                      |
| `date_from`, `date_to` | string             | none           | Timezone-aware ISO-8601 only, for example `2026-08-01T00:00:00Z`               |

The most useful response fields (the response carries more):

| Field                           | Type            | Meaning                                                                   |
| ------------------------------- | --------------- | ------------------------------------------------------------------------- |
| `total_count`                   | integer         | Total matches across all pages                                            |
| `next_offset`                   | integer or null | Pass as `offset` for the next page; null on the last page                 |
| `poll_after_ms`                 | integer or null | Suggested wait before you poll again                                      |
| `runs[].run_id`                 | string          | Equals the trace id your agent logged                                     |
| `runs[].status`                 | string          | Run build state; `ready` means complete                                   |
| `runs[].agent_name`             | string or null  | The name rules attach to                                                  |
| `runs[].started_at`, `ended_at` | string or null  | ISO-8601 timestamps                                                       |
| `runs[].duration_ms`            | number or null  | Wall-clock time of the run                                                |
| `runs[].node_count`             | integer         | Steps on the reasoning graph                                              |
| `runs[].token_count`            | integer or null | Total tokens                                                              |
| `runs[].cost_usd`               | number or null  | Total cost                                                                |
| `runs[].error_count`            | integer         | Failed steps                                                              |
| `runs[].is_governed`            | boolean or null | `true`: a live gate ran. `false`: ungoverned. `null`: unknown (older run) |

Two more reads return the two views on this page:

```bash title="The graph and the reasoning"
curl -s -H "X-API-KEY: $EXPLAINABILITY_API_KEY" \
  "$EXPLAINABILITY_GATEWAY_URL/v1/studios/$STUDIO_ID/runs/$RUN_ID/graph"
curl -s -H "X-API-KEY: $EXPLAINABILITY_API_KEY" \
  "$EXPLAINABILITY_GATEWAY_URL/v1/studios/$STUDIO_ID/runs/$RUN_ID/rml"
```

```json title="Reasoning response (trimmed)"
{
  "extraction_confidence": 0.86,
  "claims": [
    "The refund is within policy limits.",
    "No manual review is required for this order."
  ],
  "inference_chain": [
    {
      "reasoning": "Order total $39 is under the $50 auto-approve ceiling.",
      "conclusion": "Amount is inside the auto-approve limit."
    }
  ],
  "assumptions": [
    {
      "proposition": "Customer tier resolved to standard",
      "depends_on": "tier was inferred, not confirmed"
    }
  ]
}
```

`/graph` returns `nodes` and `edges`. Each node has an `id`, a `type`
(`llmNode`, `toolNode`, `retrieverNode`, `chainNode`, `agentNode`), and a
`data` object with the step's `model_name`, `duration_ms`, `token_count`,
`cost_usd`, and span identifiers, the same facts the step cards below show.
`/rml/v3` is the newer structured document, and its `findings.results[]`
entries carry the fingerprints the
[Fix](/docs/govern/fix#close-the-loop-over-the-api) write path accepts.
Analyses are extracted asynchronously after a run lands, so a `404` here means
"not computed yet", not "failed"; give it a minute and read again.

Reasoning response fields:

| Field                   | Type            | Meaning                                                                      |
| ----------------------- | --------------- | ---------------------------------------------------------------------------- |
| `extraction_confidence` | number, 0 to 1  | How faithfully the reasoning was captured. Low means read the raw trace      |
| `low_confidence`        | boolean         | Set when the extraction itself is uncertain                                  |
| `claims`                | array of string | What the agent asserted and acted on                                         |
| `evidence_attribution`  | array           | What each claim rests on, with a confidence per item                         |
| `inference_chain`       | array of object | One `reasoning` and `conclusion` pair per step, in order                     |
| `assumptions`           | array of object | Each has `proposition` and `depends_on`; the gaps the agent filled in itself |
| `extractor_model`       | string or null  | Null when extraction ran with the platform key; not a failure                |
| `extracted_at`          | string          | When the analysis was extracted                                              |
| `rml_version`           | string          | The document format version                                                  |

Prefer tools over raw HTTP? The
[learnings MCP server](/docs/use-in-your-agent#drive-the-platform-from-your-coding-agent)
wraps every read on this page for Claude Code, Cursor, and any MCP-capable
coding agent.

## A run is a graph, not a transcript [#a-run-is-a-graph-not-a-transcript]

Each run is recorded as a graph of steps. A step is one unit of work: an LLM
call, a tool call, a retrieval, a logic gate, a memory read. Every step carries
its model or tool, its latency, tokens, and cost, a status, and the policies it
triggered. This is the same anatomy you see in the dashboard.

<div className="liquid-glass my-6 p-5">
  <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
    <TraceStepCard type="tool" title="Look up order" subtitle="get_order . tool call" latency="0.21s" cost="$0.000" status="ok" policies="['#tool', 'pii: redacted']" />

    <TraceStepCard type="retrieval" title="Search refund policy" subtitle="kb.refunds . vector search" latency="0.34s" tokens="1,204" cost="$0.002" status="ok" policies="['#retrieval', 'k=6']" />

    <TraceStepCard type="llm" title="Assess refund eligibility" subtitle="claude-opus 4.8 . reasoning step" latency="0.82s" tokens="412" cost="$0.004" status="running" policies="['#inference', 'policy: risk-scoring']" />

    <TraceStepCard type="logic" title="Branch on customer tier" subtitle="tier == standard . gate" latency="0.01s" status="ok" />
  </div>
</div>

Reading a step left to right: a refund agent looked up the order, searched the
refund policy, reasoned over both, then branched on the customer tier. The third
card is mid-execution, which is how a live run reads while the LLM step is still
thinking. You can open any run as a flow diagram, as this graph, or as a
plain-English narrative; all three are the same recorded decision.

## A reasoning graph is not a knowledge graph [#a-reasoning-graph-is-not-a-knowledge-graph]

A knowledge graph stores what your organization knows: entities and the
relationships between them. It is a map of facts, and it changes slowly. A
reasoning graph records something a knowledge graph never holds: how an agent
thought on one specific run. Which claims it committed to, which evidence it
weighed, which assumptions it filled in, and how those connected to the
decision it reached.

The two are complements, not competitors. An agent may well consult a knowledge
graph as evidence, and that lookup appears as a step on the reasoning graph.
But when someone asks why the agent decided what it did, a map of what was
known cannot answer. Only the record of how it was used can, and that record is
what AISquare captures.

## Claims, evidence, and assumptions [#claims-evidence-and-assumptions]

Inside a reasoning step, AISquare structures the model's thinking into three
parts. This is the reasoning markup (RML) view, and it is the clearest answer to
"why did it decide that?"

* **Claims** are what the agent asserted, the conclusions it acted on.
* **Evidence** is what each claim rests on, every item carrying a confidence
  score so a weak input is visible rather than buried.
* **Assumptions** are the gaps the agent filled in for itself: inferred facts
  it was not given directly. Surfacing them is the point: an assumption you
  can see is one you can challenge.

The inference chain then shows, step by ordered step, how the agent moved from
evidence and assumptions to its claims.

<div className="liquid-glass my-6 p-5">
  <RMLPanel
    extractionConfidence="0.86"
    claims="[
    'The refund is within policy limits.',
    'No manual review is required for this order.',
  ]"
    evidence="[
    { text: 'Order #4821 total $39, placed 6 days ago', confidence: 0.94 },
    { text: 'Refund window for standard tier is 30 days', confidence: 0.91 },
    { text: 'Customer tier resolved to standard', confidence: 0.72 },
  ]"
    inferenceChain="[
    'Order total $39 is under the $50 auto-approve ceiling.',
    'Placed 6 days ago, inside the 30-day standard window.',
    'No prior refund on this order, so no duplicate-refund risk.',
    'Therefore the refund is auto-approvable without review.',
  ]"
  />
</div>

The third piece of evidence here, that the customer tier resolved to standard,
carries a noticeably lower confidence than the rest. That is an assumption the
agent leaned on: tier was inferred, not confirmed. Seen on the graph, it is the
first thing a reviewer would probe, and it is exactly the kind of weak link the
[Fix](/docs/govern/fix) step exists to correct.

<Callout intent="note" title="Extraction confidence is its own signal">
  The bar at the top of the panel is the confidence of the extraction itself, how
  sure AISquare is that it captured the agent's reasoning faithfully. A low
  extraction confidence is a prompt to read the raw trace, not to trust the
  structured view blindly.
</Callout>

## Why this matters [#why-this-matters]

Structured reasoning is what turns a black-box run into a decision you can defend
and improve.

* **Audit.** When someone asks why an agent did what it did, you point at the
  claims, the evidence, and the rule it triggered, not a wall of transcript.
* **Debugging.** A wrong answer usually traces to one weak claim or one bad
  assumption. The graph shows you which, so you fix the cause, not the symptom.
* **Trust.** Reasoning you can inspect is reasoning a regulator, an auditor, or a
  customer can be shown.

Understanding a decision is the input to acting on it. From here the loop
continues: [Prevent](/docs/govern/prevent) stops a bad action before it runs,
[Fix](/docs/govern/fix) corrects a decision that already happened, and
[Remember](/docs/govern/remember) carries the result forward so the next run
starts ahead.

## Next steps [#next-steps]

<Cards>
  <Card title="Prevent" href="/docs/govern/prevent" description="Enforce policy at the decision point, before an action runs." />

  <Card title="Fix" href="/docs/govern/fix" description="Correct a decision in context and keep the correction on the record." />

  <Card title="Core Concepts" href="/docs/getting-started/core-concepts" description="The entities behind the reasoning graph and the API." />

  <Card title="Connect your agents" href="/docs/govern/connect-your-agents" description="Bring an agent from any framework. It keeps running as-is." />
</Cards>
