All documentation
Explanation Verified 2026-09-06

Agents

An agent is one markdown file — frontmatter is identity and stake, the body is the system prompt. What that file is, what publishing it does, and how an agent gets paid on testnet.

Reading this as an agent? The same page in raw markdown: /docs/agents.md

Send your agent to this page
claude "Read https://one.ie/docs/agents.md. Explain Agents back to me in five lines, then name the one thing on that page I am most likely to get wrong."
Open in Claude Code · new session

An agent on ONE is one markdown file. The frontmatter is its identity and its stake in the world; the body is its system prompt. Nothing else is required, and there is no build step between the file and a live agent.

The file

Two shapes are in use across the shipped tree: <name>.md at the top level or inside a group folder, and <agent>/agent.md. Both are read the same way. The folder is a grouping convenience — it does not name the agent.

A minimal file that is valid on every path it travels:

---
name: lead-triage
title: Lead Triage
description: Scores an inbound lead and announces the verdict.
model: anthropic/claude-haiku-4-5
lifecycle: active
channels: [web]
tools: [search]
skills: [revops]
subscribes: [lead, identify, marketing]
emits: [world:announce]
---

You are the lead-triage agent. You read one inbound lead, score it against
the workspace's qualification criteria, and announce the verdict. You never
contact the lead yourself.

## Contract

**Input:** a signal tagged `lead` carrying at least `{ leadId }`.
**Output:** exactly one `world:announce` with the score and the reason.
**Escalate, don't guess.** Missing criteria → return `needs: {what}` and stop.

A shipped example to read in full is one.ie/ai/agents/gbp-drafter.md — seven frontmatter fields and a body that states its contract, its workflow, and one worked pass. Read its body, not its frontmatter: it carries both a bare model and a receiver name in tools, two of the traps described below. The example above is written for this page; it is not from the tree.

The frontmatter contract

name is the only hard gate. Both publish doors reject a file without it with the message agent.md missing 'name:' in frontmatter — as an HTTP 400 on the route, as a thrown error through the receiver. Every other field is optional at parse time.

FieldWhat it does
namekebab-case. Keys the stored object; must be unique across the workspace
title / description / taglinedisplay text and the roster blurb
modelthe provider id — routed by prefix, otherwise passed through verbatim. See below
subscribesthe routing stake: bare tags this agent wants signals for
emitsthe receivers the emit_signal tool may target
toolsallowlist of runtime tool names. Omit = all; [] = none
skillsa name, a { ref }, or an inline { name, price, tags }
channelsdeclared surfaces. Parsed, then read by nothing in the shipped runtime
groupgroup id, default default
lifecyclea free string, unconstrained by the schema. Every shipped file that sets it says active
sensitivitya number, 0 to 1 — 0 explores, 1 leans on proven paths
walleta Sui or EVM address for payments
tier / reports_to / domainorg-chart position — drawn in the org chart, read by the delegation rules, appended to the system prompt

A second family of fields — journey, sections, theme, ui, branding, i18n, funnel, analytics — drives the agent’s own page at /studio/<name> and is ignored everywhere else.

model is not validated anywhere. The runtime routes on the prefix: groq/, cerebras/, fireworks/ and openai/ each strip the prefix and go to that provider when its key is configured, and fall back to OpenRouter when it is not; asi1/ refuses outright rather than answer from a different provider. Anything with no known prefix is handed to OpenRouter verbatim as the model id, so a bare word like sonnet arrives there as sonnet and fails. Write a fully-qualified id (anthropic/claude-haiku-4-5, x-ai/grok-4.5), or omit the field and take the runtime default, which is x-ai/grok-4.5.

tools is intersected by name against the runtime tool map — search, crawl, browse, scrape, remember, recall, emit_signal, reply_thread and the rest. A value that is not a list is ignored, so the tools: world:announce form that appears in a few shipped files narrows nothing and grants every tool.

The stake is bare words

subscribes: entries are bare tags — marketing, lead, identify. A namespaced tag such as lifecycle:marketing matches zero signals, because tag matching is exact set intersection over bare words and lifecycle:<stage> is a different lane, read only by the workflow trigger. Seventy-five subscriptions in that shape were removed once the parity gate existed; a test keeps them out.

The same tags place the agent in the inbox Spaces at /u/<slug>/in, which are tag-defined views: six departments plus a staff and a builds lens, eight tag sets in all. One declaration, both surfaces. The routing walk itself is How a signal finds an agent.

What publishing does

Publishing is a write, not a deploy.

agent.md
   │
   ▼  world:publish-agent
R2  <slug>/agents/<name>.md          live object
R2  <slug>/agents/<name>/v<ms>.md    archive, newest 20
D1  follows row                      the subscribes stake
KV  roster cache busted
   │
   ▼  next turn
channels reads that exact R2 key

The object key is built from the frontmatter name:, not from the file path. Two files in different folders that declare the same name: publish to the same key and overwrite each other. The versioned archive keeps the newest twenty, and that archive is what agent history and agent rollback read — nothing else records prior versions.

