Jul 16, 2026 · ml · 10 min read · 1960 words advanced

ACP and Grok Build as an Embeddable Agent Runtime.

mlagentsgrok-buildharness-engineering

THE INCIDENT · CHAPTER 12

An editor team wants Grok Build inside its own interface. Reimplementing the agent loop would fork behavior and safety policy. They need a protocol that lets the editor remain the client while Grok Build remains the runtime.

The question: How can another application drive an agent without becoming that agent?

Start from first principles

ACP is like a standardized cockpit connection. The client owns buttons and displays; the runtime owns the engine and flight logic; messages define what can cross between them.

An agent becomes infrastructure when editors, CI, and custom applications can drive it without scraping terminal output.

The Agent Client Protocol supplies that boundary. The shell hosts sessions; clients initialize, authenticate, create/load, prompt, render, and answer permissions.

Embedding transfers authority to the client. A caller choosing cwd, plugins, metadata, and approvals belongs in the trusted computing base.

In one sentence. ACP separates agent semantics from one UI. Grok Build can run persistent JSON-RPC over stdio, expose server/relay modes, create or load sessions, stream structured updates, and request permission through clients. Its own headless mode is a concrete ACP consumer.
1 · NEEDHow can another application drive an agent without becoming that agent?
2 · MECHANISMThe harness must own a clear protocol-integration boundary.
3 · PROOFObserve the model, harness, environment, and verifier separately.
The equation for the whole series. Coding-agent effectiveness = model capability × harness quality × environment quality × verification quality. If any factor approaches zero, the product approaches zero too. This chapter isolates protocol-integration, then reconnects it to the complete system.

Build the smallest useful mental model

ACP is a control-plane protocol around the turn loop. It carries lifecycle and notifications; it does not itself execute tools.

Keep base methods separate from x.ai/ extensions. Portable clients feature-detect extras.

Stdio, server, and relay change connectivity and auth exposure but should preserve session semantics.

Editor/CI ACP client Transport stdio / server / relay Shell sessions + turns Tools policy + calls Workspace environment permission prompts cross the client boundary feedback changes the next turn

Fig 12.1 — ACP decouples clients from the shared shell, tool, and workspace runtime.

Now open the hood

Only after the idea is clear does Mira open the source. She ignores most of the workspace and follows the few boundaries that must exist for this part of the story to work.

1. The next clue — Run persistent stdio

Mira now needs one small mechanism: Exchange JSON-RPC over stdin/stdout across turns.

She follows that responsibility into the repository. The guide documents grok agent stdio as primary integration. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Clients receive structured sessions without embedding Rust.

Then she tests the unhappy path: Stray stdout logging corrupts framing; use stderr. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: User guide 15-agent-mode.md. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

2. The next clue — Negotiate capabilities

Mira now needs one small mechanism: Initialize version/features before session work.

She follows that responsibility into the repository. The client example sends initialize data and lists SDKs. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Negotiation prevents unsupported assumptions.

Then she tests the unhappy path: Ignoring response yields malformed calls or missing UI behavior. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: ACP basics/example. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

3. The next clue — Authenticate before prompt

Mira now needs one small mechanism: Complete supported auth lifecycle outside model reasoning.

She follows that responsibility into the repository. The headless client sends initialize/auth before session materialization. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Auth is reusable across clients and not prompt content.

Then she tests the unhappy path: Do not leak long-lived secrets to prompt/tool environments. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: headless.rs::run_single_turn. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

4. The next clue — Create or load explicit sessions

Mira now needs one small mechanism: Choose validated cwd and lifecycle around a concrete ID.

She follows that responsibility into the repository. ACP session/new/load flows and metadata configure session behavior. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Continuity is a protocol choice, not process accident.

Then she tests the unhappy path: Prevent cross-tenant session IDs and path traversal. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: Agent-mode guide and ACP implementation. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

5. The next clue — Stream typed updates

Mira now needs one small mechanism: Text, thought, tool, plan, permission, and terminal events remain structured.

She follows that responsibility into the repository. The guide lists session/update variants and notifications. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Clients render and persist without terminal parsing.

Then she tests the unhappy path: Tolerate unknown variants and preserve ordering/correlation. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: Agent-mode streaming section. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

6. The next clue — Route permission through client

Mira now needs one small mechanism: Interactive clients display/answer requests while hard policy remains server-side.

She follows that responsibility into the repository. ACP carries permission interaction and the shell uses shared permission manager. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Approval UX belongs to the active client.

Then she tests the unhappy path: A malicious client can auto-approve; rules and sandbox enforce hard limits. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: ACP session and permissions code. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

7. The next clue — Feature-detect x.ai extensions

Mira now needs one small mechanism: Vendor methods remain namespaced and optional.

She follows that responsibility into the repository. The guide lists methods/notifications under x.ai/. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. Base interoperability survives alongside richer features.

