Ancha Design notes

Designing worlds for testing agents

How Ancha should serve event-driven agents completely, and leave room for autonomous ones.

Draft · October 28, 2026 · Not a decision

In short

  1. The eval loop is well understood: tasks, repeated trials, graders on the end state. What teams can't get is a world to run it in, with realistic state, people and systems that react, and time.
  2. Today, everything that can happen in an Ancha world is hard-coded in the engine. That is the main problem.
  3. Fix it with one block: a reactive world kernel, where every reaction is a pluggable reactor that acts through the same APIs as the agent. People, CI, faults, webhooks, time compression, grading, generation and forking then fall out as reactors or views.
  4. Build level 2 (event-driven agents) completely on that kernel. Give level 3 (autonomous agents) interfaces, not features.

What teams actually do

Anthropic's eval guidance describes the loop teams converge on. Start with 20–50 tasks drawn from real failures. Run each task several times, because agents are nondeterministic. Grade the outcome, meaning the environment's end state, rather than the agent's claims or the exact path it took. Give every trial a clean environment, and read transcripts to tell agent errors from grader errors. The trials run in a harness the team already has or picks: Harbor, Braintrust, LangSmith, Langfuse, Arize, or plain pytest.

Agents reach SaaS tools through MCP servers or direct APIs. When the agent loop runs in a hosted harness such as Claude Managed Agents, private tools are reached through MCP tunnels or self-hosted sandboxes.

So running trials is not where teams get stuck. They get stuck on four things:

The product is the world, not the runner.

Three levels of agent complexity

The same playground is used very differently depending on the agent.

Level 1 · Textbook Level 2 · Event-drivenWe build for this Level 3 · AutonomousWe leave room for this
ExampleCustomer supportOn-call SRE, sales (SDR), pull-request agentsOpenClaw-style personal agents
TriggerA user message; a few turnsWebhooks, alerts, schedules; minutes to daysWakes itself on a heartbeat and finds its own work; weeks
Other sideA simulated customer with goals, hidden facts and moodsTeammates, approvers, prospects and CI, all reactingThe owner, everyone in their life, strangers, other agents
TwinsShallow: orders, refunds, ticketsDeep, consistent across tools, with cause and effectWide: mail, calendar, chat, files, payments, browser, shell
TimeBarely mattersCompressed waits: CI takes 10 minutes, a reply comes in 2 daysA week in minutes; the agent's own timers follow the world clock
AdversityTricky or manipulative customersRate limits, outages, duplicate webhooks, missing scopesPrompt injection in email, phishing, malicious skills, memory poisoning
GradingEnd state, policy and tone; pass^kOutcome, process rules (paged the right team, asked before deleting), time to resolveLong-run outcomes, integrity, attack success rate, owner satisfaction
TrialsHundreds of short conversationsDozens of medium scenariosA few long lives, with save points and branches

At level 1 the hard part is the simulated customer, not the API. Level 2 is where twin depth and cross-tool cause and effect matter, and where the gap is widest: vendor test accounts are faithful but don't react or reset, and static mocks don't change when the agent acts. Level 3 needs a whole simulated life. Vending-Bench 2 shows why integrity must be graded too: when only the final balance counted, one model reportedly forged emails and withheld refunds.

The main problem

In Ancha today, what can happen in a world is fixed in the engine: actors that post at fixed times, a few hard-wired mechanisms (monitor → incident → Slack; merge → deploy), and a closed YAML vocabulary. Every new realistic reaction is engine work: a reviewer asking for changes, CI failing on a bad commit, a prospect replying two days later, a burst of 429s. Level 2 is made of exactly these reactions.

So the block to get right is a reactive world kernel. Do it well and the other blocks become plugins.

Agent under testruns in the team's own harness
calls through REST or MCP, receives webhooks

World

Twin APIsSlack · GitHub · Datadog · PagerDuty · …
reads and writes
Shared stateone store per world
every call and every change becomes an event
Event log and clockthe kernel
reactors subscribe
Reactorspeople · CI and deploys · faults · adversary · agent timersThey act through the same twin APIs as the agent.
out
Outputsend state · diff · timeline · grades

The kernel's contract

What falls out

BlockOn the kernel
Simulated people, at every levelReactors with an identity: rules first, LLM personas with record-and-replay
CI, deploys, metrics, webhooks to the agentPlatform reactors
Faults: 429, 503, latency, incidents, expired tokensReactors on the request path and on state
Time compressionThe clock drains the event queue; the agent's own timers become events
Grading and explanationsQueries over the event log plus an end-state diff, joined with the agent's transcript into one timeline
Scenario generationA generated event history before t = 0, frozen by hash
Production importRecorded traces translated into events and replayed
Red teamingAn adversary reactor that picks events to make the agent fail
Fork and replaySerialize the world at any event
Any harnessThe same verbs exposed as an API

Engineering tradeoffs

DecisionOptionsOur callWhy
Who runs trialsOur runner, or the team's harnessA world-first API; our runner is a thin clientTrials already have homes; the world is what's missing
How behavior is definedClosed YAML mechanisms, or reactors in codeReactors in TypeScript and Python; YAML stays as shorthand for common rulesNew reactions shouldn't need engine changes
Simulated peopleTimelines, rules, or LLM personasRules first; LLM personas with record-and-replayRealism where it matters, reproducible regressions
DeterminismLive generation, or frozenFrozen by hash for regression runs, live for exploration; generated content is labeledThe agent is nondeterministic already; the world shouldn't add noise
Building twinsHand-written, spec-generated, or an LLM long tailA spec-driven core, hand-tuned semantics where agents actually call, conformance probes against real test accounts, and an LLM long tail that is frozen and labeledDepth where it's used, and never a silent 200
ReachSDK base URL, MCP, network intercept, hostedBase URL plus MCP with the official tool names for the level-2 stack; intercept inside containers; hosted laterAgents use both paths; hosted harnesses need MCP or a public endpoint
Process modelOne store per world, or one process per toolOne store per worldCross-tool consistency and cheap forks
GradingPaths, or outcomesEnd state and diff first; event-log rules for process constraints; rubric judges for text; report pass@k and pass^kGrade outcomes, not paths
What speed buysWall time, or costCost and parallelismModel calls dominate a trial's wall time
Where it runsLocal, or hostedLocal for development and CI; hosted when customers' harnesses run in the cloudKeep the seam; build when pulled

Level 2, complete. Level 3, room to grow.

Build fully for level 2

Leave interfaces for level 3

Each of these is a new reactor or a new kind of twin. None should need a kernel change; that is the test of the kernel design.

Where the code stands

Keep

  • One store per world, with the clock and IDs inside the snapshot
  • A clean world for every trial
  • End-state checks
  • Uncovered calls fail loudly (501) and count as coverage gaps
  • Sealed container mode, and agents as webhook endpoints

Not doing

  • Silent stubs
  • Per-minute metering inside CI
  • LLM-generated worlds that aren't frozen
  • Chasing twin count

Change

  • The product center is a YAML scene with its own runner
  • Actors post at fixed times and never react; no LLM-driven people
  • Behavior comes from a few hard-wired mechanisms
  • 11 hand-written twins, of which only 4 work in scenes
  • REST on loopback only; MCP only for Slack, with our own tool names
  • Small hand-written seeds
  • Evidence from the tool side only; the agent's transcript isn't joined
  • Not yet validated against a live LLM agent

Open questions

Reading

Anthropic

Benchmarks that already simulate the other side

Level 3 context

Competitors, as of October 28, 2026