# Case study: Dramatyze (/docs/case-study)
Dramatyze is a product the AISquare team built fast, in the open, while running
on AISquare itself. This is a build-velocity and dogfooding story. It is not a
customer governance metric. What it shows is what a small team can ship when the
agent it is building leans on the same governed spine these docs describe.
The numbers come straight from the commit and work-session record below: 30.6
hours of tracked sessions (shown rounded), 569 commits (93 on the backend and
476 across the two frontend builds), and 3 contributors. They measure how the
work got done, not how a customer's agents are governed in production.
## What the timeline shows [#what-the-timeline-shows]
The build ran in distinct phases rather than one continuous grind, which is why
30.6 tracked hours covers more than a month of calendar time.
* **Backend first (Feb 11 to Feb 22).** The backend started on FastAPI and moved
to Django early, then settled into a steady run of commits up to the v1
release. This is the 93 backend commits.
* **A real gap (a Vegas and SF trip).** The record has an honest empty stretch
where no commits land. The work paused and then picked back up. Velocity here
is bursty, not uniform.
* **Frontend v1, then a v2 rebuild (Mar 1 onward).** The frontend was built,
then rebuilt as v2. The v2 execution push is where the work concentrates: 229
commits in a single day, the tallest spike on the chart.
* **Handoff to production (through Mar 17).** v2 reached a ready handoff and then
production, closing out the 476 frontend commits.
Three people did this: one on the backend, one on the first frontend, and one
driving the v2 frontend rebuild. The shape of the work, long quiet stretches
broken by short high-output pushes, is what you would expect from a small team
shipping a real product around the rest of their lives.
## Why this belongs in these docs [#why-this-belongs-in-these-docs]
The point of dogfooding is that the team building AISquare ships on AISquare. The
same [Govern](/docs/govern/connect-your-agents) step that wraps any agent wrapped
the Dramatyze agent, so its decisions landed on the
[reasoning and memory graph](/docs/collective-intelligence) like any other run.
The velocity above is the proof we care about for this page: governing an agent
did not slow the team down. The agent kept running as-is while every decision
started shipping traces.
What this page does not claim is a production governance metric, a blocked-attack
count, or a compliance outcome for a customer. Those are real, and they live with
the [Trust Loop](/docs) and [Collective Intelligence](/docs/collective-intelligence)
pages where they belong. Here the honest claim is narrower and still worth
making: a small team built and shipped a customer-facing product fast, on the
same spine we ask you to put your agents on.
## Next steps [#next-steps]
# Changelog (/docs/changelog)
Two streams of changes. The API changelog tags every entry Breaking or not (Stripe style). The product changelog is date headed (Anthropic style). Subscribe with the [RSS feed](/changelog.xml), or read the whole changelog as [Markdown](/changelog.md).
# Collective Intelligence (/docs/collective-intelligence)
Governing one agent gives you one explained decision. Governing every agent, run
after run, gives you something larger: a shared record of what your agents
decided, what your policies blocked, and what your team corrected. Collective
Intelligence is that record, alive: the reasoning-aware, auditable, governable
layer with the memory and context of both your agents and your humans.
It is not a stage in a pipeline. It sits parallel to everything else the
platform does, and the relationship runs both ways. When you
[trace a run](/docs/govern/understand), the agent's memory lands on the graph.
When someone works in a [Studio](/docs/studios/overview), the questions they ask
and the preferences they set land on the graph. And when
[policy enforcement](/docs/govern/prevent) fires, it is powered by what the
graph already holds. Each capability is built to feed Collective Intelligence,
and each is powered by it; that is the point where "we logged your decisions"
becomes "your agents and team get smarter together."
The earlier sections close the [Trust Loop](/docs) on a single decision.
This page is about what happens after the loop closes a thousand times. Every
trace, every verdict, and every correction lands in one place and starts to
compound.
## AI + BI = CI [#ai--bi--ci]
Artificial intelligence is necessary but not sufficient. The other half of the
system is brain intelligence: the judgment of the people who read an agent's
reasoning, overturn its weak claims, and tighten its policies. An agent without
human judgment repeats its mistakes at scale. Human judgment without a record
evaporates the moment the reviewer moves on. Collective Intelligence is what
happens when the two compound on the same graph:
> **AI + BI = CI.** Artificial intelligence, plus the brain intelligence of the
> humans in the loop, compounds into Collective Intelligence.
This is why human-in-the-loop is not a review chore bolted onto the side of the
platform. It is half of the equation. And it is why the payoff ships as
[Studios](/docs/studios/overview): a Studio is the room where humans and agents
work on the same record, which is exactly where collective intelligence is
produced and where it is used.
What you get is a governed, compounding, org-wide intelligence that combines
human intelligence and agentic intelligence in Studios. It is foundational
rather than bolted on, and it is what lets an organization protect its
operations with guardrails, govern them at runtime, and perform on reasoning
that can be inspected and reused.
## The reasoning and memory graph [#the-reasoning-and-memory-graph]
Each governed decision is already structured. The reasoning behind it is a graph
of claims, evidence, and an inference chain. The policy result is a verdict
against a named rule. The correction a reviewer makes is an edit to that graph.
Collective Intelligence keeps all of it, linked, in one persistent reasoning and
memory graph. This is [not a knowledge
graph](/docs/govern/understand#a-reasoning-graph-is-not-a-knowledge-graph) of
your organization's facts; it is the record of how your agents reasoned and how
your team corrected them.
The reasoning graph is the base of the platform; Collective Intelligence is
what compounds on it. And it is not only agent runs that land there. What
happens in a Studio writes in too: the questions people ask, the preferences
they set, the corrections creators make. Agents and humans build the same
memory, which is why the layer holds the context of both.
Because the graph stores the reasoning rather than the raw prompt and response,
it does not belong to any single model or framework. A decision an Agno agent
made last month is the same shape as one a LangGraph agent makes today: claims,
evidence, verdict, outcome. That is what makes the memory portable. Swap the
model, change the framework, and the accumulated context still applies, because
it was never tied to either.
Four things persist on the graph and become reusable:
A new run does not start from nothing. It starts with the relevant slice of this
graph already in context: the evidence that held up before, the rules that
fired, and the corrections a human already made on a decision like this one.
## The compounding-trust loop [#the-compounding-trust-loop]
The graph compounds because of a tight loop between the agent (the AI) and the
people who review it (the BI). Stated plainly:
* **What the agent learns is what the human reviews.** The reasoning the agent
records, its claims, evidence, and inference chain, is exactly what a reviewer
sees. There is no separate, hidden version of the decision. The human reviews
the same graph the agent will reuse.
* **What the human corrects is what the agent remembers.** A correction is not a
one-off override. It is written back to the graph as durable context, so the
next run inherits it instead of repeating the mistake.
Take a worked example. On an early run, a refund agent reasons about whether an
order qualifies for an automatic refund. A reviewer reads the reasoning, agrees
with most of it, and corrects one weak link: customer tier was inferred, not
confirmed. That correction is remembered.
The correction from run #312 now rides along as high-confidence evidence on
every later run. The agent did not just get a one-time fix; it got a standing
piece of context. The reviewer who made the correction does not have to make it
again, and neither does anyone else on the team.
The same compounding happens with policy. A rule that a reviewer tightened after
an incident keeps firing, with its citation, on every run that touches the same
kind of action. The proof that governance ran is part of the permanent record,
not a transient log line.
Trust compounds in both directions. The agent earns more autonomy on the
decisions it has reasoned through correctly before, and reviewers spend their
attention on what is genuinely new rather than re-checking settled ground.
## How this powers Studios, and how Studios power this [#how-this-powers-studios-and-how-studios-power-this]
A reasoning and memory graph that holds your team's accumulated decisions is not
just an audit trail. It is the raw material for the things your customers
actually use. This is the payoff that [Studios](/docs/studios/overview) turns
into shippable experiences.
* **Docs for repos** draw on the reasoning the graph already captured, so an
answer about a codebase carries the evidence and the decisions behind it, not
a guess.
* **Reports** are generated from governed decisions, so every figure traces back
to the verdicts and corrections that produced it.
* **Expert agents** inherit the corrections your team has already made, so a new
agent starts where the last one left off instead of relearning from zero.
In each case the experience is trustworthy because the intelligence under it was
governed first and remembered second. Govern is what makes the memory worth
keeping. Studios is what makes the memory worth building.
The flow runs both ways. Serving an experience also compounds the layer: the
questions users ask, the preferences they set, and the corrections creators
make all write back to the same graph. A Studio is not just a consumer of
Collective Intelligence; it is one of the places where it is made.
## Next steps [#next-steps]
# AISquare Documentation (/docs)
AISquare turns agent runs into governed, explainable decisions. This is the
narrative spine the rest of the docs follow:
> **Govern** your agents, then run the Trust Loop on every decision (Understand,
> Prevent, Fix, Remember), so that **Collective Intelligence** compounds and your
> teams ship it as **Studios**.
This is the scaffolded foundation (packets A1 to A3). The narrative landing,
governance blocks, and full content land in later packets. The sidebar shows
the planned information architecture.
## Start here [#start-here]
# Use these docs in your agent (/docs/use-in-your-agent)
These docs are built to be read by agents as well as people. You can connect
them to a coding agent over MCP, feed the whole corpus to a model as plain
text, or copy any single page as Markdown. This page shows each option and the
exact config to paste.
The MCP endpoint below is hosted by GitMCP and reads this public repository
directly. There is no AISquare-hosted server to run and no credentials to
manage. Point your client at the URL and you are done.
## Query the docs over MCP [#query-the-docs-over-mcp]
[GitMCP](https://gitmcp.io) turns this repository into a Model Context Protocol
server with no build step. It indexes the docs and exposes tools your agent can
call to search and fetch pages while it works. The endpoint is:
```text
https://gitmcp.io/AISquare-Studio/docs
```
### mcp.json [#mcpjson]
Most MCP clients read a JSON config that lists the servers they can reach. Add
this server to that file:
```json
{
"mcpServers": {
"aisquare-docs": {
"url": "https://gitmcp.io/AISquare-Studio/docs"
}
}
}
```
Some clients still expect a command-based (stdio) server rather than a remote
URL. For those, run the remote endpoint through `mcp-remote`:
```json
{
"mcpServers": {
"aisquare-docs": {
"command": "npx",
"args": ["mcp-remote", "https://gitmcp.io/AISquare-Studio/docs"]
}
}
}
```
### Add to Cursor [#add-to-cursor]
Cursor reads MCP servers from `~/.cursor/mcp.json` (global) or `.cursor/mcp.json`
in a project. Add the server there:
```json
{
"mcpServers": {
"aisquare-docs": {
"url": "https://gitmcp.io/AISquare-Studio/docs"
}
}
}
```
Reload Cursor, open Settings, and confirm `aisquare-docs` shows as connected
under MCP. Your agent can now search and fetch these docs as it answers.
Claude Code, Claude Desktop, Windsurf, and VS Code read the same `mcpServers`
shape. Drop the `aisquare-docs` block into that client's MCP config and point
it at the same URL.
## Feed the whole corpus to a model [#feed-the-whole-corpus-to-a-model]
Two routes expose these docs as plain Markdown that any model can read in one
request. They follow the [llms.txt](https://llmstxt.org) convention.
Use `/llms.txt` when you want a small map and let the model follow links. Use
`/llms-full.txt` when you want everything in one payload, for example to ground
a one-off question or seed a retrieval index.
## Copy a single page [#copy-a-single-page]
Every page in these docs carries its own AI affordances in the header, next to
the title:
* **Copy Markdown** copies the page as clean Markdown, ready to paste into a
chat or a prompt.
* **Open in ChatGPT, Claude, or Cursor** opens that assistant with the page
already loaded as context.
You can also fetch the raw Markdown of any page directly. Append `.md` to its
URL:
```text
https://docs.aisquare.studio/docs/getting-started/quickstart.md
```
The same URL without the suffix returns Markdown too when the request sends an
`Accept: text/markdown` header, so a crawler or agent gets Markdown while a
browser gets the rendered page.
Building an agent on AISquare and need something these surfaces do not cover?
Reach us at [bots@aisquare.studio](mailto:bots@aisquare.studio).
# The board (/docs/agent-orchestrator/board)
```sh
aisquare board -w
```
The watch board is a full-screen terminal app (installed with the `[tui]`
extra; without it you get a simpler auto-refreshing view). Board on the left,
live feed on the right, detail bar at the bottom.
## Session states [#session-states]
Every session shows what it is doing right now:
| Chip | Meaning |
| --------------------- | ------------------------------------------------------------------- |
| `βΆ working` | mid-turn, actively doing something |
| `βΈ waiting for input` | finished its turn, wants your next prompt |
| `π NEEDS YOU` | asked for permission or has been idle; the terminal bell rings once |
The states are driven by Claude Code lifecycle hooks, so they update within a
refresh interval of the real session, and one open board terminal is enough to
know who needs you next.
## Reading the feed [#reading-the-feed]
One line per team event, bot-style: who (role, color, emoji), the verb, the
content. Click or arrow onto any line and the detail bar shows the full,
unclipped text plus its task link and timestamp.
## Keys [#keys]
| Key | Action |
| --------- | -------------------------------------------------------------------------------- |
| `d` | flip the task table to the done archive: when each task closed and who closed it |
| `o` | open the selected item's session transcript at that exact moment |
| `t` | theme browser: stays open, every change applies instantly and autosaves |
| `a` | toggle feed autoscroll |
| `v` / `c` | select-text mode (a frozen, mouse-selectable feed) / copy the selection |
| `s` | save an SVG screenshot to `~/.aisquare/screenshots/` |
| `b` | show or hide the board pane (auto-hides on narrow terminals) |
| `r` / `q` | refresh now / quit |
Two of those deserve a sentence more:
**The done archive (`d`).** Completed work does not vanish. The archive lists
every closed task, newest first, with the closing time and the session that
closed it (attribution comes from the task event, so it survives the claim
being cleared).
**Transcript jump (`o`).** Sessions record where their Claude Code transcript
lives. Select a done task or any feed event and press `o`: the board suspends
and opens that session's transcript at the line nearest that moment, in your
`$EDITOR` (or `less`). Quit the viewer and you are back on the live board. It
answers "who did this and what exactly happened" in two keystrokes.
# Memory and reference (/docs/agent-orchestrator/memory-and-reference)
## Long-term memory [#long-term-memory]
The board is working memory. Durable knowledge (decisions, results, notes,
questions, review handoffs, task outcomes, reopen feedback) is additionally
distilled into a per-project brain by a detached background worker. The brain
is powered by the AISquare `gbrain` CLI (a separate, optional tool, not the
unrelated `gbrain` package on public npm). It never runs on the hot path, and
when `gbrain` is not installed the layer simply stays off; nothing else
changes.
```sh
aisquare recall "what did we decide about auth?" # search the brain
aisquare team distill # drain the pipe into it now
aisquare team distill --all # backfill from the beginning
aisquare doctor # includes brain health + lag
```
`recall` drains any undistilled backlog before searching, so the first recall
on a busy project initialises the brain and takes a few seconds; after that it
is instant. Brains are created with embeddings off; set
`AISQUARE_BRAIN_EMBED=1` if you want distilled pages embedded (uses your
`OPENAI_API_KEY`, only at distill time).
## Environment knobs [#environment-knobs]
The orchestrator is configured per session through the environment, nothing
else:
| Variable | Effect |
| ----------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `AISQUARE_ROLE` | role for this session; also activates orchestration for the repo |
| `AISQUARE_TEAM=0` | master off switch (hooks and commands no-op) |
| `AISQUARE_TEAM_HUB` | pin sessions from several repos onto one shared board |
| `AISQUARE_TEAM_DELTA=0` | mute per-prompt teammate deltas for a heads-down session |
| `AISQUARE_TEAM_LEASE_MIN` | claim lease in minutes (default 120) |
| `AISQUARE_BRAIN=0` | disable the gbrain layer entirely |
| `AISQUARE_BRAIN_EMBED=1` | allow embedding of distilled pages |
| `AISQUARE_SERVE_CLIENT` / `AISQUARE_SERVE_ROLE` / `AISQUARE_SERVE_PORT` | identity and port for `aisquare serve` |
## Command map [#command-map]
```
aisquare team on Β· status Β· focus Β· role Β· log Β· distill [--all]
aisquare task add Β· list Β· show Β· next Β· claim Β· review Β· reopen Β· done
block Β· drop Β· release (all accept --as )
aisquare note "" [--task T] [--to ROLE] [--kind decision|question|result]
aisquare board [-w] Β· aisquare recall ""
aisquare serve [--stdio | --port N] [--show-token]
aisquare agents connect claude-code [--config-dir DIR]
```
Every command honours `--json` for scripting.
## Troubleshooting [#troubleshooting]
| Symptom | Cause and fix |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Board says "quiet here" | You are in a different project than the sessions. Export `AISQUARE_TEAM_HUB` in this shell, or run from the repo the team was launched in. |
| Sessions never appear | Hooks load at Claude startup: relaunch sessions started before `agents connect`. `aisquare doctor` confirms hook health per config dir. |
| Doctor: "hooks are missing or outdated" | An older install predates some lifecycle hooks. Re-run `aisquare agents connect claude-code` (per `--config-dir` if you use several). |
| A session shows stale | It has not heartbeat in 30+ minutes. Its claims self-release when the lease expires; the row disappears once it ends. |
| An agent says done but the task is in review | Saying is not doing: a task closes only when `aisquare task done` actually runs. Check `aisquare team log`; if there is no `task_done` event, tell the agent to execute the command, not narrate it. |
| `recall` says the brain is unavailable | `gbrain` is not on PATH, or another distill holds the brain briefly. Install gbrain, or retry in a few seconds. |
# Overview (/docs/agent-orchestrator/overview)
The Agent Orchestrator turns parallel Claude Code sessions into a team. You talk to a
planner. The planner files tasks on a shared board. Coder sessions claim tasks,
do the work, and send it to review. A runner session verifies each change and
either closes it or bounces it back with feedback. You watch all of it on a
live terminal board, and you only get pulled in when a session actually needs
you.
It ships in [`aisquare-cli`](https://github.com/AISquare-Studio/aisquare-cli)
and works with a single Claude account: sessions are per terminal, not per
account.
The page embeds a screen recording of the live board: a five-session
team (planner, runner, three coders) with live state chips, a task table of
review-stage work, and the event feed showing claims, notes, and completions
in real time.
## How it works [#how-it-works]
Three planes, one CLI:
**The board.** A shared SQLite store on your machine. Sessions register
automatically through Claude Code hooks, heartbeat on every prompt, and receive
a compact delta of what teammates did since their last turn. Repos that never
opt in never see any of it.
**The live board.** `aisquare board -w` is the cockpit: live session states
(working, waiting for input, needs you), the task table with dependencies, the
event feed, and a detail bar. Everything the team does is attributed and
timestamped, and you can jump from any event to the session transcript at that
exact moment.
**The bridges.** An MCP server (`aisquare serve`) lets remote Claude clients
(for example a browser-testing agent in the Claude desktop app) join the same
board as attributed teammates. A background distiller (powered by the optional
AISquare gbrain CLI) banks durable knowledge (decisions, results, task
outcomes) into a per-project brain that `aisquare recall` searches later.
## What makes it safe to rely on [#what-makes-it-safe-to-rely-on]
* **Idempotent tasks.** Adding the same task twice returns the original, so a
planner can re-emit its plan freely and nothing duplicates.
* **Atomic claims.** When two coders reach for the same task, exactly one wins;
the other just gets the next ready task. Claims carry leases, so a crashed
session's work returns to the pool by itself.
* **Fail-open hooks.** Every hook swallows its own failures and exits cleanly.
A broken orchestrator can never break a Claude session.
* **Explicit opt-in.** A repo joins the orchestrator only when you launch a
session with a role or run `aisquare team on` there.
# Quickstart (/docs/agent-orchestrator/quickstart)
Sessions are per terminal, not per account. A single `claude` install runs the
whole team.
## 1. Install and connect [#1-install-and-connect]
```sh
pipx install 'aisquare-cli[tui]' # or: pip install 'aisquare-cli[tui]'
aisquare agents connect claude-code # installs the lifecycle hooks
aisquare doctor # optional: verify the setup
```
`connect` merges five hooks into your Claude Code settings (it never touches
your other settings; `agents disconnect` removes them). If you run parallel
Claude installs through `CLAUDE_CONFIG_DIR` aliases, connect each one:
`aisquare agents connect claude-code --config-dir ~/.claude2`.
## 2. Launch the team [#2-launch-the-team]
From the repo you want the team working on:
```sh
AISQUARE_ROLE=planner claude # terminal 1: talk to this one
AISQUARE_ROLE=coder claude # terminal 2
AISQUARE_ROLE=coder claude # terminal 3, as many as you like
AISQUARE_ROLE=runner claude # terminal 4: verifies the coders' work
aisquare board -w # terminal 5: you, watching live
```
Launching with `AISQUARE_ROLE` activates orchestration for that repo and
registers the session. Each session is told its id, its teammates, and its standing work
cycle automatically. Nobody needs pasted instructions:
* the **planner** keeps the board stocked with tasks,
* **coders** claim the next ready task, do it, and send it to review,
* the **runner** verifies each review item and closes it or reopens it with
feedback that flows back to whichever coder picks it up next.
## 3. Drive it [#3-drive-it]
Talk to the planner like you would talk to a tech lead. It converts your intent
into tasks. You can also work the board directly from any shell:
```sh
aisquare task add "wire auth" --role coder # idempotent, safe to re-emit
aisquare task add "ship it" --needs tsk_abc # held until its dependency is done
aisquare note "JWT it is" --kind decision # share a decision with everyone
aisquare board # one-shot board (no TUI)
aisquare recall "what did we decide about auth?"
```
## Multi-repo and multi-install setups [#multi-repo-and-multi-install-setups]
* **One execution across several repos** (planner in one, coders in others):
set `AISQUARE_TEAM_HUB=/path/to/hub` in every session and shell so they all
share one board. Git worktrees already share their principal repo's board
automatically.
* **Separate rate limits per session:** run each role under its own
`CLAUDE_CONFIG_DIR` install and connect each config once.
## If the board looks quiet [#if-the-board-looks-quiet]
1. `aisquare doctor`. It flags missing or outdated hooks and tells you the fix.
2. Sessions load hooks at startup: relaunch any session that was already
running when you connected.
3. Using a hub? Export `AISQUARE_TEAM_HUB` in the shell where you run
`aisquare board`, or run it from the hub repo.
# Remote agents (MCP) (/docs/agent-orchestrator/remote-agents)
`aisquare serve` exposes the orchestrator as an MCP server, so Claude clients that
are not local terminal sessions can read the board and file tasks, notes, and
feedback like any teammate. The classic case: a browser-debugging agent running
in the Claude desktop app reports bugs straight onto the board your coders
drain.
Remote callers act through an attributed virtual session (`mcp:`,
scoped per project): their activity shows on the board and reaches every local
session's context automatically.
## Setup [#setup]
```sh
pip install 'aisquare-cli[serve]'
```
Starting the server from a repo is the explicit opt-in for that repo (it
activates orchestration there, visibly, the same as `aisquare team on`).
**Claude Desktop (stdio, simplest).** Register a local MCP server in
`claude_desktop_config.json`; the app launches and owns the process:
```json
{"mcpServers": {"aisquare-team": {"command": "wsl", "args": ["-e", "bash", "-lc",
"cd /path/to/your/repo && aisquare serve --stdio"]}}}
```
The `wsl -e` form is for Windows with the repo living in WSL2; on macOS or
Linux, point `command` straight at `aisquare`.
**HTTP (for anything else).**
```sh
aisquare serve # streamable HTTP on 127.0.0.1:8747
aisquare serve --show-token # the URL + bearer token to give the client
```
Every request needs the bearer token. The server binds loopback by default;
Windows reaches a WSL2 server via localhost automatically. `--bind 0.0.0.0` is
an explicit choice for LAN setups.
## The tool surface [#the-tool-surface]
Deliberately small (seven tools), because giant MCP surfaces burn a client's
context before any work happens: `team_board`, `task_add`, `task_next`,
`task_update`, `note_add`, `team_log`, `recall`.
A useful pattern for the remote agent's instructions:
> You are the team's debugger. Check `team_board` first. File every bug you
> find with `task_add` (role `coder`, with repro steps in `detail`). Report
> verification outcomes with `task_update` and share findings with `note_add`.
Name the client with `AISQUARE_SERVE_CLIENT=browser-debugger` and give it a
role with `AISQUARE_SERVE_ROLE=debugger` on the serve process, so the board
attribution reads right.
# Tasks and the work cycle (/docs/agent-orchestrator/tasks)
The task list is the team's single queue. Its two load-bearing guarantees:
* **Adding is idempotent.** A task's identity is a key derived from its title
(or an explicit `--key`). Re-adding returns the original instead of creating
a duplicate, so a planner can re-emit its whole plan after every
conversation with you and the board stays clean.
* **Claiming is atomic.** One `UPDATE`, one winner. Two coders reaching for the
same task never both get it; the loser's loop just receives the next ready
task. Claims carry a lease (default 120 minutes, renewed while the session
works), so a crashed session's tasks return to the pool on their own.
## The lifecycle [#the-lifecycle]
```
todo ββclaimβββΆ doing ββreviewβββΆ review ββdoneβββΆ done
β² β
βββββββββββ reopen (with feedback) β
```
| Command | What it does |
| -------------------------------------------------------------------------- | ------------------------------------- |
| `aisquare task add "" [--role coder] [--detail "β¦"] [--needs ]` | add work (idempotent) |
| `aisquare task next --role coder --claim --as ` | atomically claim the next ready task |
| `aisquare task review --note ""` | hand it to the runner |
| `aisquare task done --note "verified: β¦"` | close it |
| `aisquare task reopen --reason ""` | send it back with feedback |
| `aisquare task block --reason "β¦"` / `release ` / `drop ` | park it / return a claim / discard it |
`release` only applies to tasks in `doing`, so nobody can accidentally
resurrect finished work; `reopen` is the deliberate path back to the pool.
## Dependencies [#dependencies]
```sh
first=$(aisquare --json task add "build the API" | jq -r .id)
aisquare task add "wire the UI" --needs "$first"
```
A task with unmet needs is visible on the board (marked `β§ waits on β¦`) but
`task next` will not hand it out until everything it needs is done. Agents do
not have to reason about ordering; the queue simply never offers work that is
not ready.
## Role hints [#role-hints]
`--role coder` scopes pickup: a coder's `task next --role coder` sees tasks
hinted for coders plus unhinted tasks, and skips work hinted at other roles.
Hints are advisory vocabulary, not permissions, so agree on the role names your
team uses (the built-in cycles use `planner`, `coder`, `runner`).
## The feedback loop [#the-feedback-loop]
Reopen feedback is the heart of the system. When the runner reopens a task, the
reason lands on the shared event pipe attached to the task. Whichever coder
claims it next sees the feedback in its context automatically. Nobody forwards
anything, and the loop keeps going until the runner closes the task for real.
## Watching from the outside [#watching-from-the-outside]
You are also a participant. Every command works from any shell (no `--as`
needed; your actions are attributed to `cli`):
```sh
aisquare task list --status review # what the runner has waiting
aisquare task done tsk_abc --note "verified manually"
aisquare team log -n 30 # the raw pipe
```
# API Reference (/docs/api-reference/overview)
Generated from the OpenAPI spec in packet D6.
# Authentication (/docs/getting-started/authentication)
Every AISquare request is authenticated with a workspace API key passed in the
`Authorization` header. This page shows how to get a key, keep it safe, and use
it from a server, a script, or the SDK.
## Get a workspace key [#get-a-workspace-key]
An API key is scoped to a workspace and identifies who is making the call. You
can mint keys two ways:
* **From the dashboard.** Open your workspace settings and create a key. Copy it
once; it is shown only at creation.
* **Programmatically, per user.** Your backend registers each user through the
registration API, which provisions the user and returns a key for them. This
is the recommended path for platforms (see [Per-user
keys](#per-user-keys-for-platforms) below).
A key grants full access to its workspace. Never commit it, never put it in
client-side code, and never paste it into a browser request. Keep it on a
server or in a secret store.
## Ingest key for the explainability SDK and proxy [#ingest-key-for-the-explainability-sdk-and-proxy]
The explainability surface (the [SDK and multi-provider
proxy](/docs/govern/connect-your-agents)) uses its own workspace ingest key,
minted on the dashboard **Connectors** page. It looks like `AIS_...` and is
shown once, at creation. It is not interchangeable with the platform API key
above.
* **SDK:** export it as `EXPLAINABILITY_API_KEY`, with
`EXPLAINABILITY_GATEWAY_URL` set to your workspace's base gateway URL (no
path).
* **Proxy:** send it as the `X-AISquare-Key` header on every request.
Two more variables shape how SDK traces are identified (see [Agent
identity](/docs/govern/agent-identity) for the full contract):
* `EXPLAINABILITY_AGENTS` β a comma-separated roster, pre-registered at init so
first traces route immediately. The names must equal the `agent_name` values
used in code.
* `AISQUARE_AGENT_NAME` β configures policy checks and, from SDK 1.0.6, doubles
as the fallback trace identity when no explicit name is set. Keep it equal to
your `agent_name`.
## Store the key as an environment variable [#store-the-key-as-an-environment-variable]
Keep the key out of your source. Put it in an environment variable, which is
also where the SDK looks for it by default.
```bash title=".env"
AISQUARE_API_KEY=aisq_live_your_key_here
```
Make sure the file is gitignored, then load it into your shell or process
manager so the variable is available at runtime.
## Authenticate a request [#authenticate-a-request]
Pass the key as a bearer token. This works for any HTTP client, in any
language.
```bash title="curl"
curl -X POST https://api.aisquare.com/api/v1/aistudios/experiences/flattened/ \
-H "Authorization: Bearer $AISQUARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "ai-research-studio" }'
```
## Let the SDK read the key [#let-the-sdk-read-the-key]
The SDK reads `AISQUARE_API_KEY` from the environment, so you construct the
client with no arguments and it is already authenticated. Nothing about the key
appears in your code.
```python title="Python"
from aisquare import AISquare
# Reads AISQUARE_API_KEY from the environment.
client = AISquare()
experiences = client.experiences.flattened(url="ai-research-studio")
print(experiences.count)
```
```typescript title="TypeScript"
import { AISquare } from "@aisquare/sdk";
// Reads AISQUARE_API_KEY from the environment.
const client = new AISquare();
const experiences = await client.experiences.flattened({ url: "ai-research-studio" });
console.log(experiences.count);
```
To use a key explicitly instead of the environment (for example, when you hold a
different key per user), pass it to the constructor:
```python title="Explicit key"
client = AISquare(api_key=user_api_key)
```
## Per-user keys for platforms [#per-user-keys-for-platforms]
If you are building a platform on top of AISquare, give each of your users their
own key rather than sharing one workspace account. Your backend registers the
user, stores their key securely, and makes calls on their behalf.
Per-user keys keep each user's data and metrics separate, which a shared account
cannot do.
| Shared account | Per-user keys |
| ----------------------- | -------------------------------------- |
| Activity is merged | Activity is tracked per user |
| Personalization is lost | Metrics like accuracy and streaks work |
| Leaderboards are skewed | Leaderboards and ranking are accurate |
## Tokens for browser and SSO flows [#tokens-for-browser-and-sso-flows]
API keys cover server-to-server calls. Two other methods cover the cases keys do
not.
* **JWT tokens.** Exchange a key at the login endpoint for an access token (valid
7 days) and a refresh token (valid 30 days). Send the access token the same
way: `Authorization: Bearer `. Refresh it when it expires. See
[Token lifecycle](/docs/guides/token-lifecycle) for the full flow.
* **Cookie and OpenID.** Browser apps can authenticate with a session cookie
that rides along automatically; enterprises can connect SSO over OpenID.
| Use case | Method |
| ------------------- | ---------------------- |
| Backend integration | API key |
| Browser app session | Cookie |
| Token-based flows | JWT (access + refresh) |
| Enterprise SSO | OpenID |
## Next steps [#next-steps]
# Core Concepts (/docs/getting-started/core-concepts)
A handful of entities show up across every endpoint. Learn them once and the
API stops being a list of routes and starts being a model you can reason about.
## AI Studio [#ai-studio]
An [**AI Studio**](/docs/studios/overview) is the container for AI content and
the experiences built on it. It is the workspace where content is created,
users interact with it, and engagement is tracked. Each studio has a unique
`url` (its `publication_custom_url`), for example `ai-research-studio`, which is
how you address it in requests.
## Publication [#publication]
A **Publication** is the entity behind a studio. It holds the metadata (name,
logo, description), the visibility setting (public, private, or team), and the
associated users (the creator and any co-creators). In most of the API,
"publication" and "AI Studio" mean the same thing.
## Experience and Resource [#experience-and-resource]
These two are easy to conflate, so keep the distinction sharp:
* An **Experience** is a container: a topic, workflow, or module, such as
"Advanced Machine Learning Models."
* A **Resource** is an item inside an experience: the actual content.
One experience holds many resources. Resources come in a few types:
| Type | Description |
| ----------- | -------------------------------------- |
| `AI_EXPERT` | Interactive expert systems |
| `AI_NOTE` | Informational or educational content |
| `QUEST` | Task-based or challenge-driven content |
| `PODCAST` | Audio content |
### Flattened responses [#flattened-responses]
Some endpoints return data in a **flattened** shape: one row per resource, with
the parent experience repeated on each row. It looks redundant, and that is the
point. A frontend can render the rows as a flat list with no extra joining. The
Quickstart call uses this shape.
## Creator and co-creators [#creator-and-co-creators]
Every studio has one **creator**, the owner who manages content and settings,
and any number of **co-creators**, collaborators who can edit, review, or
contribute. Each co-creator carries a role (such as editor or reviewer) and a
status (invited or accepted). See [working with
creators](/docs/studios/overview) for the API.
## Metrics [#metrics]
AISquare tracks engagement across experiences and resources: views, likes,
shares, bookmarks, and comments. These power ranking (trending and popular
ordering), analytics, and personalization, and they appear on items in list
responses.
## Collections [#collections]
A [**Collection**](/docs/studios/collections) is a curated, ordered group of
experiences. Use collections to build learning paths or group related content.
Like publications, they carry a visibility setting (public, private, team, or
org).
## Activity [#activity]
AISquare records user **activity** across the platform: interactions, content
engagement, and progress over time. This history is what feeds personalization
and recommendations.
## Permissions [#permissions]
Access to content depends on three things together: the publication's
visibility, the user's role (creator, co-creator, or member), and their
authentication status. Some endpoints additionally require workspace membership
or owner access. See [Permissions](/docs/guides/permissions) for the rules.
## How it fits together [#how-it-fits-together]
```text
AI Studio (Publication)
|-- Experiences
| '-- Resources (AI Expert, Note, Quest, Podcast)
|-- Creator and co-creators
|-- Collections (group experiences)
'-- Metrics and Activity
```
## Next steps [#next-steps]
# Overview (/docs/getting-started/overview)
AISquare is governance infrastructure for agentic systems. It turns each agent
run into a governed, explainable decision you can observe, defend, and improve.
The rest of these docs follow one spine, and this page walks it end to end.
> **Govern** your agents, then run the **Trust Loop** on every decision
> (Understand, Prevent, Fix, Remember), so that **Collective Intelligence**
> compounds and your teams ship it as **Studios**.
## Why this exists [#why-this-exists]
As teams put agents into production, one problem shows up everywhere: the
system makes decisions that are hard to explain, audit, or trust. That gap
carries real cost.
* **Regulatory.** No durable record of what the agent decided or why.
* **Legal.** No way to reconstruct and defend an outcome after the fact.
* **Operational.** Black-box failures you cannot debug or keep from recurring.
AISquare closes the gap by adding a system of record for AI decisions, the same
way a financial system keeps a ledger of transactions. Every action and the
reasoning behind it becomes a durable, queryable artifact.
## Govern [#govern]
Governance starts by connecting your agents. You bring an agent from any
framework, on any model, and AISquare records what it decides without changing
how it runs. From there you get a tamper-evident decision record, decision-level
policy enforcement, and a no-code interface for reviewing and replaying any run.
Connecting is the only setup step. Everything below operates on the decisions
that flow in once an agent is connected.
## The Trust Loop [#the-trust-loop]
Once decisions are flowing, you run the Trust Loop on each one. It is four
moves, in order:
* **Understand.** See why the agent decided what it did, on the reasoning graph:
the claims it made, the evidence behind them, and the inference chain that
connected them.
* **Prevent.** Enforce policy at the decision point. A policy can allow, deny,
escalate, or modify an action before it runs.
* **Fix.** Correct a decision in place when it is wrong, and keep the correction
as part of the record.
* **Remember.** Persist every decision, intervention, and fix as enterprise
memory the next run can draw on.
## Collective Intelligence [#collective-intelligence]
Because every governed decision is remembered, the system does not start from
zero each time. Decisions accumulate on a shared reasoning and memory graph, so
corrections, evidence, and policy outcomes compound. Each agent and each team
gets the benefit of every decision that came before. The equation behind it is
[AI + BI = CI](/docs/collective-intelligence#ai--bi--ci): artificial
intelligence, plus the brain intelligence of the humans in the loop, compounds
into Collective Intelligence. It is not a stage between Govern and Studios; it
is the layer all of them write into and draw on. Logging becomes learning, and
a pilot becomes governed production.
## Studios [#studios]
Governed intelligence is the foundation; Studios are what your customers ship on
top of it. A Studio packages experiences and resources, backed by the same
reasoning graph and governance controls, into a product surface you deliver to
users. The trust you built in the loop rides along into everything you ship.
## Next steps [#next-steps]
# Quickstart (/docs/getting-started/quickstart)
Then your quickstart is [Connect your
agents](/docs/govern/connect-your-agents) β the SDK and proxy paths that put
traces, policy verdicts, and enforcement on your agents. This page covers
the Studios content API.
You will make one authenticated request to the AISquare API, get a real
response back, and understand what you got. Copy the call below, run it, and you
are done in under a minute.
## Your first call [#your-first-call]
This is a complete request. It carries the auth header, hits a live endpoint,
and sends a body. Paste it into a terminal and run it.
```bash title="First request"
curl -X POST https://api.aisquare.com/api/v1/aistudios/experiences/flattened/ \
-H "Authorization: Bearer aisq_sandbox_key" \
-H "Content-Type: application/json" \
-d '{
"url": "ai-research-studio"
}'
```
The response comes back immediately:
```json title="Response"
{
"count": 12,
"results": [
{
"experience_id": 123,
"experience_title": "Advanced Machine Learning Models",
"resource_type": "AI_EXPERT",
"resource_title": "Image Classification Expert",
"publication_title": "AI Research Studio",
"metrics": {
"views": 1250,
"likes": 89
}
}
]
}
```
`aisq_sandbox_key` and `ai-research-studio` are illustrative sandbox values so
this call works with no setup. Swap in your own workspace API key (see
[Authentication](/docs/getting-started/authentication)) and a studio `url` you
own to query live data.
## What just happened [#what-just-happened]
### Authenticated the request [#authenticated-the-request]
The `Authorization: Bearer ` header identifies your workspace. Every
AISquare request carries it. The sandbox key above is read-only and rate
limited; your real key unlocks your own data.
### Targeted a studio [#targeted-a-studio]
The body's `url` field is the public identifier of an AI Studio
(`publication_custom_url`). `ai-research-studio` is a sandbox studio. Point this
at a studio you own to fetch its content.
### Called the endpoint [#called-the-endpoint]
`POST /aistudios/experiences/flattened/` returns the resources inside a studio,
such as AI experts, notes, and quests, one row per resource so a UI can render
them as a flat list.
### Read the response [#read-the-response]
`count` is the total number of matching resources. Each item in `results`
carries its experience, its resource type and title, the publication it belongs
to, and engagement `metrics`. See [Core
Concepts](/docs/getting-started/core-concepts) for what each field means.
## Base URL [#base-url]
Every endpoint lives under one base URL:
```text
https://api.aisquare.com/api/v1/
```
## Filtering and pagination [#filtering-and-pagination]
Most list endpoints accept the same query parameters, so you can page and sort
without learning a new shape each time.
| Parameter | Description |
| ----------- | ---------------- |
| `page` | Page number |
| `page_size` | Results per page |
| `search` | Search content |
| `ordering` | Sort results |
For example, fetch the trending resources on the first page:
```text
GET /aistudios/experiences/flattened/?ordering=trending&page=1
```
## Next step [#next-step]
# Agent identity (/docs/govern/agent-identity)
Every trace that reaches AISquare carries an agent name. The gateway routes
each trace by the pair **(workspace, agent name)** to a studio and its Rule
Book, and the dashboard groups runs, verdicts, and cost by the same name. A
trace without a name has nowhere to go. This page is the contract: where the
name lives, how each integration path sets it, and what breaks when it is
missing.
## Why identity exists [#why-identity-exists]
Identity is written to the trace as `attributes["agent.name"]` on the trace's
**root span**. The gateway reads it once per trace and uses it three ways:
* **Routing.** Each trace routes by (workspace, agent name) to a studio. This
is how a run ends up on the right dashboard.
* **Rule Book binding.** The name decides which Rule Book judges the run. Bind
a Rule Book to `support-bot` and every run named `support-bot` is evaluated
against it.
* **Grouping.** Runs, policy verdicts, and cost aggregate per agent. The name
is the axis.
## Two channels, one name [#two-channels-one-name]
The SDK carries identity on two channels. They answer different questions, and
you should keep them equal.
* **Span identity** (`agent.name` on the root span) routes the trace and
groups your dashboards.
* **Policy identity** (`AISQUARE_AGENT_NAME`) tells policy checks which Rule
Book judges the agent.
From SDK 1.0.6 the two are unified: `AISQUARE_AGENT_NAME` also serves as the
**fallback trace identity**. When a span batch arrives with no explicit name
on its root span, the SDK stamps it with `AISQUARE_AGENT_NAME`. Explicit
naming in code always wins; the env var is the safety net. Keep it equal to
your `agent_name` so both channels agree.
## How identity is set, per path [#how-identity-is-set-per-path]
Explicit naming is the contract. Each integration path has exactly one place
to put the name.
| Path | Where the name goes |
| -------------------------------------------- | -------------------------------------------------------------- |
| Raw pipeline / custom spans | `AgentRunTracer(agent_name=...)` |
| Agno | `Agent(name=...)` β required |
| LangChain | `metadata={"agent_name": ...}` in the invoke config |
| Custom or OpenAI-wrapped via `GovernedAgent` | `agent_name=` on the wrapper; tracing is automatic (SDK 1.0.6) |
| Proxy | `X-Agent-Name` header |
**Raw pipelines.** Open an `AgentRunTracer` around the run. Its `agent_name`
lands on the root span and every child inherits the route.
```python
# .env: EXPLAINABILITY_GATEWAY_URL, EXPLAINABILITY_API_KEY,
# EXPLAINABILITY_AGENTS=support-bot <- pre-registers; must equal agent_name below
import aisquare.explainability as sdk
sdk.init_from_env()
with sdk.AgentRunTracer(agent_name="support-bot"):
with sdk.LLMCallTracer(model="gpt-4o", provider="openai") as llm:
...
sdk.flush()
```
**Agno.** The agent must be named. The SDK reads `Agent(name=...)` and uses it
as the trace identity; an unnamed Agno agent has no identity to send.
```python
my_agent = Agent(name="support-bot", ...)
```
**LangChain.** Pass the name in the invoke config's metadata. The callback
handler picks it up per call.
```python
chain.invoke(inputs, config={"metadata": {"agent_name": "support-bot"}})
```
**Custom and OpenAI-wrapped agents.** From SDK 1.0.6, `GovernedAgent`
auto-opens an `AgentRunTracer` around `.run()` and `.arun()`, so the wrapped
agent is traced and named in one move.
```python
agent = GovernedAgent.wrap(my_agent, agent_name="support-bot")
agent.run("...") # traced automatically, routed as support-bot
```
The automatic tracer wraps `.run()` and `.arun()`. If your run method is
generator-shaped (it streams or yields), the run outlives the call and the
wrapper cannot see its end. Open an `AgentRunTracer(agent_name=...)` around
the code that consumes the stream instead.
**Proxy.** Identity comes from the `X-Agent-Name` header on each request. If
the header is absent, the proxy falls back to the pipeline id
(`X-Pipeline-Id`), then to `claude-code`. Set the header if you want the name
to mean something.
## Running more than one agent [#running-more-than-one-agent]
Name each agent in code. `AISQUARE_AGENT_NAME` holds **one** name; it is a
single-agent convenience, not a naming scheme.
If several agents run in one process and rely on the env-var fallback, they
all inherit the same identity. Their traces collapse into one agent β
one shared Rule Book, merged dashboards, blended cost β and nothing warns you.
The runs still arrive; they are just indistinguishable. With multiple agents,
set `agent_name` explicitly on every one.
## Pre-register your roster [#pre-register-your-roster]
`EXPLAINABILITY_AGENTS` takes a comma-separated list of agent names and
registers them at `init_from_env()`, so the first trace from each agent routes
immediately instead of waiting on registration.
```bash
export EXPLAINABILITY_AGENTS="support-bot,billing-bot"
```
The names must equal the `agent_name` values used in code, character for
character. A roster entry that matches nothing registers an agent that never
runs; a coded name missing from the roster still needs registration before its
first trace routes.
## Naming rules [#naming-rules]
* **Unique per workspace.** The name is the routing key; two agents sharing a
name are one agent as far as AISquare is concerned.
* **Stable across deploys.** Rule Book bindings key off the name. Rename the
agent and its bindings, history, and dashboards do not follow.
* **Allowed characters:** letters, digits, `.`, `_`, `-`, and spaces.
## What failure looks like [#what-failure-looks-like]
When identity is missing or unknown, trace ingest answers `409 Conflict` with
a machine-readable code in `detail.code`:
| Code | Meaning | What to do |
| ---------------------- | ---------------------------------------------------- | ---------------------------------------------------------------- |
| `no_agent_identity` | A root span arrived with no identity on it. | Fix the integration β name the agent. Retrying will not succeed. |
| `awaiting_trace_route` | A child-only batch arrived before its root span. | Transient. The SDK retries it automatically. |
| `agent_not_registered` | The name is set but not registered in the workspace. | Register the agent, or enable auto-discovery on the workspace. |
Full remediation for each code is in the
[error reference](/docs/reference/errors#409-conflict--trace-ingest). If you
are not sure which case you are in, run `explainability-doctor`: its
`agent_identity` check flags naming gaps in your integration, and its
`delivery_backlog` check reads the local delivery queue and reports exactly
which of these failures is holding traces back.
## Next steps [#next-steps]
# Connect your agents (/docs/govern/connect-your-agents)
Your agents keep running exactly as they do today. AISquare connects alongside
them, recording each run as a trace, extracting the reasoning, evaluating it
against your policies, signing the result, and surfacing cost. You connect one
of two ways, and you can mix them across teams: every run lands in the same
[reasoning graph](/docs/govern/understand) regardless of how it got there.
```text
Your agent -> AISquare . trace . screen PII . evaluate policy . sign -> Your dashboard
```
Connecting is the only setup step. Everything in the Trust Loop
([Understand](/docs/govern/understand), [Prevent](/docs/govern/prevent),
[Fix](/docs/govern/fix), [Remember](/docs/govern/remember)) operates on the
decisions that flow in once an agent is connected.
## Which path should I use? [#which-path-should-i-use]
For the complete proxy guide (the coding-CLI connect script, the per-provider
reference, and enforcement semantics), see
[Proxy integration](/docs/govern/proxy-integration).
| What matters to you | Proxy | SDK |
| ---------------------------------------------------------------- | ---------------------------------------- | -------------------------------------------------------- |
| Setup effort | About 5 minutes, a base URL and a header | Install, name your agent, wrap |
| Agent code change | None | Minimal (a wrapper) |
| Agent identity | X-Agent-Name header (defaults applied) | Required: agent\_name / AgentRunTracer β the routing key |
| New dependency | No | Yes, one package |
| How runs are captured | At the network boundary (zero code) | In your code (both emit OpenTelemetry spans) |
| Traces, reasoning, and cost | Yes | Yes |
| PII / PHI / PCI detection at ingest (redact via the mask policy) | Yes | Yes |
| Policy verdicts | Yes | Yes |
| Signed audit record plus AIBOM | Yes | Yes |
| Runtime enforcement | Yes: block / improve / warn / gate-in | Yes: block / improve / warn |
| Where the gate runs | At the LLM call, on AISquare's side | Inside the agent, at the tool boundary |
| Best starting point for | Fast, zero-code governance | Custom spans and in-process gating |
Both paths give you full governance: every run is evaluated against your
policies, each verdict (pass or block, with a reason and a citation) is
recorded on the run, and both can enforce at runtime. They differ on **where
the gate runs**.
* The **SDK** runs a policy gate inside the agent, at the tool boundary, so a
rule can block, improve, or warn on a tool call at runtime, before it fires.
* The **proxy** enforces at the LLM-call boundary, on AISquare's side. With
its Rule Book switched to Live, it can `block` an unsafe tool call
(the agent is handed the reason and re-plans), `improve` a non-compliant
reply by rewriting it, `warn` by flagging the run, and `gate-in` by checking
tool outputs for prompt injection before the model sees them. In Audit, it
records and flags but never alters a run.
The proxy is the fastest way to put observability and enforcement across your
fleet on day one, with zero code changes. Choose the SDK when you want the
gate in-process, or instrumentation beyond what the transparent proxy
captures: custom spans, enrichers, and inline governance.
## Option A: SDK [#option-a-sdk]
The SDK is OpenTelemetry-native: it auto-instruments your agent, batches spans,
retries on failure, and ships them to your AISquare workspace. There is no
proprietary wire format to adopt: if you already emit OpenTelemetry, the SDK
attaches to your existing TracerProvider. It supports Agno and LangChain with
automatic tool interception, plus custom agents and direct OpenAI SDK callers
via `GovernedAgent.wrap` and the gate API. (For the direct Anthropic SDK, use
the proxy below.)
```bash
pip install "aisquare[explainability]"
```
Values come from your workspace settings. See
[Authentication](/docs/getting-started/authentication) for where to find your
ingest key. The URL is the **base** gateway URL, with no path β the SDK
appends the ingest route itself.
```bash
export EXPLAINABILITY_API_KEY=""
export EXPLAINABILITY_GATEWAY_URL="https://.aisquare.studio"
export EXPLAINABILITY_AGENTS="support-bot" # pre-registers; must equal the agent_name used in code
```
The governance surface (`GovernedAgent`, policy checks) also accepts
`AISQUARE_API_KEY` and `AISQUARE_INGEST_URL` as aliases, but the pair above is
read by every part of the SDK β use it. If you set `AISQUARE_AGENT_NAME` for
policy checks, keep it equal to your `agent_name`: from SDK 1.0.6 it also
serves as the fallback trace identity when no explicit name is set.
Every trace routes by **(workspace, agent name)** to a studio and a Rule Book
β the name is the routing key, and setting it explicitly is the contract. For
a raw pipeline, the name goes on the `AgentRunTracer`:
```python
import aisquare.explainability as sdk
sdk.init_from_env()
with sdk.AgentRunTracer(agent_name="support-bot"):
with sdk.LLMCallTracer(model="gpt-4o", provider="openai") as llm:
...
sdk.flush()
```
For framework agents, one line each: Agno agents must be named
(`Agent(name="support-bot", ...)`); LangChain callers pass
`config={"metadata": {"agent_name": "support-bot"}}` on invoke; custom agents
get `agent_name=` on the `GovernedAgent` wrapper in the next step. The full
contract β multiple agents, naming rules, and what failure looks like β is on
[Agent identity](/docs/govern/agent-identity).
No behavioural change. Traces ship automatically. `from_agno` requires the
Agno agent to be named β either name the agent itself or pass `agent_name=`
on the wrapper.
```python
from aisquare import GovernedAgent
my_agent = Agent(name="support-bot", ...) # Agno agents must be named
agent = GovernedAgent.from_agno(my_agent) # or: from_agno(my_agent, agent_name="support-bot")
# run your agent exactly as before
```
For custom and OpenAI-wrapped agents, `GovernedAgent.wrap(my_agent,
agent_name=...)` auto-traces `.run()` and `.arun()` (SDK 1.0.6). Streaming or
generator-shaped run methods are not auto-traced β open an
`AgentRunTracer(agent_name=...)` around the code that consumes the stream. See
[Agent identity](/docs/govern/agent-identity).
Add a pre-tool policy gate, checked before each tool runs. The verdict it
produces is the same one you see on the [Prevent](/docs/govern/prevent) page.
`enforce=True` requires the two environment variables from the Configure step.
```python
agent = GovernedAgent.from_agno(
my_agent,
rule_book="your-rule-book", # your synced policies
enforce=True, # check each tool before it runs: block / improve / warn
)
```
**What you get:** full traces with flow, graph, and plain-English narrative
views; structured reasoning (claims, evidence, assumptions, and the policies
each run triggered); policy verdicts; a signed, tamper-evident audit record with
an AIBOM per run; and cost, plus the pre-tool enforcement gate.
## Option B: Multi-provider proxy [#option-b-multi-provider-proxy]
The quickest way to begin, with no new dependency and no agent code
change. Point your provider base URL at AISquare and send your workspace key as
a header. Every LLM call then flows through a thin shim that traces it, screens it
for PII, evaluates your policies (and, in Live, enforces them), and
forwards the call to the real provider (streaming supported; in Live,
streamed turns are checked before release).
This section is the short version; the full walkthrough, including the
one-command connect script for the Claude Code and Codex CLIs and the
per-provider reference, is at
[Proxy integration](/docs/govern/proxy-integration).
You get both from the dashboard **Connectors** page: generate your workspace
API key (`AIS_...`) there β it is shown once, at creation β and the proxy URL
is in the setup guide on the **Proxy connector** card.
Your provider key stays exactly where it is and still authenticates the model.
The `X-AISquare-Key` header tells the proxy which workspace and Rule Book
govern the run; with most SDKs, set it once in `default_headers`.
```python
# Anthropic shown; OpenAI, Azure OpenAI, and Gemini work the same way
from anthropic import Anthropic
client = Anthropic(
base_url="https://",
default_headers={"X-AISquare-Key": "AIS_"},
) # your ANTHROPIC_API_KEY passes through
```
The exact base URL and enforced paths for each provider (OpenAI, Azure OpenAI,
Gemini) are in the
[per-provider reference](/docs/govern/proxy-integration#per-provider-reference).
Every call is now traced, cost-extracted, PII-screened, and policy-evaluated,
and with your Rule Book in Live, it enforces in real time.
**What you get:** traces, cost, PII screening, policy verdicts, and live Rule
Book enforcement (`block` / `improve` / `warn` / `gate-in`) on every run, with
zero code.
The proxy sits inline in your live LLM path. Ungoverned agents and
workspaces in Audit stream straight through untouched; a governed workspace in
Live holds each turn just long enough to check it against your Rule Book
(streamed turns are buffered, checked, then released). It uses your provider
key only to forward the call, never written to a trace or stored. Auth and
gateway outages fail closed for agents the proxy has seen enforcing, so a
governed Live agent is never silently un-governed; Audit workspaces keep
recording.
### Already running OpenTelemetry? [#already-running-opentelemetry]
The SDK attaches to your existing OpenTelemetry `TracerProvider`: install it,
set the environment variables above, and call
`aisquare.explainability.init_from_env()` β the spans your instrumentation
already emits are captured as-is, no re-instrumentation. Those spans still
need an [agent identity](/docs/govern/agent-identity) to route: open an
`AgentRunTracer(agent_name=...)` around the run, or set `AISQUARE_AGENT_NAME`
as the single-agent fallback. (A direct OTLP ingest endpoint is not available
today; the SDK is the integration path for existing OpenTelemetry setups.)
## What your team will see [#what-your-team-will-see]
Once you are connected, every run shows up in your dashboard:
* **Traces, several ways.** Each run as a flow diagram, a graph, and a
plain-English narrative.
* **Reasoning.** The claims the agent made, the evidence behind them, the
assumptions it filled in, and the policies it triggered, structured, not a
wall of transcript. See [Understand](/docs/govern/understand).
* **Policy verdicts.** Each run evaluated against your rule book; pass or block
with a written reason and a citation to the exact rule. See
[Prevent](/docs/govern/prevent).
* **Auditability.** Each verdict cryptographically signed, plus an AIBOM (AI
Bill of Materials) per run.
* **Cost.** Per run, per agent, and per provider and model, with per-step
cost in the flow view.
PII / PHI / PCI detection runs at ingest, before anything is persisted.
Detection defaults to alert-only; set your data policy to **mask** to redact in
place, or **block** to reject the trace. The policy is set per
workspace, under **Settings -> Security**.
## A practical rollout [#a-practical-rollout]
Point your provider base URL at AISquare β zero code change β or add the SDK
to an existing OpenTelemetry setup (one init call), with your rule books in
Audit. You immediately get
traces, reasoning, policy verdicts, and cost on every agent, and nothing is
altered at runtime.
Flip the rule books that matter to Live and arm the actions you want on the
agents that handle sensitive data or take irreversible actions. For an
in-process gate at the tool boundary, or instrumentation beyond what the
proxy captures, add the SDK to those agents. Same traces, no rework.
Bring the rest of the fleet onto whichever path each team prefers. Every run
lands in the same place, so nothing is redone.
## Next steps [#next-steps]
# Fix (/docs/govern/fix)
Fix is the third move of the Trust Loop. [Understand](/docs/govern/understand)
showed you the reasoning, [Prevent](/docs/govern/prevent) stopped a bad action,
and now Fix is how you correct a decision that was wrong, in the exact context
that produced it. A correction here is not an edit to a log. It is a first-class
event on the run, attributed and kept, that changes what the system does next.
## Correct in context, not in a vacuum [#correct-in-context-not-in-a-vacuum]
A correction lands on the decision itself, against the claims, evidence, and
assumptions that produced it. That context is what makes the fix precise. You are
not retyping an answer; you are overturning a specific claim or replacing a
specific assumption, and the system records exactly what changed and why.
Take the refund run from [Understand](/docs/govern/understand). The agent leaned
on a low-confidence assumption, that the customer tier resolved to standard, and
auto-approved on the back of it. A reviewer who saw that weak link can correct it
directly on the step.
The reviewer replaced the inferred tier with the confirmed one. The original
decision stays on the record, marked as superseded, and the correction sits
beside it with who made it and when. Nothing is overwritten, because the point of
a system of record is that you can still see what the agent originally believed.
## A fix changes three things [#a-fix-changes-three-things]
A single correction propagates, in order:
1. **The decision.** The outcome is reversed or adjusted now. The refund that was
auto-approved on a bad assumption is re-routed under the correct tier.
2. **The record.** The correction is appended to the run, attributed to the
person who made it, with the before and after both visible. The run stays
auditable, and the audit now includes the human judgment.
3. **The future.** The correction becomes reusable context. The next run that
hits the same weak assumption starts from the corrected position rather than
repeating the mistake. That hand-off is [Remember](/docs/govern/remember).
Most systems treat a fix as cleanup that disappears once applied. Here a
correction is durable and reusable. Fixing the same problem twice is a signal
that the first fix was not carried forward, and on AISquare it is, by default.
## Escalations land here too [#escalations-land-here-too]
A [Prevent](/docs/govern/prevent) policy that escalates rather than denies routes
the decision to a person, and this is where it arrives. The reviewer sees the
full reasoning, makes the call, and that judgment is recorded as a correction on
the run, exactly like any other fix. Escalation and correction are the same loop:
a human decision, attributed and carried forward.
## Why this matters [#why-this-matters]
* **Decisions get better in place.** You fix the cause on the run that produced
it, not in a downstream patch that loses the context.
* **Human judgment is captured.** The reviewer's call becomes part of the
permanent record and part of the system's future behaviour. This is the BI
half of [AI + BI = CI](/docs/collective-intelligence#ai--bi--ci): brain
intelligence, recorded where the artificial intelligence can reuse it.
* **The fix compounds.** A correction made once is available everywhere the same
situation recurs, which is the bridge from Fix to
[Remember](/docs/govern/remember).
## Next steps [#next-steps]
# Prevent (/docs/govern/prevent)
Prevent is the second move of the Trust Loop. [Understand](/docs/govern/understand)
shows you why an agent decided what it did; Prevent decides whether the agent is
allowed to act on it. A policy is evaluated at the decision point, against the
reasoning of the run in flight, and it produces a verdict that is recorded on the
run forever.
## Policies gate the decision, not just the prompt [#policies-gate-the-decision-not-just-the-prompt]
A keyword filter on the prompt cannot tell whether an action is safe, because
the risk lives in what the agent decided to do, not in the words a user typed.
AISquare policies evaluate the decision: the claims the agent made, the evidence
it leaned on, the tool it is about to call, and the data crossing the boundary.
Each policy resolves to one of four outcomes:
* **Allow.** The action is within policy. It runs, and the pass is recorded.
* **Deny.** The action violates a blocking rule. It is blocked before it
executes.
* **Improve.** The action violates an improving rule. The agent is handed a
correction with a suggested fix and retries; repeated misses on the same rule
escalate to a hard block.
* **Warn.** The action violates an advisory rule. It proceeds, and the run is
flagged for review.
Policies do not fire in a vacuum. A rule can lean on what the reasoning and
memory graph already holds: a refund already recorded against the order, a
correction a reviewer made on a case like this one. That is
[Collective Intelligence](/docs/collective-intelligence) powering enforcement,
the same layer every capability writes into.
## A verdict is the proof governance ran [#a-verdict-is-the-proof-governance-ran]
Every run carries its verdicts: one row per policy check, each with the rule it
evaluated, a pass or blocked result, a threshold meter showing the measured value
against the limit, and a citation to the exact rule that fired. This is the
concrete record that governance ran, not just that it was configured.
Reading these two verdicts from the same refund run:
* **`data-residency-eu` passed.** Every record the agent retrieved resolved to
EU-hosted storage. The meter sits at 64 percent against an 80 percent ceiling,
comfortably inside the limit, so the action ran and the pass is on the record.
* **`no-external-email` blocked.** The agent tried to send a confirmation email
to an address outside the verified customer domain. That crossed the rule, so
the tool call was stopped before it fired. The citation points at the exact
rule, so the block is explainable to anyone who asks.
A blocked verdict is not a dead end. It is the signal that feeds
[Fix](/docs/govern/fix): a human can correct the decision in context, and the
correction is carried forward by [Remember](/docs/govern/remember) so the same
mistake is caught earlier next time.
## Where the gate runs [#where-the-gate-runs]
Where a policy can enforce depends on how the agent is
[connected](/docs/govern/connect-your-agents).
* The **SDK** runs the gate inside the agent, at the tool boundary, so a rule can
block, improve, or warn on a tool call at runtime, before it fires.
* The **proxy** enforces at the LLM-call boundary, on AISquare's side. With the
rule book in Live, a rule can `block` an unsafe tool call before it runs (the
agent is handed the reason, so it re-plans a safe alternative), `improve` a
non-compliant reply by rewriting it to comply, `warn` by flagging the run
while it proceeds untouched, and `gate-in` by checking tool outputs for
prompt injection and sanitizing them before the model sees them. See
[Proxy integration](/docs/govern/proxy-integration).
Each workspace has a Live / Audit switch. **Audit** records and flags but never
alters a run; start there to see what your rule book would do. **Live** applies
enforcement in real time. Both connection paths give you full policy
visibility either way: every run is scored against your rule book and every
verdict is recorded.
## Rule books [#rule-books]
Policies are grouped into a rule book: a named, versioned set of rules you sync
to your workspace and attach to an agent. Because a rule book is versioned, a
verdict can be traced to the exact rule text that was live when the decision was
made, which is what makes an old decision defensible long after the rules have
moved on.
## Next steps [#next-steps]
# Proxy integration (/docs/govern/proxy-integration)
The proxy is a drop-in gateway that sits between your agent and the model
provider. Point your agent's base URL at it, add one header, and every call
flows through unchanged, while AISquare records it and applies your policies in
real time. It works for Anthropic, OpenAI (Chat Completions and Responses),
Azure OpenAI, and Gemini, plus the Claude Code and Codex CLIs. No changes to
your agent logic; connect in one line, disconnect just as fast.
```text
Your agent (app, CLI, pipeline) -> AISquare proxy (record + enforce) -> Model provider
```
## What you get [#what-you-get]
* **Full recording.** Every request, tool call, and reply becomes a Run in your
dashboard, with tokens, cost, and the full reasoning trace. See
[Understand](/docs/govern/understand).
* **Live enforcement.** Your [Rule Book](/docs/govern/prevent) can block an
unsafe tool call, rewrite a non-compliant reply, or flag a run, the moment it
happens.
* **Every provider.** Anthropic, OpenAI (Chat Completions and Responses),
Azure OpenAI, and Gemini, plus the Claude Code and Codex CLIs.
* **Your keys stay yours.** Your provider API key passes straight through to
the model. The proxy never stores it.
## Before you start [#before-you-start]
From the AISquare dashboard you need two things, and both come from the
**Connectors** page (the key is shown once, at creation; the proxy URL is in
the **Proxy connector** card's setup guide):
1. Your **workspace API key** (`AIS_...`).
2. Your **production proxy URL**.
Everywhere below, replace `` and `AIS_` with those
values.
## Two keys, one hop [#two-keys-one-hop]
Requests carry two credentials. Your provider key authenticates the model call
and is forwarded untouched. Your AISquare workspace key, sent as the
`X-AISquare-Key` header, tells the proxy which workspace and Rule Book govern
the run.
Headers on every request: `X-AISquare-Key: AIS_...` (workspace auth) plus your
existing provider key (`x-api-key` or `Authorization`), forwarded to the model.
The proxy also streams the run to your dashboard; nothing else leaves your
provider path.
## Three ways in [#three-ways-in]
Whichever path you choose, you keep your existing provider key and change
nothing about your agent's behavior.
### Option A: coding CLIs (Claude Code and Codex) [#option-a-coding-clis-claude-code-and-codex]
The Connectors page gives you a one-command script that configures both CLIs.
No hand-editing of `settings.json` or `config.toml`. In the dashboard, open
**Connectors -> Proxy connector**, paste your `AIS_` key, and download
`aisquare-connect.sh` β the key is embedded client-side and never travels in a
URL.
```bash
bash aisquare-connect.sh on # route Claude Code + Codex through AISquare
bash aisquare-connect.sh status # check state + connectivity
bash aisquare-connect.sh off # disconnect and remove the AISquare settings
```
Then run `claude` or `codex` as usual. Every session shows up as a Run.
`off` restores Codex's previous model provider exactly; if you had pointed
Claude Code at a custom `ANTHROPIC_BASE_URL` of your own before connecting,
re-add it after disconnecting.
### Option B: backend or agentic pipeline [#option-b-backend-or-agentic-pipeline]
Works in any language, no SDK. Already calling
a provider from your own code? Point that SDK at the proxy and add one header,
the same `X-AISquare-Key` on every request. Your provider key still
authenticates the model. Two optional headers make runs cleaner:
`X-Agent-Name` (a stable [agent identity](/docs/govern/agent-identity) your
Rule Book can bind to; without it the proxy falls back to the pipeline id,
then to `claude-code`) and `X-Pipeline-Id` (groups a pipeline's calls into one
Run). Setup per provider (Python shown):
```python
# Anthropic (Claude)
from anthropic import Anthropic
client = Anthropic(
base_url="https://",
default_headers={"X-AISquare-Key": "AIS_"},
) # your ANTHROPIC_API_KEY passes through
```
```python
# OpenAI (Chat Completions + Responses, Codex)
from openai import OpenAI
client = OpenAI(
base_url="https:///v1",
default_headers={"X-AISquare-Key": "AIS_"},
) # your OPENAI_API_KEY passes through
```
```python
# Azure OpenAI (set your resource endpoint once in the dashboard first)
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint="https://", # the proxy, not your resource
api_version="2024-10-21",
api_key="", # passes through
default_headers={"X-AISquare-Key": "AIS_"},
)
```
The `api-version` your client sends is forwarded verbatim to your Azure
resource; the version field on the dashboard's Azure card is informational.
```python
# Gemini (google-genai)
from google import genai
client = genai.Client(
api_key="", # passes through
http_options={"base_url": "https://",
"headers": {"X-AISquare-Key": "AIS_"}},
)
```
### Option C: Python SDK [#option-c-python-sdk]
The tightest integration. For richer control
(custom spans, enrichers, and inline governance), `pip install
"aisquare[explainability]"` and initialize it once. The minimal working shape
is an `AgentRunTracer` around your run, with your LLM calls traced inside it:
```python
# .env: EXPLAINABILITY_GATEWAY_URL, EXPLAINABILITY_API_KEY,
# EXPLAINABILITY_AGENTS=support-bot <- pre-registers; must equal agent_name below
import aisquare.explainability as sdk
sdk.init_from_env()
with sdk.AgentRunTracer(agent_name="support-bot"):
with sdk.LLMCallTracer(model="gpt-4o", provider="openai") as llm:
...
sdk.flush()
```
`agent_name` is the routing key β see
[Agent identity](/docs/govern/agent-identity). Use this path when you want
instrumentation beyond what the transparent proxy captures. See
[Connect your agents](/docs/govern/connect-your-agents) for the SDK path in
full.
## Per-provider reference [#per-provider-reference]
All providers carry the same `X-AISquare-Key` header and forward your provider
credentials unchanged. Only Azure needs one extra step: its per-workspace
resource endpoint is set once in the dashboard (the proxy stores the endpoint,
never a key).
| Provider | Base URL | Enforced paths |
| ----------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------ |
| Anthropic + Claude Code | `https://` | `/v1/messages`, stream and non-stream |
| OpenAI + Codex CLI | `https:///v1` | `/v1/chat/completions`, `/v1/responses` (Codex) |
| Azure OpenAI | `https://` (SDK `azure_endpoint`) | `/openai/deployments/.../chat/completions`; set your resource in the dashboard first |
| Gemini | `https://` | `:generateContent`; streaming enforces with `?alt=sse` |
## What the Rule Book can do [#what-the-rule-book-can-do]
Each rule book has a **Live / Audit-only** switch on the dashboard's Rules
page. Audit records
and flags but never alters a run; start there. Live applies the actions below
in real time.
| Action | What happens |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `block` | An unsafe tool call is withheld before it runs, and the agent is handed the reason, so it re-plans a safe alternative on the spot. |
| `improve` | A non-compliant reply is rewritten to comply (for example, a hard-coded secret becomes an env-var read). Runs on AISquare's side, so it works for every provider. |
| `warn` | The run proceeds untouched but is flagged in the dashboard for review, for advisory policies. |
| `gate-in` | Tool outputs coming back into the agent are checked against your retrieval-scope rules (for example, a prompt-injection rule) and sanitized before the model sees them. Covers Anthropic, OpenAI, and Codex tool outputs. |
## Verify [#verify]
* Make one call through the proxy. It appears as a Run in your dashboard
within seconds.
* With a blocking rule armed and its rule book in Live, trigger it. The
enforcement event shows on the run with a before and after.
## Operate with confidence [#operate-with-confidence]
* **Reversible.** Disconnect any time (`off`, or remove the base URL). `off`
removes the AISquare settings; Codex's previous provider is restored.
* **Low overhead.** Ungoverned agents and workspaces in Audit stream straight
through untouched. A governed workspace in Live adds a policy check per
gated turn, and streamed turns are held until they clear the gate, then
released. Streaming is fully supported.
* **Fails safe.** Auth and gateway outages fail closed for agents the proxy
has seen enforcing, so a governed Live agent is never silently un-governed;
Audit workspaces keep recording. What happens when an improve rewrite cannot
be produced is configurable per proxy deployment: fail open to the original
reply (default) or withhold it.
* **Your data path is unchanged.** Provider keys pass through and are never
stored; the only added destination is your own AISquare dashboard, over TLS.
## Next steps [#next-steps]
# Remember (/docs/govern/remember)
Remember is the fourth move of the Trust Loop, and the one that makes the first
three compound. [Understand](/docs/govern/understand) captured the reasoning,
[Prevent](/docs/govern/prevent) recorded the verdicts, and [Fix](/docs/govern/fix)
attached the corrections. Remember persists all of it as enterprise memory, so
the next run does not start from zero. Without this step, governance is a logbook.
With it, governance is something the system learns from.
## Decisions accumulate on a graph [#decisions-accumulate-on-a-graph]
Every governed decision, with its claims, evidence, policy verdicts, and any
human corrections, is written to a shared reasoning and memory graph. It is not a
flat log of past runs. It is queryable context: a later run can read the prior
decision that matches its situation and start ahead of where the earlier one did.
Carrying the refund agent forward, the assumption a reviewer corrected in
[Fix](/docs/govern/fix), that the customer tier was inferred rather than
confirmed, is now memory. The next run on that customer reads it before it
reasons.
The second run reads the correction and branches on the confirmed priority tier
straight away. The weak assumption never recurs, not because the prompt changed,
but because the decision that fixed it is part of the record the agent now draws
on. A memory read is a step like any other: it shows up on the trace, with its
own latency and cost, so you can always see what the agent recalled and where it
came from.
## What gets remembered [#what-gets-remembered]
Memory is not the raw transcript. It is the governed, structured outcome of each
run:
* **Decisions.** The claims an agent acted on and the evidence behind them.
* **Verdicts.** Which policies fired and how, so a precedent carries its
governance with it.
* **Corrections.** Every human fix and escalation, attributed, so judgment made
once is available everywhere.
* **Outcomes.** What actually happened after the decision, which is what lets the
graph distinguish a good call from a lucky one.
Everything in memory has already been through ingest, so detected PII / PHI / PCI
was screened before anything was persisted (redacted when your data policy is
set to mask), and the graph is scoped to your
workspace. Remembering more does not mean retaining more sensitive data; the same
[connection-time](/docs/govern/connect-your-agents) protections apply to what is
recalled.
## Logging becomes learning [#logging-becomes-learning]
This is the move that changes the economics of running agents. When decisions are
remembered:
* **Corrections do not have to be repeated.** A fix made once is reused
automatically, so the same mistake is caught earlier, or avoided entirely, on
every later run.
* **Precedent accrues.** Similar decisions resolve consistently because the agent
can see how the matching case was handled before.
* **Each run starts ahead.** The system gets more reliable the more it is used,
rather than relearning the same lessons.
## Where memory lands: Collective Intelligence [#where-memory-lands-collective-intelligence]
Remember closes the Trust Loop for a single agent. The same graph spans every
agent and every team, which is where it stops being one agent getting better and
becomes an organisation getting better. Each team gets the benefit of every
governed decision that came before it. That compounding layer is
[Collective Intelligence](/docs/collective-intelligence): every capability
writes into it, every capability is powered by it, and it is the intelligence
behind the [Studios](/docs/studios/overview) your customers ship.
## Next steps [#next-steps]
# 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, and
AISquare extracts the reasoning behind it so you can 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: the
question it was asked, the context it fetched, the evidence and the one
assumption it leaned on, the policy it cleared, the claim it made, 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.
## 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.
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, the inferred
facts that were not given to it 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.
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.
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.
## 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]
# Content modeling (/docs/guides/content-modeling)
AISquare organizes content into a hierarchy. Understanding it is the key to
building feeds, learning flows, and discovery pages that render cleanly.
```text
AI Studio (Publication)
|-- Experiences
| '-- Resources
```
For the entities themselves, see [Core
Concepts](/docs/getting-started/core-concepts). This guide focuses on turning
them into UI.
## Building blocks [#building-blocks]
### AI Studio [#ai-studio]
The top-level container: a workspace, a content hub, a themed collection of
experiences. It is addressed by a `url`, for example `ai-research-studio`.
### Experience [#experience]
A logical grouping of content, such as a topic, a module, or a journey. Example:
"Advanced Machine Learning Models." An experience is a container, not a content
item.
### Resource [#resource]
The actual content unit. An experience holds many resources, and each resource
has a type.
| Type | Use case |
| ----------- | ------------------------------ |
| `AI_EXPERT` | Interactive AI systems |
| `AI_NOTE` | Educational or written content |
| `QUEST` | Challenges or tasks |
| `PODCAST` | Audio content |
## Two response formats [#two-response-formats]
AISquare returns content in two shapes.
### Flattened (recommended) [#flattened-recommended]
Each resource comes back as its own item, with the parent experience repeated on
each row.
```json title="Flattened item"
{
"experience_title": "Advanced Machine Learning Models",
"resource_type": "AI_EXPERT",
"resource_title": "Image Classification Expert"
}
```
It looks redundant, and that is the point: a frontend can render the rows as a
flat list with no joining. Use it for feeds, search results, and discovery
pages.
### Nested [#nested]
Experiences contain their resources inside them. Use it for a detailed
experience view or a structured content page, where the grouping matters.
## UI patterns [#ui-patterns]
### Feed [#feed]
The common case. Use flattened data to build a scrollable list.
```text
[ AI Expert Card ]
[ AI Note Card ]
[ Quest Card ]
```
### Grouped by experience [#grouped-by-experience]
Group resources under their experience for a sectioned layout.
```text
Experience: Advanced ML
- AI Expert
- AI Note
```
### Collection [#collection]
Use [collections](/docs/studios/collections) to build playlists, courses, and
learning paths from ordered groups of experiences.
## Mapping fields to UI [#mapping-fields-to-ui]
| API field | UI usage |
| ------------------ | ------------------------ |
| `experience_title` | Section header |
| `resource_title` | Card title |
| `resource_type` | Badge or icon |
| `cover_image` | Thumbnail |
| `creator` | Author info |
| `metrics` | Likes, views, engagement |
## Rendering by resource type [#rendering-by-resource-type]
Different types call for different layouts. Branch on `resource_type`:
```python title="Render by type"
if resource_type == "AI_EXPERT":
show_interactive_ui()
elif resource_type == "AI_NOTE":
show_reading_layout()
elif resource_type == "QUEST":
show_challenge_ui()
```
## Using metrics [#using-metrics]
Each item carries engagement `metrics`. Use them to sort (trending, popular),
highlight popular content, and surface engagement in the UI. See the metrics
section of [Core Concepts](/docs/getting-started/core-concepts) for what is
tracked.
## Designing for scale [#designing-for-scale]
As content grows:
* **Paginate.** Do not load everything at once.
* **Lazy load.** Fetch more as the user scrolls.
* **Cache.** Reuse responses for frequently accessed data.
See [Search and filtering](/docs/guides/search-and-filtering) for the list
parameters that drive all three.
## Common mistakes [#common-mistakes]
* **Treating experiences as content.** An experience is the container; a
resource is the content.
* **Ignoring resource types.** Each type needs its own UI handling.
* **Overfetching.** Always use pagination and filters.
## Putting it together [#putting-it-together]
1. Fetch flattened resources.
2. Map each item to a UI card.
3. Group or filter if needed.
4. Render as a feed or sections.
## Next steps [#next-steps]
# Integration patterns (/docs/guides/integration-patterns)
AISquare is a backend service layer. Your application calls it through your own
backend, which keeps your credentials safe and gives you a place to add caching,
business logic, and personalization. This page walks the three integration
shapes and helps you choose one.
Most integrations follow the same spine:
```text
Frontend -> Your backend -> AISquare API
```
Your backend sits between your application and AISquare. The patterns below are
variations on where that backend lives and what it does.
## Pattern 1: Frontend and backend (recommended) [#pattern-1-frontend-and-backend-recommended]
The common case. A client talks to your backend, and your backend talks to
AISquare.
```text
Client (web or mobile)
|
Your backend
|
AISquare API
```
How a request flows:
1. The user does something in your app.
2. Your backend calls the AISquare API.
3. Your backend processes the response and applies any business logic.
4. The frontend renders the result.
This pattern keeps API keys on the server, lets you add caching and
transformations, and is where per-user personalization lives. Use it for content
feeds, recommendations, and dashboards.
## Pattern 2: Server to server [#pattern-2-server-to-server]
No frontend in the loop. Your backend calls AISquare as part of an internal
workflow.
```text
Your backend -> AISquare API
```
The call runs inside a service or a scheduled job rather than in response to a
user action. Use it for syncing user data, generating reports, and running
analytics jobs.
## Pattern 3: Platform embedding [#pattern-3-platform-embedding]
AISquare powers features inside another product, such as a learning or gaming
platform. Your platform owns the users and authentication, and calls AISquare on
their behalf.
```text
User -> Your platform -> AISquare API
```
Here AISquare acts as a data and intelligence layer. Your platform manages
users, handles authentication, and maps your own user IDs to AISquare users. See
[User onboarding](/docs/guides/user-onboarding) for how to register users and
keep that mapping.
When you embed AISquare, register each of your users through the API and store
their key against your own user ID. A shared account merges everyone's
activity and breaks personalization.
## Choosing a pattern [#choosing-a-pattern]
| Use case | Recommended pattern |
| ----------------- | -------------------- |
| Web or mobile app | Frontend and backend |
| Internal services | Server to server |
| Partner platform | Platform embedding |
## Best practices [#best-practices]
Whichever pattern you pick, the same rules apply.
* **Keep credentials on the backend.** Never call AISquare from the frontend
with a workspace key, and never ship a key in client-side code. See
[Authentication](/docs/getting-started/authentication).
* **Handle errors gracefully.** Retry transient failures, refresh expired
tokens, and validate inputs before sending a request. See
[Errors](/docs/reference/errors).
* **Page through large results.** Do not fetch everything at once. Use the
shared list parameters in [Search and
filtering](/docs/guides/search-and-filtering).
## Putting it together [#putting-it-together]
A typical integration, end to end:
1. The user opens your app.
2. Your backend authenticates the user.
3. Your backend fetches AISquare data.
4. The frontend renders the content.
5. The user interacts, and your backend records or acts on it.
## Next steps [#next-steps]
# Permissions (/docs/guides/permissions)
Access in AISquare depends on three things together: a publication's visibility,
the user's authentication, and the user's role or membership. Not all data is
visible to all users, so your app should check access before fetching protected
content.
## Publication visibility [#publication-visibility]
Every AI Studio (publication) carries a visibility setting.
| Type | Access |
| --------- | ---------------------------------------- |
| `PUBLIC` | Anyone, no authentication required |
| `TEAM` | Authenticated workspace members |
| `PRIVATE` | Authenticated users with explicit access |
In short: public content is open, team content requires workspace membership,
and private content requires explicit access.
## Permission check [#permission-check]
AISquare exposes an endpoint that validates whether a user can access a
publication.
```text
POST /aistudios/permission/
```
```json title="Request"
{
"url": "ai-research-studio"
}
```
It resolves the publication from the `url`, checks the user's membership and
roles, and may set a workspace context for subsequent requests.
### How access is resolved [#how-access-is-resolved]
1. Resolve the publication from the `url`.
2. Check its visibility.
3. Check authentication.
4. Check membership or role.
5. Grant or deny.
| Status | Meaning |
| ------ | -------------------------------------- |
| `200` | Access granted |
| `401` | Authentication required |
| `404` | Publication not found or access denied |
For non-public resources, a `404` may mean the user is not allowed to see the
publication rather than that it does not exist. Do not assume `404` always
means missing data.
### Workspace context [#workspace-context]
When access is granted, AISquare may set a workspace context (a cookie) so
later requests are scoped to the right workspace. Send it along on subsequent
calls to keep behavior consistent.
## Roles and membership [#roles-and-membership]
A user can hold different roles within a publication:
* **Creator.** The owner.
* **Co-creator.** An editor, reviewer, or other collaborator.
* **Workspace member.** A member of the workspace.
Roles determine whether a user can view content, edit or manage resources, and
see metrics and analytics. See [Studios](/docs/studios/overview) for how
creators and co-creators are managed.
## Access patterns [#access-patterns]
Public content needs no check:
```text
user -> request -> public data returned
```
Restricted content goes through authentication and a permission check first:
```text
user -> authenticate -> permission check -> access granted
```
## Best practices [#best-practices]
* **Check before you fetch.** Call the permission endpoint before requesting
protected data.
* **Handle failures.** On `401`, prompt login; on `404`, show not found or
restricted. See [Errors](/docs/reference/errors).
* **Cache results.** Avoid repeating the same check for the same user and
publication.
* **Do not assume access.** Not every user can see every publication.
## Common mistakes [#common-mistakes]
* **Skipping the check.** Leads to surprise failures on later calls.
* **Treating 404 as missing.** It can mean access denied.
* **Ignoring workspace context.** Dropping the cookie causes inconsistent
behavior across requests.
## Putting it together [#putting-it-together]
1. The user selects a studio.
2. Your backend checks permission.
3. If allowed, fetch the data.
4. If denied, handle the error.
## Next steps [#next-steps]
# Search and filtering (/docs/guides/search-and-filtering)
Most AISquare list endpoints accept the same query parameters for search,
filtering, sorting, and pagination. Learn them once and they apply across the
API. These features are what make discovery pages, search experiences, and
scalable feeds possible.
The examples below use the flattened experiences endpoint, but the parameters
work the same way on other list endpoints.
## Search [#search]
Search retrieves content by free text, typically across titles, tags,
categories, and focus areas.
```text
GET /aistudios/experiences/flattened/?search=machine%20learning
```
Keep queries short, and combine search with filters for sharper results.
## Filtering [#filtering]
Filters narrow results by a specific field.
| Parameter | Description |
| ----------------- | --------------------------- |
| `type` | Filter by resource type |
| `category` | Filter by category ID |
| `category_name` | Filter by category name |
| `tags` | Filter by tags |
| `publication_url` | Filter by a specific studio |
Combine filters by adding more parameters:
```text
GET /aistudios/experiences/flattened/?type=AI_EXPERT&category_name=ai
```
## Sorting [#sorting]
Use `ordering` to control the order of results.
| Value | Description |
| ---------- | ------------------------------- |
| `trending` | Based on engagement and recency |
| `newest` | Most recently created |
| `popular` | Highest engagement |
| `updated` | Recently updated |
```text
GET /aistudios/experiences/flattened/?ordering=trending
```
Prefix the value with `-` for descending order:
```text
GET /aistudios/experiences/flattened/?ordering=-newest
```
## Pagination [#pagination]
Pagination returns large datasets in smaller pages.
| Parameter | Description |
| ----------- | ---------------- |
| `page` | Page number |
| `page_size` | Results per page |
```text
GET /aistudios/experiences/flattened/?page=1&page_size=10
```
The response wraps the results with paging metadata:
```json title="Paged response"
{
"count": 100,
"next": "url_to_next_page",
"previous": null,
"results": []
}
```
Follow `next` to load more, and stop when it is `null`.
## Combining everything [#combining-everything]
Search, filters, sorting, and pagination compose into one request.
```text
GET /aistudios/experiences/flattened/?search=ai&type=AI_EXPERT&ordering=trending&page=1&page_size=10
```
## Performance best practices [#performance-best-practices]
* **Always paginate.** Never fetch a full dataset in one request.
* **Keep pages small.** Ten to twenty items per page is a reasonable default.
* **Filter early.** Narrow on the server to cut payload size.
* **Cache hot queries.** Trending and popular results are good candidates.
## Common mistakes [#common-mistakes]
* **Fetching everything at once.** Slow responses and large payloads.
* **Ignoring `next`.** Skipping pagination leaves data behind.
* **Overusing search.** Prefer filters where a field match will do.
## Example flow [#example-flow]
1. The user searches for "ai".
2. Apply a filter, for example `type=AI_EXPERT`.
3. Sort by `trending`.
4. Fetch page 1.
5. Load more by following `next`.
## Next steps [#next-steps]
# Token lifecycle (/docs/guides/token-lifecycle)
AISquare supports a token-based authentication flow built on access tokens and
refresh tokens. Tokens let you authenticate users without resending the API key
on every request. This page covers the flow, how to refresh safely, and how to
handle failures in a production system.
## Token types [#token-types]
| Token | Purpose | Expiry |
| ------------- | --------------------------- | ------- |
| Access token | Authenticates API requests | 7 days |
| Refresh token | Generates new access tokens | 30 days |
## The flow [#the-flow]
```text
API key -> login -> access token + refresh token
|
use access token for requests
|
access token expires
|
use refresh token to get a new access token
```
### Obtain tokens [#obtain-tokens]
Call the login endpoint with the user's API key. You receive an access token and
a refresh token.
### Use the access token [#use-the-access-token]
Send the access token on every authenticated request.
```text
Authorization: Bearer
```
### Handle expiration [#handle-expiration]
The access token expires after 7 days. When a request fails with an
authentication error, detect it and trigger a refresh.
### Refresh the token [#refresh-the-token]
Use the refresh token to mint a new access token, then replace the expired one.
```text
refresh_token -> new access_token
```
## Where to manage tokens [#where-to-manage-tokens]
Store and refresh tokens on your server, not in the browser. A backend keeps
credentials out of client code, centralizes refresh logic, and avoids token
leakage. See [Integration patterns](/docs/guides/integration-patterns).
A backend-managed flow looks like this:
```text
user request
|
backend checks token validity
|
if expired -> refresh token
|
call AISquare API
```
Storing tokens in a frontend app risks leakage, makes refresh hard to
coordinate, and widens your attack surface. Avoid it.
## Refresh strategies [#refresh-strategies]
Pick the strategy that matches how long your sessions run.
* **Reactive.** Make the request; if it fails on expiry, refresh and retry.
Simple, and fine for low-traffic paths.
* **Proactive.** Track the expiry time and refresh just before it lapses.
```text
if current_time > expiry_time - buffer:
refresh token
```
* **Background.** Refresh on a schedule so long-running sessions never block on a
refresh.
## Handling failures [#handling-failures]
| Situation | What to do |
| --------------------- | --------------------------------------------------- |
| Access token expired | Refresh with the refresh token, then retry. |
| Refresh token expired | Re-authenticate with the API key to get new tokens. |
| Invalid token | Clear stored tokens and restart the flow. |
See [Errors](/docs/reference/errors) for the status codes behind these cases.
## Storage best practices [#storage-best-practices]
* **Store securely.** Use encrypted storage; never keep tokens in plain text.
* **Associate with the user.** Keep tokens keyed to your user ID.
```text
user_id -> access_token + refresh_token
```
* **Rotate safely.** Replace old tokens immediately after a refresh and never
reuse a stale one.
## API key or tokens [#api-key-or-tokens]
| Scenario | Recommended |
| -------------------- | ------------------------- |
| Simple backend calls | API key |
| User sessions | Access and refresh tokens |
| Long-running apps | Tokens with refresh |
## Putting it together [#putting-it-together]
1. Register the user and get an API key.
2. Log in to get tokens.
3. Use the access token for requests.
4. Refresh when it expires.
5. Repeat.
## Next steps [#next-steps]
# User onboarding (/docs/guides/user-onboarding)
AISquare supports per-user identity and personalization. Instead of one shared
account, give each of your users their own AISquare account, created
programmatically from your backend. Your platform owns sign-up; AISquare owns
identity, activity, personalization, and metrics for each user.
Register users through the API and hold a per-user API key for each one. Your
users never sign up with AISquare directly.
## User lifecycle [#user-lifecycle]
A user moves through these stages:
```text
User signs up on your platform
|
Backend registers the user in AISquare
|
AISquare returns an API key
|
Backend stores the key
|
User interacts with AISquare-powered features
```
## Onboarding a user [#onboarding-a-user]
### Register the user [#register-the-user]
When a new user is created on your platform, call the AISquare registration API
to create a matching AISquare user. Registration is programmatic, so your users
do not sign up by hand. They may receive an automated welcome email.
### Store the credentials [#store-the-credentials]
Store the returned API key securely on your backend and associate it with your
own user ID.
```json title="User mapping"
{
"user_id": "user_123",
"aisquare_api_key": "api_key_xyz"
}
```
### Authenticate requests [#authenticate-requests]
When the user acts in your app, your backend retrieves their key and calls
AISquare on their behalf.
```text
Authorization: Bearer
```
### Personalize [#personalize]
Because each user has a unique account, AISquare can track their activity,
engagement, and performance, and use it to drive personalized content, adaptive
difficulty, leaderboards, and per-user analytics.
## Token-based flow (alternative) [#token-based-flow-alternative]
Instead of sending the API key on every call, you can exchange it for tokens.
Log in with the key, receive an access token and a refresh token, then send the
access token the way you would the key. Refresh it when it expires.
| Token | Expiry |
| ------------- | ------- |
| Access token | 7 days |
| Refresh token | 30 days |
See [Token lifecycle](/docs/guides/token-lifecycle) for the full flow, including
how to detect expiry and refresh safely.
## Mapping users between systems [#mapping-users-between-systems]
Keep a mapping between your platform user ID and the AISquare user (or their
key) so identity stays consistent across both systems.
```text
your_user_id -> aisquare_user_id / api_key
```
## Why not a shared account [#why-not-a-shared-account]
Using one AISquare account for every user merges their data: mixed activity, no
personalization, inaccurate metrics, and broken leaderboards. Per-user accounts
give you accurate activity tracking, personalized recommendations, meaningful
metrics, and user management that scales.
## Best practices [#best-practices]
* **Register lazily.** Create an AISquare user only when you first need one.
* **Store keys securely.** Keep keys in encrypted storage on the backend, never
in the frontend. See [Authentication](/docs/getting-started/authentication).
* **Avoid duplicates.** Make sure a user is not registered more than once.
* **Monitor the flow.** Track registration failures and retry them.
## Putting it together [#putting-it-together]
1. The user signs up on your platform.
2. Your backend registers the user in AISquare.
3. The key is stored securely.
4. Your backend uses the key for requests.
5. AISquare tracks the user's activity.
## Next steps [#next-steps]
# Compliance and audit (/docs/reference/compliance)
Sooner or later someone outside your team asks you to prove why an agent did
what it did. A regulator, an internal auditor, a customer's security review, a
court. The frameworks they bring differ, but the thing they ask for is the
same: evidence, per decision, that you knew what the system was doing and could
intervene.
AISquare's answer is the decision record. This page lays out what that record
contains and maps it to the three frameworks that come up most often: the EU AI
Act, ISO/IEC 42001, and the NIST AI RMF.
## What every governed decision leaves behind [#what-every-governed-decision-leaves-behind]
Once an agent is [connected](/docs/govern/connect-your-agents), every run
produces the same set of artifacts, whether anyone is watching or not:
* **The reasoning graph.** The claims the agent made, the evidence behind each
one with its confidence, the assumptions it filled in, and the inference
chain that connected them. See [Understand](/docs/govern/understand).
* **Policy verdicts.** Each action passed or blocked against a named rule, with
the citation attached. Proof that governance ran is part of the record, not a
transient log line. See [Prevent](/docs/govern/prevent).
* **Corrections.** When a reviewer fixes a decision, the correction is written
back as durable context, with who changed what. See [Fix](/docs/govern/fix).
* **A signed, tamper-evident audit record** for the run, including an AIBOM
(AI Bill of Materials) listing the models and tools involved, persisted as
enterprise memory you can query and [replay](/docs/govern/fix). See
[Remember](/docs/govern/remember).
Sensitive data is handled before any of this is stored: detected PII, PHI, and
PCI is screened at connection time (redacted when your data policy is set to
mask), and memory is scoped to your workspace.
No tool makes you compliant. Compliance is a property of your organization,
its processes, and its people. What AISquare removes is the scramble: when an
auditor asks for evidence, the record already exists, structured, per
decision, from the day the agent was connected.
## EU AI Act [#eu-ai-act]
For high-risk AI systems, the EU AI Act requires, among other things, that the
system keeps automatically generated logs over its lifetime (Article 12), that
it is transparent enough for the people operating it to understand and use its
output (Article 13), and that it remains under effective human oversight,
including the ability to intervene or interrupt (Article 14). Deployers carry
their own obligations, including retaining those logs.
| The Act asks for | The record provides |
| ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Automatic, lifetime logging of operation (Art. 12) | Every run recorded as a trace with per-step model, tool, latency, and cost, kept as durable enterprise memory |
| Output the operator can interpret (Art. 13) | The reasoning graph readable as a flow diagram, a graph, or a plain-English narrative, not a raw transcript |
| Effective human oversight with the ability to intervene (Art. 14) | Policy gates that allow, deny, escalate, or modify before an action runs, plus in-place corrections kept on the record |
| Reconstruction after an incident | Any decision reopened with its claims, evidence, assumptions, and the rule that fired, and replayed |
## ISO/IEC 42001 [#isoiec-42001]
ISO/IEC 42001 certifies an AI management system. An auditor working through it
needs two things from your tooling: documented controls, and records showing
those controls actually operate. Both are what the decision record is.
| The audit asks for | The record provides |
| ------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Documented, operating controls | Policies enforced at the decision point, each verdict citing the named rule it ran against |
| Evidence of monitoring and measurement | Per-decision traces with confidence signals, including the confidence of the reasoning extraction itself |
| Corrective action and continual improvement | Reviewer corrections written back as durable context, so the fix is provably in force on later runs |
| Records management | A signed, tamper-evident record per decision, scoped to the workspace and queryable after the fact |
## NIST AI RMF [#nist-ai-rmf]
The NIST AI Risk Management Framework is organized around four functions. The
Trust Loop lines up with them directly:
| Function | Where it lands in AISquare |
| ----------- | ----------------------------------------------------------------------------------------------------------------- |
| **Govern** | Decision-level policies with named rules, workspace scoping, and an accountable record of every intervention |
| **Map** | The reasoning graph documents how the system actually behaves in context: what it relied on and what it assumed |
| **Measure** | Confidence on every piece of evidence, extraction confidence per decision, and per-step cost, latency, and tokens |
| **Manage** | Prevent blocks the bad action, Fix corrects the one that happened, Remember carries the outcome forward |
## Answering an audit, concretely [#answering-an-audit-concretely]
A compliance lead asks: "Show me every automated refund above $25 last
quarter, the rule that approved each one, and any human correction along the
way."
Without a decision record, that is weeks of transcript archaeology. With one,
it is a query: each refund decision carries its policy verdict
(`refund-auto-approve`, pass, with citation), its evidence and confidence, and
any reviewer correction, all on the same graph. A
[Studio report](/docs/studios/overview) built on those decisions is auditable
by construction, because every figure traces back to the verdicts that
produced it. The proving was done when the decisions were governed, not when
the question arrived.
## Next steps [#next-steps]
# Errors (/docs/reference/errors)
AISquare uses standard HTTP status codes to signal success or failure. An error
response means authentication failed, input was invalid, access was restricted,
or a resource was not found. This page lists the codes and how to handle each.
## Status codes [#status-codes]
| Status | Meaning |
| ------ | ------------------------------------- |
| `200` | Request successful |
| `201` | Resource created |
| `204` | Resource deleted |
| `400` | Invalid request or missing parameters |
| `401` | Authentication required or failed |
| `403` | Access forbidden |
| `404` | Resource not found or access denied |
| `409` | Conflict (trace ingest routing) |
| `500` | Internal server error |
## 401 Unauthorized [#401-unauthorized]
Returned when authentication is missing, the token or API key is invalid, or the
session has expired.
**Handling.** Make sure credentials are included, verify the token or key, and
re-authenticate if needed. See [Token
lifecycle](/docs/guides/token-lifecycle) for the refresh flow.
## 403 Forbidden [#403-forbidden]
Returned when the user lacks the required role, or the endpoint is restricted
(for example, owner-only metrics).
**Handling.** Verify the user's role and access level. See
[Permissions](/docs/guides/permissions).
## 404 Not Found [#404-not-found]
Returned when a resource does not exist, a publication is invalid, or access to
a non-public resource is restricted.
**Handling.** Verify identifiers (`id`, `url`, `username`) and confirm the user
has access.
For non-public resources, `404` can mean access denied rather than
non-existence. Treat it as "not accessible" where that matters.
## 400 Bad Request [#400-bad-request]
Returned when required fields are missing, the request format is invalid, or
query parameters are incorrect.
**Handling.** Validate the request body, ensure required fields are present, and
check parameter formats before sending.
## 409 Conflict β trace ingest [#409-conflict--trace-ingest]
Returned by the explainability trace-ingest endpoint when a span batch cannot
be routed to an agent. The response carries a machine-readable code in
`detail.code`; branch on the code, not the message.
### `no_agent_identity` [#no_agent_identity]
A root span arrived carrying no [agent identity](/docs/govern/agent-identity).
The gateway routes each trace by (workspace, agent name), so a nameless root
span has nowhere to go.
**Handling.** Fix the integration: name the agent
(`AgentRunTracer(agent_name=...)`, `Agent(name=...)` for Agno,
`metadata={"agent_name": ...}` for LangChain, or `X-Agent-Name` on the proxy).
Retrying will not succeed β the batch is rejected until it carries a name.
### `awaiting_trace_route` [#awaiting_trace_route]
A child-only batch arrived before the root span that names its trace. The
gateway cannot route children until the root establishes the identity.
**Handling.** Transient. The SDK retries the batch automatically once the root
lands; no action needed unless it persists.
### `agent_not_registered` [#agent_not_registered]
The trace carries a name, but that agent is not registered in the workspace.
**Handling.** Register the agent: `PUT
/api/v2/iam/workspaces/{ws}/agents/{name}/`, or the dashboard's **Connectors
-> Agents** "Register agent" button. Or avoid the case entirely: pre-register
your roster with `EXPLAINABILITY_AGENTS`, or enable auto-discovery
(`autoregister_unknown_agents`) on the workspace.
Run `explainability-doctor`: its delivery-backlog check reads the local
delivery queue and tells you which case you are in, and its agent-identity
check flags naming gaps in the integration itself.
## 500 Internal Server Error [#500-internal-server-error]
Returned on an unexpected failure on the server.
**Handling.** Retry if appropriate, log the error for debugging, and contact
[Support](/docs/reference/support) if it persists.
## Endpoint-specific behavior [#endpoint-specific-behavior]
A few endpoints have notable error behavior:
* The **permission** endpoint may return `404` for access denial.
* The **metrics** endpoint returns `403` for unauthorized users.
* **Collection** and **publication** endpoints return `400` when the `url` is
missing.
## Best practices [#best-practices]
* **Validate inputs first.** Avoid unnecessary `400` errors.
* **Handle auth failures centrally.** Put retry and re-auth logic in one place.
* **Do not assume `404` means missing.** It can indicate restricted access.
* **Log errors.** Capture status codes and responses for debugging.
## Next steps [#next-steps]
# Support (/docs/reference/support)
If you hit an issue while integrating or using the AISquare APIs, reach out and
we will help.
## Contact [#contact]
For technical assistance, email **[bots@aisquare.studio](mailto:bots@aisquare.studio)**.
## When to reach out [#when-to-reach-out]
Contact support when:
* API requests consistently fail.
* Authentication issues cannot be resolved.
* Unexpected `500` errors occur.
* Returned data is inconsistent or incorrect.
* Access or permission behavior is unclear.
Before you do, check [Errors](/docs/reference/errors) to see whether the status
code already explains the failure.
## What to include [#what-to-include]
Give us enough to reproduce the problem:
* Endpoint used
* Request method (`GET`, `POST`, and so on)
* Request payload, if any
* Response status code
* Error message
* Timestamp of the request
```text title="Example report"
Endpoint: POST /aistudios/metrics/
Status: 403
Body: { "url": "ai-research-studio" }
```
Do not include API keys, tokens, or personal user data in a support request.
Redact them before sending.
## Before reaching out [#before-reaching-out]
A quick check often resolves the issue faster than a round trip:
* Confirm the required parameters for the endpoint.
* Confirm your authentication method. See
[Authentication](/docs/getting-started/authentication).
* Confirm the access rules for the resource. See
[Permissions](/docs/guides/permissions).
## What to expect [#what-to-expect]
A support response may include clarification on API usage, debugging
assistance, or confirmation of an issue with resolution steps.
## Next steps [#next-steps]
# Collections (/docs/studios/collections)
A [Studio](/docs/studios/overview) holds many
[experiences](/docs/studios/experiences-and-resources). A **collection** is how
you group them into something with a shape and an order: a learning path, a
course, a curated reading list. Where an experience answers "what is this piece
of content," a collection answers "what should someone go through, and in what
order."
## What a collection does [#what-a-collection-does]
A collection is a curated group of experiences scoped to one Studio. It lets you:
* **Group related experiences** so they read as one journey rather than a loose
pile.
* **Set the order** the experiences appear in, and keep that order stable.
* **Control visibility**, so the right audience sees the collection and no one
else does.
A collection orders experiences. The experiences themselves order their own
resources. If you want to sequence individual items (an AI Expert, then a Note),
that lives inside an experience, not in the collection above it. See
[Experiences and resources](/docs/studios/experiences-and-resources).
## Ordering [#ordering]
The order of experiences in a collection is preserved. This is what makes a
collection usable as a path: the first experience is the starting point, and
each one follows the last in a sequence you control. Reordering the collection
reorders the journey, and the new order is what every viewer sees.
Only eligible experiences can be added to a collection. An experience must be
published and must belong to the same Studio as the collection. You cannot pull
an experience from another Studio into the order.
## Visibility [#visibility]
Every collection carries a visibility setting that decides who can open it. It
follows the same model as the Studio itself.
| Visibility | Who can see it |
| ---------- | ---------------------------------- |
| `public` | Anyone, no authentication required |
| `private` | The owner only |
| `team` | Members of the workspace |
| `org` | Anyone in the organization |
Visibility is enforced together with the publication's own access rules. A
public collection on a public Studio is reachable without signing in; a team
collection requires workspace membership; a private collection is the owner's
alone. The full rules, including how publication visibility and user role
combine, are in [Permissions](/docs/guides/permissions).
A collection cannot widen access beyond its Studio. If the publication is
private, marking a collection public does not make it reachable to the world.
Access is always the publication's rules and the collection's visibility taken
together.
## Worked example: a learning path [#worked-example-a-learning-path]
A Studio that documents your platform groups its experiences into an onboarding
path:
```text
Collection: New engineer onboarding (visibility: team)
|-- Experience: Our architecture (start here)
|-- Experience: The billing service
'-- Experience: Deploying safely (finish)
```
Set to `team` visibility, the path is visible to everyone in the workspace and
no one outside it. The order is fixed, so a new hire works through architecture
before deployment, not the other way around. Because each experience draws on
the governed [reasoning and memory graph](/docs/collective-intelligence), the
path teaches what the system actually decided and why, not a hand-written
approximation that drifts out of date.
## Working with collections in the API [#working-with-collections-in-the-api]
Collections are a first-class API resource. You can list them, create and update
them, set their ordered experiences, and fetch the collections for a given
Studio by its `url`. The endpoints, request shapes, and status codes are in the
[API Reference](/docs/api-reference/overview), and the parameters for filtering
and paging lists are covered in
[Search and filtering](/docs/guides/search-and-filtering).
## Next steps [#next-steps]
# Experiences and resources (/docs/studios/experiences-and-resources)
A [Studio](/docs/studios/overview) turns governed intelligence into things a
person opens and uses. Those things have a shape. A Studio is made of
**experiences**, and an experience is made of **resources**. Get this one
distinction right and the rest of the model follows.
## Experience and resource [#experience-and-resource]
These two are easy to conflate, so keep the line sharp.
* An **experience** is a container: a topic, a workflow, or a module, such as
"Advanced Machine Learning Models" or "Our Billing Service." It groups related
content but is not itself the content.
* A **resource** is the item inside an experience: the actual thing a person
reads, asks, or works through.
One experience holds many resources. When you are deciding where something
belongs, ask whether it is the shelf or the thing on the shelf. The experience
is the shelf.
```text
Experience: Our Billing Service
|-- Resource: Webhook retry expert (AI Expert)
|-- Resource: Refund policy (Note)
'-- Resource: Onboarding walkthrough (Quest)
```
## The four resource types [#the-four-resource-types]
Every resource has exactly one type. The type decides how the resource behaves
and how a frontend renders it.
| Type | What it is | Drawn from the graph as |
| ----------- | ------------------------------------- | ------------------------------------------------------- |
| `AI_EXPERT` | An interactive expert you can ask | Answers carrying the reasoning and evidence behind them |
| `AI_NOTE` | Informational or educational content | A written explanation grounded in governed decisions |
| `QUEST` | A task-based or challenge-driven flow | A guided path with each step checked against policy |
| `PODCAST` | Audio content | A narrated summary generated from the same record |
The types matter because a Studio is not a generic CMS. Each type is a different
way of consuming the [reasoning and memory
graph](/docs/collective-intelligence). An AI Expert answers a question on
demand; a Note presents a settled explanation; a Quest walks someone through a
process; a Podcast narrates it. The knowledge underneath is the same governed
record. The resource type is how it is served.
### Why an AI Expert is more than a chatbot [#why-an-ai-expert-is-more-than-a-chatbot]
An `AI_EXPERT` resource answers from the graph, so its replies can show the
claims and evidence behind them and inherit the corrections your team already
made. That is the difference between a chatbot that guesses and an expert that
[explains why](/docs/govern/understand). The same governed memory that made the
decision trustworthy is what makes the answer trustworthy.
## How a Studio is put together [#how-a-studio-is-put-together]
Experiences and resources sit inside the wider Studio model. The full hierarchy:
```text
AI Studio (Publication)
|-- Experiences
| '-- Resources (AI Expert, Note, Quest, Podcast)
|-- Creator and co-creators
|-- Collections (group experiences)
'-- Metrics and Activity
```
* **Creator and co-creators** are the humans who own the Studio. The creator
owns it; co-creators collaborate with a role (such as editor or reviewer) and
a status (invited or accepted). Their corrections are what keep the content
honest over time.
* **[Collections](/docs/studios/collections)** group experiences into ordered
sets, such as a learning path or a course.
* **Metrics and activity** track engagement (views, likes, shares, bookmarks)
and power ranking and personalization.
For the entity definitions and the API fields behind each of these, see [Core
Concepts](/docs/getting-started/core-concepts).
## Flattened and nested responses [#flattened-and-nested-responses]
The API returns this content in two shapes, and the right one depends on what
you are building.
* **Flattened** returns one row per resource, with the parent experience
repeated on each row. It looks redundant, and that is the point: a frontend
can render the rows as a flat list with no joining. Use it for feeds, search
results, and discovery pages.
* **Nested** keeps resources inside their experience. Use it for a detailed
experience view where the grouping is what matters.
Turning these responses into a UI (feeds, cards, rendering by resource type) is
the subject of the [Content modeling](/docs/guides/content-modeling) guide.
## Next steps [#next-steps]
# Studios Overview (/docs/studios/overview)
The spine so far has been about making decisions trustworthy. [Govern](/docs/govern/connect-your-agents)
runs the Trust Loop on every agent decision, and [Collective
Intelligence](/docs/collective-intelligence) compounds those decisions on a
shared reasoning and memory graph. Studios are the payoff. They are where that
governed intelligence stops being infrastructure and becomes something a
customer opens, reads, and uses.
A Studio is the last step of the spine:
> Govern your agents, run the Trust Loop on every decision, let Collective
> Intelligence compound on the graph, then ship it as a **Studio**.
## What a Studio is [#what-a-studio-is]
A Studio is a governed, reusable unit of knowledge, AI, and humans. Three things
travel together inside it:
The combination is the point. A pile of documents is not a Studio, and neither
is a bare model endpoint. A Studio is the knowledge, the AI that reasons over
it, and the people who own and correct it, packaged as one thing you can publish
and others can use. In the API it is a publication, addressed by a unique `url`
such as `ai-research-studio`. See [Core
Concepts](/docs/getting-started/core-concepts) for that entity model.
This is also where the platform's equation lands:
[AI + BI = CI](/docs/collective-intelligence#ai--bi--ci). A Studio is the room
where artificial intelligence and brain intelligence meet. Agents reason over
governed knowledge, humans own and correct the result, and the collective
intelligence that compounds between them is what your customers actually use.
## How a Studio draws on the graph, and writes back to it [#how-a-studio-draws-on-the-graph-and-writes-back-to-it]
A Studio is not a fresh start. It is built on the
[reasoning and memory graph](/docs/collective-intelligence) that Govern and
Collective Intelligence have already filled. That is what separates a Studio
from an ordinary content product: every experience it serves can draw on
governed decisions rather than guesses. And the flow runs both ways: the
questions people ask in a Studio, the preferences they set, and the corrections
creators make write back to the same graph, so using a Studio compounds the
layer it is built on.
* **Reasoning** is already structured. Each answer a Studio gives can carry the
claims and evidence behind it, because the graph stored the reasoning, not
just the output. See [Understand](/docs/govern/understand).
* **Memory** is already governed. The corrections your team made on earlier runs
ride along as durable context, so a Studio inherits judgment instead of
relearning it. See [Remember](/docs/govern/remember).
* **Policy** is already proven. The verdicts that fired during governance stay
on the record, so an experience can show that what it served was checked, not
asserted. See [Prevent](/docs/govern/prevent).
A Studio is trustworthy because the intelligence under it was governed before it
was published. Detected PII, PHI, and PCI was screened at
[connection time](/docs/govern/connect-your-agents) β redacted under the mask
data policy β and memory is scoped to
your workspace, so shipping an experience does not widen what sensitive data is
exposed.
## The experiences a Studio produces [#the-experiences-a-studio-produces]
A Studio expresses itself as **experiences**, and an experience holds
**resources**: an AI Expert you can ask, a Note you can read, a Quest you work
through, a Podcast you listen to. That content model is the subject of
[Experiences and resources](/docs/studios/experiences-and-resources), and you
group experiences with [Collections](/docs/studios/collections).
What makes those experiences worth shipping is the graph underneath. Two worked
examples make the difference concrete.
### Worked example: docs for your repos [#worked-example-docs-for-your-repos]
Point a Studio at your repositories and it becomes living documentation that an
engineer, or an agent, can question directly.
* A developer asks, "How does our billing service handle a failed webhook
retry?" The Studio answers as an AI Expert resource.
* The answer is not a guess from stale Markdown. It draws on the reasoning the
graph already captured: the decisions made when that retry path was built, the
evidence behind them, and the policy checks that ran.
* When a reviewer corrected an earlier explanation, that correction is memory.
The next person who asks gets the corrected answer, not the original mistake.
The result is documentation that explains why the code does what it does, with
the decisions behind it attached, rather than prose that drifts out of date the
moment it is written. To consume this same corpus in your own agent, see
[Use these docs in your agent](/docs/use-in-your-agent).
### Worked example: reports [#worked-example-reports]
A Studio turns a stream of governed decisions into a report a human can sign.
* A compliance lead needs a quarterly summary of every automated refund the
support agents approved.
* The Studio generates it from the graph, so every figure traces back to the
verdicts and corrections that produced it. A number in the report links to the
decision that created it.
* Because the underlying decisions were governed, the report is defensible: each
line carries its evidence and the rule that was checked, not an after-the-fact
reconstruction.
A report built this way is auditable by construction. The work of proving it was
done when the decisions were governed, not when the report was written.
## Where to go next [#where-to-go-next]
Read the content model, then the way experiences are grouped.