THE INCIDENT · CHAPTER 04
The model requests a shell command. Mira realizes the request itself cannot execute anything. Somewhere, code must describe the command to the model, parse its arguments, decide whether it is allowed, run it in a specific place, and return an honest result.
The question: How does a text prediction become a file read, edit, search, or process?
Start from first principles
A tool schema is a restaurant menu, not a kitchen. It tells a diner what can be ordered. The implementation is the kitchen, permissions are the waiter checking the order, and the tool result is the plate that actually returns.
Tool discussions often stop at a list: read, edit, bash, search. A production harness needs more than names. It needs argument contracts, output limits, timeouts, concurrency rules, permission semantics, lifecycle hooks, environmental dependencies, and errors the model can repair from.
Grok Build makes the two-sided contract explicit. ToolDefinition belongs to the model-facing side. Registry/runtime types and the workspace belong to the execution side. The shell is the policy bridge between them.
The third-party notice is equally precise: specific implementations under Codex- and OpenCode-named directories are adapted. That provenance does not justify saying the entire Grok Build runtime was copied from either system.
Build the smallest useful mental model
Represent a tool call as a proposed capability use, not a command that is already happening. The proposal passes five stages: exposure, parsing, policy, execution, and observation.
A failure at each stage means something different. Unknown tool is exposure/resolution. Invalid JSON is parsing. Denied is policy. Nonzero exit is execution. Truncated or lost output is observation. The next model round needs the distinction.
The effective toolset is a security and context boundary. Removing a tool with --disallowed-tools prevents selection; a permission deny leaves the tool visible but rejects a particular invocation. Those produce different agent behavior.
Fig 4.1 — A tool call is admitted through contracts before it can cause a side effect.
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 — Define the model-facing function
Mira now needs one small mechanism: Every visible tool needs a stable name, useful description, and JSON parameter schema.
She follows that responsibility into the repository. ToolDefinition is a function definition with name, optional description, and parameters. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: A schema can validate syntactically while allowing a dangerous semantic value, so policy must inspect normalized arguments. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:xai-grok-tools/src/types/definition.rs. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
2. The next clue — Finalize per-session implementations
Mira now needs one small mechanism: Definitions must resolve to implementations carrying the correct cwd, environment, terminal, filesystem, memory, and integration state.
She follows that responsibility into the repository. FinalizedToolset and SessionContext connect the registry to session dependencies. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: A stale context can execute in the wrong directory or retain outdated integration state. Bind and log session identity. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:xai-grok-tools/src/registry/types.rs. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
3. The next clue — Filter before model selection
Mira now needs one small mechanism: Agent definitions and headless flags can restrict which tool schemas enter a request.
She follows that responsibility into the repository. Headless supports --tools and --disallowed-tools, including restrictions on the Agent tool and named subagent types. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: Filtering the alias instead of the real tool name can leave a capability exposed; use inspect/help and source-pinned names. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source: User guide14-headless-mode.md, tool-filtering section. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
4. The next clue — Normalize calls before policy
Mira now needs one small mechanism: Arguments need parsing, alias resolution, and canonical tool identity before matchers or rules evaluate them.
She follows that responsibility into the repository. prepare_tool_call parses and normalizes the model call and resolves the bridge tool. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: Malformed arguments should become a model-visible error and must never fall through to a permissive default implementation. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:xai-grok-shell/src/session/acp_session_impl/tool_calls.rs::prepare_tool_call. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
5. The next clue — Apply deterministic preconditions
Mira now needs one small mechanism: Plan-mode edit restrictions and PreToolUse hooks run before the ordinary permission decision and implementation.
She follows that responsibility into the repository. The preparation path checks plan-mode edits, dispatches the pre-hook, and converts explicit denial into a not-executed result. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: Hook crashes/timeouts are documented fail-open; enforcement hooks must handle errors and emit explicit deny. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:tool_calls.rsand user guide10-hooks.md. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
6. The next clue — Ask the permission manager
Mira now needs one small mechanism: Rules, remembered grants, built-in approvals, and mode policy decide admission after pre-hook checks.
She follows that responsibility into the repository. The shell sends a request through PermissionHandle; the workspace permission manager implements mode and rule evaluation. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: bypassPermissions removes most prompts but does not convert an unconfined environment into a safe one. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:xai-grok-workspace/src/permission/manager.rs. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
7. The next clue — Dispatch locally or by proxy
Mira now needs one small mechanism: Authorized calls should use the same high-level tool contract regardless of execution placement.
She follows that responsibility into the repository. dispatch_tool delegates to WorkspaceOps::call_tool, whose local branch calls the session toolset and proxy branch routes to the hub. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: Proxy errors must retain enough classification to distinguish transport failure from tool failure; otherwise the model may retry a side effect blindly. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:tool_dispatch.rsandxai-grok-workspace/src/workspace_ops.rs. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
8. The next clue — Control concurrency and output
Mira now needs one small mechanism: Parallel operations need call identity, path locking where appropriate, bounded output, and background lifecycle APIs.
She follows that responsibility into the repository. The dispatch layer derives same-file lock paths; long-running commands and subagents use get/wait/kill operations, and MCP output has documented inline caps with spill files. The important point is not the Rust syntax. It is ownership: this is where the system decides what crosses the boundary.
Then she tests the unhappy path: Two edits to one file can race; unbounded logs can exhaust context; orphan background work can outlive the assumption that a turn is finished. If the model, operator, and saved session do not receive the same honest outcome, the mechanism is not yet trustworthy.
Source:tool_dispatch.rs::lock_path_for_args, background guide, MCP guide. Verified against Grok Buildc68e39f60462f28d9be5e683d9cbe2c57b1a5027.
Mira runs the experiment — read-only repository review
Reading source gives her a hypothesis. A small experiment tells her whether that hypothesis survives contact with a real workspace. Design a run that can inspect code and execute no mutation-capable tool.
- Create a disposable checkout with no ambient write credential.
- Expose only read, list, and grep/search tools.
- Remove shell if command execution is unnecessary.
- Add explicit deny rules for edit/write and risky MCP tools.
- Use a read-only or strict sandbox profile as a separate OS boundary.
- Request findings with file/symbol evidence.
- Capture structured output and the effective tool inventory.
- Verify the checkout hash and working tree remain unchanged.
before=$(git status --porcelain=v1) grok -p "Review this parser for correctness. Cite files and symbols; do not modify anything." \ --tools "read_file,grep,list_dir" \ --output-format json after=$(git status --porcelain=v1) test "$before" = "$after"
What she learns. The example uses documented filtering concepts. Exact effective names should be confirmed with the current binary because user-facing aliases can differ from internal names.
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 question | Source-backed answer | Operational consequence |
|---|---|---|
| Visible or denied? | Filtering removes schema; permission denial rejects an invocation. | Use filtering for least context/authority and rules for value-specific policy. |
| Who executes? | Finalized toolset through local/proxy workspace. | Record placement and session context. |
| What serializes? | Same-path calls can acquire a derived lock; other calls may run concurrently. | Do not infer global serial execution. |
| What is third-party? | The notice identifies specific adapted tool implementations. | Attribute files precisely, not the whole runtime. |
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
- Effective schema name/description hash and source integration.
- Raw and normalized arguments with secret redaction.
- Hook, rule, mode, remembered-grant, and final admission decision.
- Start/end time, exit classification, truncation/spill location, changed paths, and post-hook result.
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
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
Why not expose every installed tool?
Every schema spends context and every capability expands the model's action surface. Expose the smallest set needed for the task.
Is denying a command the same as removing bash?
No. Removal prevents the model from selecting bash; a rule can allow safe invocations and deny or ask for others.
How does the model recover from a failed command?
The structured result is appended to chat state, so the next round can inspect stderr/exit status and choose another action.
Can tools execute in parallel?
Yes, with targeted serialization for inferred same-file operations. Shared environmental side effects still require careful workflow design.
Are MCP tools ordinary tools?
They are external integration tools with namespacing/discovery and their own transport/output concerns, routed through the broader authorization lifecycle.
What changed for Mira
Mira learns to inspect four things for every tool: its promise, authority, execution location, and result contract.
Next: Those tools still need a place to act, which makes the workspace more than a directory path.
Key takeaways
- A tool is a model schema plus an authorized implementation.
- Filtering, permission denial, and sandboxing are different controls.
- Session context determines where an implementation acts.
- Failures and denials must return as structured observations.
- Concurrency needs call identity, path-aware locks, bounded output, and cleanup.
References & source notes
- Pinned Grok Build repository — default branch snapshot researched July 16, 2026.
- Grok Build README — first-party overview and source-build entry points.
- Tool definitions — model-facing tool contract.
- Third-party notices — precise Codex and OpenCode attribution.
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.