Then she tests the unhappy path: Hard dependency makes a client Grok-specific and should be declared. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: Agent-mode extensions section. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

8. The next clue — Study headless as reference client

Mira now needs one small mechanism: A real in-repo client should exercise lifecycle and projection.

She follows that responsibility into the repository. headless.rs starts the shell in-process and drives ACP to completion. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.

Why the story changes here. It demonstrates task tracking, cancellation, and result construction.

Then she tests the unhappy path: External clients must not assume internal in-process shortcuts. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.

Source: xai-grok-pager/src/headless.rs. Verified against Grok Build c68e39f60462f28d9be5e683d9cbe2c57b1a5027.

Mira runs the experiment — minimal read-only review client

Reading source gives her a hypothesis. A small experiment tells her whether that hypothesis survives contact with a real workspace. Open Grok over stdio, create a repository session, stream findings, and refuse mutation permissions.

  1. Spawn stdio with stderr separate.
  2. Initialize and inspect capabilities.
  3. Authenticate.
  4. Create session for validated path.
  5. Send correlated review prompt.
  6. Render/log typed updates.
  7. Deny mutation permissions.
  8. Wait for terminal event and clean up.
// Pseudocode; verify current ACP SDK types.
const proc = spawn("grok", ["agent", "stdio"]);
await client.initialize({ protocolVersion: 1 });
const session = await client.newSession({ cwd: checkedPath });
await client.prompt(session.id, [{ type: "text", text: reviewPrompt }]);

What she learns. Illustrative pseudocode based on the guide, not a copy-paste SDK program.

The proof she demands. Test framing, negotiation, unknown updates, denial, cancellation, cleanup, and correlation.

That last check matters. Grok Build can expose a mechanism and report an observation; the repository, operating system, CI platform, and reviewer decide whether those observations prove the actual task succeeded.

The whiteboard test

Before Mira explains the chapter to her team, she reduces it to three questions: what owns the decision, what evidence comes back, and what changes when the mechanism fails?

Review questionSource-backed answerOperational consequence
Portable?Base ACP lifecycle.Feature-detect.
Grok-specific?x.ai methods.Declare dependency.
Who owns UI?Client.Render state accurately.
Who owns effects?Shell/tools/workspace.Transport is not sandbox.

This is not a feature scorecard. A mechanism can work exactly as implemented and still be the wrong control for a particular threat. Defaults also change, so recheck the pinned source path before copying configuration into production.

Signals Mira keeps

  • Versions, negotiated capabilities, connection identity.
  • Session/cwd identity, metadata, auth method without secrets.
  • Request/call/update correlation, ordering, cancellation.
  • Permission answer, stop reason, cleanup and orphan state.

Together, those signals tell a complete story: the model proposed an action, the harness admitted and routed it, the environment performed something, and a verifier measured the result.

Limits and uncertainty

Relay. Public code does not establish hosted relay production topology.
Client trust. Clients can choose paths, plugins, and approvals; authenticate them.
Drift. Pin SDK/protocol versions and negotiate capabilities.

The public repository is unusually detailed, but it is not the complete deployed product. The snapshot has one visible public commit, so it cannot support a rich historical explanation of why every boundary evolved. Hosted xAI model serving, account systems, and production topology remain outside this study. Where code and guide differ, this series gives the pinned implementation priority and marks documentation-only behavior instead of silently merging versions.

FAQ

ACP versus MCP?

ACP connects client to agent; MCP connects agent to tool servers.

Why not headless JSON?

Headless suits one-shot automation; ACP suits persistent interactive clients.

Can client enforce read-only?

It can deny, but hard policy also belongs in rules/tools/sandbox.

Can stdio hold sessions?

Use documented persistent process and session lifecycle.

Can I use base ACP only?

Yes for supported base capabilities; extras require x.ai extensions.

What changed for Mira

Mira sees ACP as a boundary between presentation and agent semantics, not merely another transport flag.

Next: With the architecture understood, she can finally compare Grok Build with Pi Agent and Hermes fairly.

Key takeaways

  • ACP separates UI and runtime.
  • Transports wrap shared session semantics.
  • Headless is an in-repo ACP client.
  • Hard policy must not trust client approval alone.
  • Negotiate versions and isolate extensions.

References & source notes

Freshness boundary. Grok Build claims in this article are pinned to c68e39f60462f28d9be5e683d9cbe2c57b1a5027. Pi comparison claims, where present, are pinned to 97f9978fa66685f78d2da19ae22e20c46d125f74; Hermes claims are pinned to c9c9bb33fcc6ab479846a1c496a6e9efe2c1c7d4. Recheck paths, symbols, commands, and defaults if those branches advance.

← Article 11 — Headless CIArticle 13 — Comparison →
© cvam — written in plaintext, served warm