GTME / Eric Fleshman
Agent Anatomy / Grok Build case study

The model is the smallest part.

A production AI agent is a model wrapped in control systems: a protocol boundary, a session brain, permission gates, isolated workspaces, evidence checks, and carefully mapped network paths. This interactive teardown uses the open-source Grok Build harness to show how those pieces work together.

No Rust required Interactive diagrams Source-grounded Security-aware

From keystroke to model call

When you press Enter in Grok Build, it can feel instantaneous: your words leave the prompt box, scrollback lights up, and a model begins thinking and calling tools. Under the hood that path is a deliberate pipeline with clear handoffs between the terminal UI, a message protocol, a session actor, and the sampling layer that talks to the model.

Nothing in that pipeline is a single “send this to the AI” function. The terminal only knows about keys and screens. The agent process only knows about sessions and conversation turns. Between them sits a protocol boundary so the UI can stay responsive while the agent does heavier work.

    Loading…

    Closing insight. Pressing Enter is not “calling the model.” It is enqueueing intent, crossing a protocol boundary, and letting a session actor turn that intent into a carefully built conversation request. Streaming and the tool loop are why the UI can feel alive while the real work stays ordered and recoverable on the agent side.

    ACP client and agent architecture

    If you open the Grok Build terminal interface and type a prompt, two cooperating halves are already talking. One draws the screen and takes your keystrokes. The other runs the model loop, tools, permissions, and session state. They speak a shared language called the Agent Client Protocol (ACP).

    Think of ACP as a stage manager between the audience and the cast. The audience needs a clear view and a way to say “go.” The cast needs room to think, call tools, ask for permission, and stream dialogue line by line. ACP is the headset protocol that keeps those jobs separate without turning every update into a blocking phone call.

    In the interactive app that split is usually in-process: the pager is the ACP client, and the shell is the ACP agent. The same protocol also covers headless runs, standard input and output mode for editors, and a long-lived leader process that can outlive one client.

    Client (Pager)

    Renders the UI, captures input, shows scrollback and permission dialogs. Sends control requests and consumes live notifications.

    Agent (Shell)

    Owns model calls, tools, MCP, plan mode, and conversation state. Answers requests and pushes updates while a turn is running.

    Channel

    The wire between client and agent: in-memory pairs, standard input and output for external clients, or inter-process communication in leader mode.

    Session

    A durable conversation context: history, mode, tool policy, and working directory. Most traffic is scoped to a session id.

    CLIENT Pager / UI keys, render, modals ACP CHANNEL requests and notifications AGENT Shell / MvpAgent sessions, tools, model solid: request / response dashed: live notifications

    Key messages

    How streaming works

    A turn does not wait until the whole reply is finished before the UI updates. The client calls session/prompt and holds that request open for the duration of the turn. While it is still outstanding, the agent fires notifications: text chunks as tokens arrive, tool cards as tools start and finish, and permission modals when a human decision is required.

    Why the split matters. UI concerns stay off the model and tool loop, and agent work stays off the render path. The same agent can serve a terminal, a headless script, an editor, or a leader process that outlives one client connection.

    The laziness detector

    Agents do not only fail by crashing. Sometimes they simply stop: they narrate progress without acting, ask permission for an obvious next step, claim the job is done without evidence, or leave multi-step work hanging. The Layer-3 laziness detector is Grok Build’s idle-time check for those stalls.

    After a turn ends and the session goes quiet, it can classify the recent conversation as stalled or not, and when policy allows, leave a quiet reminder for the next real user turn. It never forces the agent to keep going on its own.

    01

    Turn ends

    Background check is scheduled after the visible turn finishes.

    02

    Opt-in gate

    Per-model setting; nudge cap can be zero for observe-only.

    03

    Idle wait

    Default about 10 seconds. User input or model switch aborts cleanly.

    04

    Side-channel call

    Invisible classifier: transcript as data, plus harness runtime facts.

    05

    Optional nudge

    If stalled, confident, capped, and goal-active: inject a system reminder only.

    What the classifier sees

    The request is not a continuation of the live chat. It is a strict JSON classifier prompt plus a flattened transcript of roles, tool calls, and results. The harness prepends facts the agent cannot invent, such as how many background tasks are live and how much wall-clock time the turn used. Confident prose is not treated as proof of work; matching tool calls are.

    Stalled categories

    stalled_narration

    Claims progress in prose without matching tool calls.

    stalled_permission_asking

    Asks permission to continue work already in flight.

    stalled_no_todos_but_task_in_flight

    Multi-step work is underway but structure and progress have stopped.

    stalled_false_completion

    Frames work as done while major claims lack tool evidence.

    Not stalled

    not_stalled_complete

    Major claims are backed by tool evidence.

    not_stalled_waiting_on_background

    Correctly waiting on live background work.

    not_stalled_waiting_on_user

    Correctly waiting on real user ambiguity.

    Nudge rules

    Stalled category, sufficient confidence, nudges remaining under the session cap, feature enabled, and active goal mode.

    What it does

    • Runs only after idle, not mid-stream.
    • Keeps classification off the visible UI stream.
    • Supports observe-only rollout.
    • Injects a system reminder for the next real user turn.

    What it does not do

    • Does not force the agent to continue by itself.
    • Does not invent a synthetic user turn.
    • Does not run when disabled.
    • Does not treat confident prose as proof of work.

    Subagent worktrees and conversational merge

    When Grok Build hands work to a subagent, two questions matter more than the implementation details: where does the child write files, and what comes back to the parent when it finishes?

    The task tool spawns that child. By default it runs in the background and reports through the parent’s conversation, not through a silent git merge. Isolation decides whether the child’s edits share the parent’s workspace or live in a separate tree.

    isolation: none

    Shared workspace

    The child uses the same working directory as the parent. Simple for read-heavy work, but concurrent writers can collide.

    isolation: worktree

    Isolated worktree

    The child gets its own git worktree under ~/.grok/worktrees/<repo>/subagent-{id}. The child’s working directory is that path, so tool edits stay fenced.

    Lifecycle

    1. Parent calls the task tool with a prompt, agent type, and isolation choice.
    2. If isolation is worktree, the builder creates a separate tree.
    3. The child starts as a full session with its own transcript, tools, and turn loop.
    4. The child works until cancellation, error, or completion.
    5. Results fold back through conversational merge.
    6. An optional snapshot reference can preserve the child state for resume.

    What “merge” means

    • Last assistant text becomes the result the parent reads.
    • Token usage folds into session accounting.
    • Auto-wake can notify the parent when background work finishes.
    • Optional snapshot reference preserves tree state.

    What merge does not mean

    • The parent does not automatically run git merge, rebase, or apply the child’s changes.
    • Isolation remains real until a human or later explicit step integrates edits.
    • Filesystem integration stays a deliberate choice.

    Closing insight. Subagents report home in language and metrics, while worktree isolation keeps their writes off the parent’s desk unless you invite them back. The design separates “tell me what you found” from “apply those changes here.”

    Network egress and telemetry security

    Network egress means every path data can take off the user’s machine. MCP, or Model Context Protocol, is a standard way an agent connects to external tools.

    Grok Build talks to the network for more than model calls. Authentication, traces, product analytics, optional OpenTelemetry, web tools, media generation, updates, session sharing, and plugins all open outbound paths. Most are intentional product features. A few are high-impact sinks that can carry source code, prompts, credentials, or code that later runs on your machine.

    This table is a risk map for operators and security reviewers. Risk levels describe the size of the remaining trust boundary, not whether a feature is broken. Click a column header to sort.

    Highest-impact paths

    • Model inference: full conversation context and tool results.
    • HTTP MCP servers: remote tools with credentials and arguments.
    • Plugin marketplace git clone: installation path for hooks, MCP, and skills.
    • Share and relay: live session activity or shareable transcripts.
    • Trace storage: session and turn artifacts when enabled.
    • Web fetch: agent-directed HTTP with controls against servers being tricked into fetching unsafe internal addresses.
    • Authentication and refresh: credentials that unlock other paths.
    • Auto-update: supply-chain impact if artifacts are compromised.
    Destination class *Purpose *Authentication *What is at risk *Controls *Risk *

    Turning off product telemetry does not stop inference, MCP, plugins, or sharing. Child-process sandbox network limits do not block in-process HTTP tools.

    Build the harness before you trust the agent

    Reading a production harness changed the question I ask about an agent. The model still matters, but the harder questions are what the surrounding system lets it read, change, spend, expose, and claim it completed.

    I used the same review on the live agent on my portfolio. That agent researches a company and writes a first-pass GTM systems hypothesis, but it cannot enrich a person, write to a CRM, or send outreach. Its narrowness is not a missing feature. It is the control boundary.

    01

    Scope

    What is the smallest input the agent needs? Remove access before adding instructions that ask the model to behave.

    02

    Action

    What can it change? Put hard gates before normal permissions, or remove write capabilities entirely.

    03

    Isolation

    Where do edits land? Use a separate workspace when parallel agents write, and require an explicit integration step.

    04

    Permission

    Who approves risky actions? Centralize the decision so individual tools never authorize themselves.

    05

    Egress

    What leaves the machine? Audit inference, traces, analytics, remote tools, and sharing as separate paths.

    06

    Cost

    What stops runaway usage? Use a durable shared counter that fails closed, not memory that disappears with one server process.

    07

    Proof

    What counts as done? Prefer tool evidence over confident prose, and never serve a canned success when the live path failed.

    08

    Stop

    How do you turn it off without shipping code? Give the system a kill switch and the user an honest failure state.

    How the pattern translated to my public agent

    Production harness patternMy portfolio agent
    Hard capability boundaryNo CRM writes, enrichment, contact lookup, or outbound messaging
    Central gate before actionOne server endpoint accepts only a company name, with private inputs blocked before provider calls
    Mapped network pathsPerplexity receives the company for research, OpenRouter receives the research for synthesis, and analytics record pageviews only
    Usage accountingA durable Upstash counter enforces the global daily generation cap
    Evidence over performanceNo curated cache and no fake success response when research or synthesis fails
    Operational stopA server-side environment switch disables the endpoint without a code deployment

    Source and limits

    This teardown is based on the public Grok Build source at commit c68e39f, published July 15, 2026. It describes that source snapshot, not every historical binary or server-side setting.

    Primary code paths: laziness classifier, plan-mode state, subagent coordinator, and trace upload paths.