ENS records as canonical state
AGENSAI stores no fleet database. Your fleet, main subname → orchestrator → agents, lives entirely in JustaName CCIP-Read text records on ENS.
This is what makes recovery work without an AGENSAI server. Walking the chain main → orchestrator → children → metadata is a sequence of standard ENS lookups, queryable from any ENS-aware tool.
The three-tier record hierarchy
adrian-main.agensai.eth ← user's main subname
├── active_orchestrator "adrian-orc.agensai.eth"
└── archived_orchestrators ["adrian-orc-2025-q3.agensai.eth", ...]
adrian-orc.agensai.eth ← orchestrator's subname
├── owner "adrian-main.agensai.eth"
├── children ["dca-bot.agensai.eth", "alice.agensai.eth", ...]
├── created_at "2026-05-10T14:32:00Z"
└── status "active"
dca-bot.agensai.eth ← each agent's subname
├── description "DCA bot for ETH on Base"
├── policy {serialized scope: calls, spends, expiry}
├── parent "adrian-orc.agensai.eth"
├── owner "adrian-main.agensai.eth"
├── created_at "2026-05-10T14:35:00Z"
└── status "active" | "revoked" | "archived"ENS resolution returns the chain-appropriate address for each subname; AGENSAI's lib selects the right resolver slot transparently. You don't usually need to think about which slot holds what, call resolve(ens, chainId) and you get the address that should be used on that chain.
Why ENS records and not a database
Three reasons.
Recovery is a chain-walk. Lose your device. Sign in to the dashboard from a new device with your passkey. The dashboard reads active_orchestrator from your main subname, then reads the orchestrator's children, then reads each child's policy and description. Renders the "Previous fleet" view. One biometric tap kicks off rehydration. No AGENSAI database required.
Sovereignty. Your fleet identity is yours. It's standard ENS. Any ENS-aware tool can read it. AGENSAI's dashboard is one renderer; your own tooling can be another.
Forkable in a weekend. A fork of AGENSAI that runs on a different namespace doesn't need to copy a database. It mints subnames under a new namespace, writes the same records, and the chain-walk logic in apps/cli/src/lib/fleet/ works unchanged.
What writes which records
| Record tier | Signer | Biometric? |
|---|---|---|
Main subname (active_orchestrator, archived_orchestrators) | Main account via SIWE | Yes, but only at orchestrator setup or rotation |
Orchestrator subname (children, status) | Orchestrator's local key via SIWE | No |
Each agent's subname (description, policy, status) | Orchestrator's (or agent's) local key via SIWE | No |
The biometric line is only at events that touch your main subname: orchestrator creation, orchestrator rotation, fleet rehydration. Day-to-day record writes, agent creation, status updates, policy changes, happen on subnames owned by local keys, no biometric.
How AGENSAI writes them
The lib exposes fleet manifest helpers for both reads and writes:
// Reads, no signing, public resolution.
const fleet = await walkFleet("adrian-main.agensai.eth");
// {
// main: { ens, activeOrchestrator, archivedOrchestrators },
// orchestrator: { ens, address, children, createdAt, status },
// agents: [ { ens, description, policy, parent, status }, ... ],
// }
// Writes, orchestrator's local key signs SIWE; main writes use the passkey.
await writeOrchestratorRecords(env, {
orchEns: "adrian-orc.agensai.eth",
children: ["dca-bot.agensai.eth", "alice.agensai.eth"],
});Reads are free; they're standard ENS resolution against the JustaName CCIP-Read gateway. Writes go through JustaName's subnames.updateSubname with a SIWE message signed by the appropriate signer for that tier.
Today (v0): the orchestrator's
childrentext record is set at mint time and not updated as agents are spawned. Fleet discovery uses an onchaingrantPermissionsevent scan against the orchestrator's smart account (~1-2s slower on first load). The chain remains the source of truth either way.children[]becomes the fast path again in v0.1.
Implications
Your dashboard is a renderer. It doesn't own your fleet. Sign out of the dashboard, your fleet still exists. Sign into a different dashboard built on the same namespace, you see the same fleet.
Recovery doesn't need our infrastructure. As long as ENS resolution works (which is approximately as long as Ethereum + JustaName's gateway are up), your fleet identity is recoverable.
ENS is the source of truth, on-chain permissions are the source of authority. Records describe what your fleet is. The ERC-7715 grants on-chain define what each agent can do. Both are independent of any AGENSAI server.
Further reading
- Recovery, how the chain-walk powers fleet rehydration on a new device.
- JustaName ENS-identity rules, SIWE message construction, subname updates.
apps/cli/src/lib/fleet/manifest.ts, the actual reader/writer.