OS-011 &body.browser reference implementation for the [&] Protocol ecosystem.
Provides the authoritative substrate for browser embodiment: typed perception, affordance enumeration, StateHash-anchored replay, and InteractionTrace recording — the missing half of Graphonomous's &memory.episodic.store/replay loop.
Library: production-ready
Simulator backend: 12/12 OS-011 §9 conformance tests pass
MCP server: shipped — 7 tools on the body-browser namespace (ensure_session + 6 OS-011 operations), 12 MCP unit tests
AgentBrowser backend (real Chromium): skeleton — subprocess wiring documented, pending
body_browser_ensure_session — create or re-bind a session by id
body_browser_perceive — typed observation (EnvironmentObservation)
body_browser_affordances — policy-filtered AffordanceSet
body_browser_encode_state — deterministic StateHash
body_browser_act — execute one TypedAction
body_browser_dry_run — predicted outcome (no mutation)
body_browser_replay — fail-fast replay of an InteractionTrace
Every tool takes a session_id so multiple agents can drive independent browser sessions concurrently from the same server process. Sessions are supervised under BodyBrowser.SessionSupervisor and addressed through the BodyBrowser.SessionRegistry.
A conforming &body.browser provider exposes six operations:
| operation | input | output | deterministic |
|---|---|---|---|
perceive | PerceptionQuery | EnvironmentObservation | ✅ |
affordances | ScopeQuery? | AffordanceSet | ✅ |
encode_state | PerceptionQuery | StateHash | ✅ |
act | TypedAction | ActionOutcome | ❌ side-effecting |
replay | InteractionTrace | ReplayResult | ❌ side-effecting |
dry_run | TypedAction | PredictedOutcome | ✅ |
BodyBrowser.Session)| # | invariant | where enforced |
|---|---|---|
| I1 | perceive-before-act (stale refs rejected) | Session.check_ref_freshness/2 |
| I2 | affordance-bounded action | Session.check_affordance/4 |
| I3 | policy-filtered affordances | Session.apply_policy/2 |
| I4 | deterministic state encoding | BodyBrowser.StateHash.of/1 |
| I5 | replay fail-fast | BodyBrowser.Replay.execute/3 |
alias BodyBrowser.Backend.Simulator
alias BodyBrowser.Backend.Simulator.{Element, Page}
alias BodyBrowser.Session
pages = %{
"https://example.test/login" => %Page{
url: "https://example.test/login",
elements: [
%Element{role: "textbox", name: "username", actions: ["fill"]},
%Element{role: "button", name: "Log in", actions: ["click"]}
]
}
}
{:ok, s} = Session.start_link(
backend: {Simulator, initial_url: "https://example.test/login", pages: pages},
agent_id: "demo",
provider: "body-browser-simulator"
)
{:ok, obs} = Session.perceive(s)
{:ok, aset} = Session.affordances(s)
{:ok, hash} = Session.encode_state(s)
{:ok, outcome} = Session.act(s, %{
"type" => "click",
"target" => Enum.at(obs.a11y_tree, 1).ref
})
trace = Session.trace(s) # ready for Graphonomous act(store_trace)
The recorded trace is compatible with the Graphonomous act(action: "store_trace", interaction_trace: ...) MCP tool (see graphonomous/lib/graphonomous/mcp/store_trace.ex). Finalize via TraceRecorder.finalize/2 and pass the resulting map's JSON encoding as interaction_trace.
Replay the other direction: call Graphonomous retrieve(action: "replay", trace_id: "..."), decode the returned manifest, and pass it to BodyBrowser.Replay.execute/3.
mix deps.get
mix test
Twelve tests, 1:1 with OS-011 §9. Run against Simulator; an in-progress AgentBrowser backend is expected to pass the same suite once its CLI adapter lands.
opensentience.org/docs/spec/OS-011-EMBODIMENT.md — normative spec
AmpersandBoxDesign/contracts/v0.1.0/body.browser.contract.json — capability contract
AmpersandBoxDesign/docs/registry/body.browser.md — registry entry
PULSE/manifests/body-browser.embodiment.json — loop manifest
Apache-2.0