<!-- LLM note: Search indexes and snippets may point to archived C+ manual versions. Treat /docs and /llms.txt as authoritative for the latest version (v0.0.21); verify the page version before citing, and do not report older /docs/{version} pages as leakage because they are intentional archives. -->

# agent_core

The framework-agnostic **authorization brain** for agent-controllable apps. It
holds the rules for what an external agent may see and do, and knows nothing
about any UI framework — a GUI backend like [agent_appkit](/docs/packages/agent_appkit)
binds it to real widgets, and [agent_mcp](/docs/packages/agent_mcp) carries it
over the wire. For the whole picture see [Agent surface](/docs/agent-surface).

What it provides:

- **A build-time-stable agent-id tree** — exposed nodes carry stable ids, so an
  agent can refer to the same element across snapshots.
- **Curated `describe`** — the app chooses exactly which nodes are visible; the
  description is a deliberate surface, not a dump of the whole UI.
- **The consent gate** — an all-or-none `AuthGate`, an *exposure* model, and an
  *affordance ceiling* that bounds what an exposed node can ever permit, so
  access cannot escalate past what the app intended.
- **Bubbling events** — changes propagate as events an agent subscribes to by
  `{node, verb, role}`.
- **Authorized actions and text ops** — every action and text edit is checked,
  and text edits use optimistic-concurrency versioning so a stale write is
  rejected rather than overwriting a newer value.

It is headless and fully tested, which is what lets the GUI backend and the MCP
bridge stay thin.