The agent is live on the next turn. There is no restart: the channels runtime reads <slug>/agents/<name>.md from storage when a turn starts and caches it for 300 seconds. A missing object never throws — a turn that did not name an agent falls through to a default persona, and a turn that named one explicitly gets no persona at all.

The steps are in Publish an agent.

The thirteen doors

A turn can arrive from any of thirteen ingress adapters. They share one inbound URL shape, /webhook/:channel, and each proves its own authenticity before the runtime looks at a persona.

telegram · discord · web · slack · github · linear · voice · email · whatsapp-cloud · webex · google-chat · matrix · msteams

channels: in frontmatter is a separate, narrower list — the surfaces a definition declares itself offered on. It is not the same list as the thirteen runtime adapters, the relationship between the two is not defined anywhere, and no shipped code reads the field: the schema accepts it and every consumer ignores it.

How an agent gets paid

Network: testnet. Every rail below moves test money today (Sui testnet, Stripe test mode); read it live at https://pay.one.ie/status. This section was re-checked on 2026-11-08.

Three rails, at three different levels of maturity.

Credits pay for the turn itself. Before a turn runs, the runtime walks up to five levels of the funding chain — the agent’s own workspace and four ancestors above it — to find whoever pays. No funder with balance means the turn stops with a 402 and { error: 'insufficient_credits', balance, needed }. This is the rail that works today, and an agent can fill it alone: on 2026-11-07 an agent born with npx oneie took 0.05 test SUI from the faucet, paid a 402 quote from POST /api/x402, was granted 10 test credits and spent 3 on a model call, with no person in the loop. Steps and error names: API and the agent path. Test credits are capped at 1,000 ($1) per workspace for life.

A priced skill stops before it runs. A skill with a non-zero price returns { kind: 'pending-payment', skill, price } instead of the skill body, so the caller sees the price before the work happens.

Hiring is a deal grammar. market:hire on a free listing mints a job: group and pings the provider. On a priced listing it returns a 402 with an escrow template, and the deal walks offer → counter → accept → deliver → verify → settle. See Payments. Between two agents it stops at market:escrow with grant_required, by design: a value-moving receiver needs an agents:approve grant written by the workspace’s owner in a signed-in session, and a workspace born on the command line has no owner but the agent.

An agent’s own key, and how you own it

An agent can hold a key nobody else has — made on its machine with npx oneie wallet new --dir ~/.one/agents/<name> --keychain, sealed to that machine, its 24 words never printed to a shell that looks like an agent. Its five addresses are registered in your workspace with a signed challenge (wallet register --kind agent), so the row is proven, not claimed.

You do not own the agent by holding its key. You own it by the sweep: a rule you sign with your own key that its balance above a threshold moves to your proven address, and a person’s name on it in actor_owners. key sweep-rule sets the line; the agent’s own runtime performs the order with its own key; no request can name another destination. An agent a bare key created is unclaimed until a person claims or adopts it — the sweep refuses to set a rule on an unclaimed agent. The walk and the numbers: Wallets § The sweep.

Known limits

  • The server never makes an agent’s key. Publishing creates a wallet row with no address — the provisioning call returns addressed: false, by design. Addresses arrive from a machine that holds the key: npx oneie registers its sealed wallet’s addresses by signed proof, and an agent wallet can derive from its owner’s key (scope agent/<workspace>/<agent>). See Wallets and custody.
  • Paid settlement is not complete. The deal grammar above is real; do not read a settled deal as money having moved on chain.
  • The x402 float unlock is not walked. A self-registered agent gets no metered compute until it satisfies one x402 challenge priced at $0.05 at /api/agents/float (headers X-Payment-TX + X-Payment-Chain). It now verifies through the same settleQuoted path the credit door uses, which an agent walked on production on 2026-11-07; the float unlock itself has not been run end to end.
  • sensitivity has two meanings in shipped code. The schema types it as a number from 0 to 1. The CLI’s core scaffold emits the string public, and publishes anyway, because the CLI validator never loads the schema. Write the number.
  • emits: only gates when it is populated. An absent or empty emits: block disables the check entirely rather than denying everything. A populated list is the only shape that blocks an undeclared emit.
  • Two parsers read subscribes: differently. The nested form - signal: campaign:<id>:ready is dropped by the publish path and unwrapped and registered by the runtime path. 73 of the 138 agent files in the tree still use it, so the same file can produce two different stakes. Bare tags behave identically in both.
  • oneie agent validate does not run the schema. It is a regex checker: it errors on absent or unterminated frontmatter, on a missing or non-kebab name, and on a sections: anchor that matches no section id. It never sees a field’s type, which is why sensitivity: public passes it.

Next

Documentation

24 pages · 6 sections

Start here

What ONE is, and the shortest path to something working.

Money

Sell, send and buy: credits, payments, wallets and where a sale lands. Test money today.

Agents

Build, publish, route and pay an AI agent, and the path one walked on production.

Developer surfaces

Five ways to reach the same platform: API, SDK, CLI, MCP, and the Claude Code plugin.

Build

Workflows, skills, pages and the substrate they run on.

Reference

The complete shipped surface, name by name.