Subject: grok-build (
xai-org/grok-build), official released CLI namegrokBased on commit: main branch (the SOURCE_REV file records the source commit SHA synced from xAI’s internal monorepo) Analysis date: 2026-07-24 Size: Rust monorepo, 60+ crates; core crates include xai-grok-shell (main entry), xai-grok-agent, xai-grok-tools, xai-grok-workspace, xai-grok-pager (TUI), etc. Audience: a computer-science beginner. This lecture uses many analogies and gives real source locations (file:line/crate/module) so you can follow the map. Note: this repo is a periodic sync of xAI’s internal monorepo and does not accept external contributions (seeCONTRIBUTING.md).
🗺️ Companion architecture diagram: this project has a dedicated figure in the seven-agent architecture gallery—Goal Mode’s four-phase state machine (including failure-recovery paths). Every gallery figure first states “what question it answers” and “the load-bearing claim,” then goes through three review and render-acceptance rounds.
Chapter 1 · Project overview
What is grok-build? The official README says: " a terminal-based AI coding agent that runs as a full-screen TUI that understands your codebase, edits files, executes shell commands, searches the web, and manages long-running tasks". After install the command is grok; the binary’s own name is xai-grok-pager.
Who builds it? xAI (the AI company Elon Musk founded, parent of the Grok model family). The repo is periodically synced from xAI’s internal monorepo (root SOURCE_REV tracks each sync’s internal commit SHA). 22.2k stars, 4.2k forks, Apache 2.0 (third-party original licenses in THIRD-PARTY-NOTICES).
Positioning and selling points:
- xAI’s official CLI: deeply bound to Grok models (also supports OIDC/external auth attaching other endpoints); the officially recommended way to “write code collaborating with Grok models”;
- Rust single binary: the whole agent compiles to one native binary (DotSlash for toolchain version lock); starts extremely fast; no Node/Python runtime;
- Goal Mode: grok’s most distinctive feature—a multi-phase autonomous-execution frame: you give a goal, grok plans, executes, verifies on its own; if stuck a “strategist” helps it recover; it only stops when done;
- ACP (Agent Client Protocol): a standardized editor-embedding protocol, already integrated with Zed; TUI / headless / IDE connect through the same protocol;
- Enterprise-grade extension: OIDC auth, corporate proxy, telemetry config, Marketplace plugins, MCP server management.
Stack: Rust (Tokio async runtime), Ratatui (TUI rendering library), tree-sitter (bash command syntax-tree parsing), gix (Git operations), JSONL (session persistence). Build tools: Cargo, toolchain version locked in rust-toolchain.toml, protoc for codegen, DotSlash for tool version management.
Vs Claude Code (one-sentence edition): both are “terminal agent loop + tool use + permission gating,” but Claude Code is bound to Anthropic/Claude; grok is bound to xAI/Grok, and is distinctive in three things: a Rust single binary, Goal Mode autonomous execution, ACP protocol open integration. And grok’s discovery path supports both .grok/agents/ and .claude/agents/—it deliberately compatible with some Claude Code user habits.
flowchart LR
subgraph 用户感知
A["grok
xAI 官方编程 agent"]
end
A --> B["Goal Mode
规划→执行→验证的多阶段自主循环"]
A --> C["Rust 单二进制
无运行时依赖,启动极快"]
A --> D["ACP 协议
TUI/无头/Zed 统一接口"]
A --> E["Grok 模型深绑
支持 OIDC/外部端点"]
F["Claude Code"] -.对比.-> A
F -.-> G["Anthropic 官方,TypeScript,绑 Claude 模型"]
Chapter 2 · Panorama
If grok is a company: the TUI (xai-grok-pager) is front-desk reception, session actor (xai-grok-shell/src/session) is the project teams, WorkflowManager is the project-management middle office, Agent (xai-grok-agent) is each employee’s job description + toolbox, ToolBridge (xai-grok-tools) is the unified shelf of all tools, the permission system (xai-grok-workspace/src/permission) is corporate compliance, the Grok model API is the “decision brain” outsourced to xAI.
Key crate map (all under crates/codegen/):
| crate | Duty | Analogy |
|---|---|---|
xai-grok-shell |
main entry: CLI parse, session management, extension system | company main building |
xai-grok-pager |
TUI rendering (Ratatui), including bin/pager/render/pty-harness | front lobby |
xai-grok-agent |
Agent definition parse, builder, discovery, prompt rendering | job descriptions |
xai-grok-tools |
all tool implementations (~25) + ToolBridge registry | tool shelf |
xai-grok-workspace |
filesystem ops, VCS, permission system, worktree | compliance + file room |
xai-acp-lib |
Agent Client Protocol (ACP), editor integration | outward interface protocol |
xai-grok-mcp |
MCP (Model Context Protocol) client | third-party tool socket |
xai-grok-auth |
auth middleware (credential provider + retry) | access-control system |
xai-grok-config / xai-grok-config-types |
config read/write (~/.grok/config.toml) | company regulations |
xai-chat-state |
session message state management | meeting minutes |
xai-codebase-graph |
codebase index and code navigation | library index |
xai-gix-status / xai-fast-worktree |
Git status and worktree ops | version control |
ptyctl / ptyctl-cli |
PTY control (pseudo-terminal) | terminal device |
xai-grok-markdown / xai-grok-mermaid |
Markdown/Mermaid rendering | typesetting room |
Overall data flow:
flowchart TB
subgraph 接入层
TUI["xai-grok-pager
全屏 TUI (Ratatui)"]
HEADLESS["grok -p
无头/CI 模式"]
ACP["ACP 客户端
Zed / 其他 IDE"]
end
subgraph 会话层 ["xai-grok-shell / session"]
SA["SessionActor
actor 任务,持有 ChatState + MCP"]
WFM["WorkflowManager
最多 4 路并发 workflow"]
GT["GoalTracker
规划→执行→验证 状态机"]
PM["PermissionManager
ask / auto / YOLO"]
end
subgraph Agent层 ["xai-grok-agent"]
AG["Agent
定义 + 系统提示词 + ToolBridge"]
CP["CompactionPolicy
85% 阈值 + 二阶段可选"]
end
subgraph 工具层 ["xai-grok-tools"]
TB["ToolBridge / 注册表
~25 内置工具"]
MCP["McpDispatcher
外部 MCP 服务器"]
end
subgraph 外部
LLM["Grok 模型 API
xAI / OIDC 端点"]
FS["文件系统 / Git"]
end
TUI --> SA
HEADLESS --> SA
ACP --> SA
SA --> WFM --> GT
SA --> AG --> TB
TB --> PM
TB --> MCP
AG --> CP
SA -->|采样请求| LLM
TB --> FS
Especially note: grok does not, like opencode, make “the TUI an independent client, the server an HTTP Worker”—grok’s TUI (xai-grok-pager) and the shell layer run in the same process, communicating via ACP; but its ACP layer is designed so that remote connection can be supported later.
Chapter 3 · Startup
What happens after you type grok in the terminal?
Step one: CLI entry. crates/codegen/xai-grok-pager/src/bin/ is the binary entry. Startup arguments support three major modes:
- Interactive TUI (default): full-screen terminal UI;
- Headless: grok -p "prompt" executes and exits;
- ACP mode: grok --acp exposes Agent Client Protocol for an IDE to connect.
Step two: workspace discovery. At start, discover and trust the current workspace (xai-grok-workspace/src/folder_trust.rs, trust.rs)—similar to Claude Code’s “workspace trust,” but grok’s implementation is more low-level: it uses xai-grok-workspace/src/discovery.rs to scan the project root (git repo root), load .grok/config.toml (project-level config) and ~/.grok/config.toml (user global config).
Step three: session actor init. xai-grok-shell/src/session/acp_session.rs creates a SessionActor—a Tokio task holding:
- ChatStateHandle: conversation history and token stats;
- PermissionManager (xai-grok-workspace/src/permission/manager.rs): permission arbitrator;
- McpState: the set of connected MCP servers;
- GoalTracker: Goal Mode state machine;
- State (TokioMutex protected): current active task queue + queued input.
Step four: Agent build. xai-grok-agent/src/builder.rs’s AgentBuilder.build() runs a 10-step flow (see Chapter 5): read AgentDefinition → discover skills → inject tools → filter allowlist/denylist → create ToolBridge → render the system prompt. The default Agent is general-purpose (loaded from discovery.rs’s built-in list).
Step five: MCP servers initialize in the background. All MCP servers declared in ~/.grok/config.toml initialize concurrently asynchronously (session/mcp_servers.rs). In the TUI you can see each server’s state change from Initializing → Ready (or NeedsAuth / Unavailable).
Step six: TUI render starts. xai-grok-pager initializes Ratatui’s full-screen alternate screen, first showing a welcome page (AppView); after the user sends the first message it switches to AgentView (Chapter 4).
sequenceDiagram
participant U as 用户 (终端)
participant CLI as xai-grok-pager/bin
participant WS as xai-grok-workspace
(工作区发现)
participant SA as SessionActor
participant AB as AgentBuilder
participant MCP as McpState (后台)
participant TUI as Ratatui TUI
U->>CLI: grok
CLI->>WS: 发现 git root, 加载 config.toml
WS->>SA: 初始化 SessionActor + PermissionManager
SA->>AB: build Agent (default: general-purpose)
AB-->>SA: Agent(ToolBridge + 系统提示词)
SA->>MCP: 后台并发初始化 MCP 服务器
SA->>TUI: AppView (欢迎页)
TUI-->>U: 全屏 TUI 就绪
MCP-->>SA: Ready / NeedsAuth / Unavailable
Chapter 4 · Input capture and routing
How does the TUI take input? xai-grok-pager’s PromptWidget is a feature-rich multiline text box (based on xai-ratatui-textarea), supporting: @ triggering file-search completion, / triggering slash-command completion, ! switching bash mode, Ctrl+P opening the command palette (command console), multiline toggle, paste images. Keybindings walk an Elm-style architecture: user key → Action → Effect → update AppState.
How is Enter routed? After SessionActor’s input queue (InputItem in State) receives a user message, it routes by these rules:
| Input type | Trigger | Destination |
|---|---|---|
| Shell mode | press ! to enter, then any command |
sent directly to BashTool to execute, not through the model |
| Slash command | starts with / + a registered command name |
command handler expands the template, turns into an ordinary prompt |
| Goal Mode trigger | /goal "goal description" or UpdateGoalTool |
enter the GoalTracker state machine (Chapter 6) |
| Ordinary prompt | other input | InputItem enqueued, SessionActor handles |
| Queue | send a message while the agent is busy | "send_now" priority FIFO queue |
Priority-queue design: State maintains two lines, “active tasks” and “queued input” (TokioMutex protected). The send_now flag lets some inputs (e.g. emergency interrupt or a synthetic turn) jump the queue to the head—this is grok’s “injectable turn” design, allowing the system to insert a message at a safe point of the agent loop.
flowchart TD
A["用户在 PromptWidget 输入并回车"] --> B{"输入类型?"}
B -->|"! 开头 (bash 模式)"| C["BashTool 直接执行
不经过模型"]
B -->|"/ 开头 + 已注册命令"| D["命令模板展开
转普通提示词"]
B -->|"/goal ... 或 UpdateGoalTool"| E["GoalTracker
进入自主目标循环"]
B -->|"其他"| F{"agent 忙?"}
F -->|闲| G["InputItem 进队
SessionActor 立即处理"]
F -->|忙| H["排到 send_now 队列
等循环安全点接管"]
C --> I["结果写入对话历史
模型后续可见"]
D --> G
E --> J["Planning → Executing → Verifying
多阶段自主循环"]
Chapter 5 · Context assembly
Before sending a request to the model, grok has to “assemble a complete work package.” This is done by the 10-step build flow of xai-grok-agent/src/builder.rs, re-executed at the start of each session or when switching Agent:
Agent definition file (AgentDefinition, xai-grok-agent/src/config.rs): a Markdown file; YAML frontmatter is config, the body is system-prompt content. Frontmatter supports an extremely rich set of fields (key fields excerpted):
name: "my-agent"
permissionMode: default # default / acceptEdits / auto / dontAsk / bypassPermissions / plan
tools: ["read_file", "grep"] # 工具白名单(空则全部启用)
disallowedTools: [] # 工具黑名单
skills: ["rust", "git"] # 注入的 skills 名单
discoverSkills: true # 是否自动发现 skills
agentsMd: true # 是否加载 AGENTS.md
effort: high # 推理档位
maxTurns: 20 # 最大 turn 数
model: "grok-4" # 覆盖默认模型
completionRequirement: # 完成要求(工具名 + 兜底 reminder)
tool: "update_goal"
reminder: "Call update_goal when done"
mcpServers: [...] # 本 agent 专属 MCP 服务器
memory: session # 记忆范围
10-step build flow (AgentBuilder.build()):
- Resolve definition: merge builder fields and AgentDefinition;
- Discover skills: load skill manuals from the filesystem or a preloaded snapshot;
- Inject skill prompts: prepend skill content into
prompt_body; - Initialize tool config: clone the definition’s tool config;
- Inject default tools: inject memory, web search, image generation, etc. by feature flags;
- Filter tools: remove disabled tools (memory/ask_user_question/workflow etc. can be closed by flag);
- Apply allowlists/denylists: execute
tools(allowlist) anddisallowedTools(denylist) filtering; - Parse task directives: extract sub-agent type constraints from
@agent(...)annotations; - Merge parameters: apply bash, ask_user_question parameter overrides;
- Finalize via ToolBridge: create the Agent, render the system prompt (
agent.finalize_prompt().await).
System-prompt rendering: xai-grok-agent/src/prompt/context.rs’s PromptContext.render() renders with the MiniJinja template engine (AgentDefinition’s prompt_mode decides template selection: extend = append to the base template, full = fully custom). Two prompt modes:
- extend (default): grok’s official base prompt + the user’s frontmatter body;
- full: the user fully controls; MiniJinja variable injection (can reference the tool list, current model name, date, etc.).
AGENTS.md / agents_md_files collection (xai-grok-agent/src/agent.rs’s agents_md_section()): reads .grok/AGENTS.md, .claude/AGENTS.md (compatible with Claude Code); discovering a new file mid-session also triggers agents_md_user_reminder().
System reminder mechanism (xai-grok-agent/src/system_reminder.rs): two independent reminder sets:
- TodoNudge: if todo_write has not been written for 3 rounds, remind; at least 5 rounds between two reminders (prevent screen-flooding);
- TodoGate: at turn end check whether there are unfinished todos (default off, must be explicitly enabled); at most 2 fires per prompt (DEFAULT_TODO_GATE_MAX_FIRES = 2, system_reminder.rs), preventing a billing explosion.
flowchart TB
subgraph AgentDefinition["AgentDefinition (Markdown + YAML frontmatter)"]
D1["permissionMode / tools / skills
model / effort / maxTurns"]
D2["prompt_mode: extend / full
MiniJinja 模板正文"]
end
subgraph Build["AgentBuilder.build() 10步"]
S1["1-2 Resolve + Skills 发现"]
S2["3 Inject skill prompts"]
S3["4-7 工具注入/过滤/白名单/黑名单"]
S4["8-9 task 指令 + 参数覆盖"]
S5["10 ToolBridge 创建 + finalize_prompt"]
end
subgraph Prompt["系统提示词 (MiniJinja 渲染)"]
P1["基础人格提示词
(extend = 官方模板)"]
P2["AGENTS.md / .claude/AGENTS.md"]
P3["skills 清单前置"]
P4["工具列表 / 日期 / 模型 / 工作区"]
end
D1 --> S1 --> S2 --> S3 --> S4 --> S5
D2 --> S5
S5 --> P1
S5 --> P2
S5 --> P3
S5 --> P4
P1 & P2 & P3 & P4 --> FINAL["最终系统提示词
Agent.system_prompt"]
Chapter 6 · The agent loop (the heart)
grok’s “heart” is two layers: the ordinary turn loop (similar to every agent’s standard pattern) and the distinctive Goal Mode loop.
6.1 Ordinary turn loop
The ordinary session’s agent loop is in xai-grok-shell/src/session/acp_session.rs (SessionActor’s turn handling):
- Take input from the InputItem queue (supports send_now priority ordering);
- Judge whether injectable: the "session is idle and safe to inject" assertion prevents inserting a synthetic message into an active turn;
- Prompt assembly: plate system prompt + history (
ChatStateHandle) + tool definitions (ToolBridge); - Sampler invocation: stream-request the Grok model API, handle events as the stream arrives;
- Tool-call dispatch: receive tool_call → ToolBridge looks up the implementation → walk permission gating (Chapter 7) → execute → append the result to history;
- Turn termination: model finish contains no tool_calls, and there are no pending tool results → break;
- Telemetry + persistence: token stats written to ChatState; conversation history written JSONL (
session/storage/).
Doom-loop defense (acp_session.rs): consecutive identical tool calls trigger a doom-loop recovery policy, similar to opencode’s DOOM_LOOP_THRESHOLD.
Rewindability tracking: at turn start mark “rewindable”; once the first outbound event exists, clear it—this lets the system distinguish “failed before producing side effects” from “already has side effects.”
6.2 Goal Mode loop (grok’s core difference)
This is grok’s most distinctive place. Goal Mode is a multi-phase autonomous-execution frame, driven by 5 core modules + 1 coordinator (GoalOrchestrator), plus independent Stall detection:
GoalTracker (goal_tracker.rs): a pure state machine (no async I/O), maintaining the goal’s full lifecycle:
- Phase (GoalPhase):
Idle → Planning → Executing - Status (GoalStatus):
Active / UserPaused / BackOffPaused / NoProgressPaused / InfraPaused / Blocked / BudgetLimited / Complete - Historical event log (at most 64 entries, with timestamps), token-budget tracking, per-goal scratch directory (with symlink-attack protection)
GoalPlanner (goal_planner.rs): a fail-closed planner. Receives a goal description, spawns a sub-agent, requires it to write the complete plan to plan.md (not casually talk in the conversation). Success conditions: the plan file exists + non-empty + the sub-agent’s final response is the literal "Done"; if any condition fails → FailClosed (the goal pauses), never allowing a broken plan to quietly continue. Two spawn paths:
- inherit path: reuse the current model/tool set, single attempt;
- override path: use the configured model/tool set; on a non-cancel error retry once (switching back to the default tool set);
- Cancel signals (user Ctrl+C) propagate as-is, do not trigger retry.
GoalStrategist (goal_strategist.rs): a fail-open strategist. Triggers after N consecutive verification failures (not a pause, but a “last effort”):
- Read workspace artifacts and trace files, analyze why it is stuck;
- Write remediation advice into a strategy note file (do not write back to plan.md!);
- PlanGuard RAII: snapshot plan.md bytes before spawn, restore after execution regardless of success or failure—prevent the strategist from accidentally polluting the planner’s contract file;
- Strategist failure → record telemetry, the main loop continues (fail-open; do not abort the goal because the strategist errored).
GoalStopDetector (goal_stop_detector.rs): an early-give-up detector. Scans the model turn’s last non-empty paragraph, matching 9 classes of “give-up signal” with ^-anchored regex:
| Class | Example patterns |
|---|---|
| Cannot continue | "I can't proceed", "I cannot continue" |
| Give up | "Giving up", "task is not actionable" |
| Stop here | "Stopping here", "Paused here" |
| Sub-agents in flight | "3 agents in flight", "Loop active" |
| Waiting for you | "I'll retry when X" (delay not instructed by the user) |
| Verdict line | "VERDICT: PASS/FAIL" |
| Submit/PR | "Pushed to", "Opened PR" |
| Ready for review | "Ready to merge", "Ready to ship" |
| Please-deflection | "Please provide", "Please configure" |
GoalOrchestrator (goal_orchestrator.rs): a notification sender, converting GoalTracker snapshots into ACP wire-format GoalUpdated events, distinguishing “persist” and “broadcast only” two sends (high-frequency live-token ticks only broadcast, not land JSONL, preventing the log from growing unboundedly).
GoalClassifier: verifies whether the goal is truly complete. Run cap is classifier_max_runs; exceeding the limit triggers BackOffPaused. last_classifier_verdict records the most recent judgment (Achieved / NotAchieved).
Stall detection: the same gap fingerprint appearing twice → trigger early-exit (NoProgressPaused), preventing the goal from spinning in a dead end without knowing.
Token budget: three fields in GoalOrchestration, token_budget / tokens_used / token_baseline, tracked precisely. live_subagent_tokens has a value only while an active sub-agent is running; live_tokens_by_model breakdown is sent only when two or more different models (single-model case is merged, preventing a 1-element vec from messing up the UI).
stateDiagram-v2
[*] --> Idle
Idle --> Planning : /goal 命令 / UpdateGoalTool
Planning --> Executing : GoalPlanner.Planned
Planning --> UserPaused : FailClosed / 用户中断
Executing --> Executing : GoalStrategist (fail-open)
战略师建议后继续
Executing --> UserPaused : Ctrl+C / GoalStopDetector 检测到提前放弃
Executing --> BackOffPaused : classifier 超限
Executing --> NoProgressPaused : stall 检测(相同 gap fingerprint)
Executing --> InfraPaused : 基础设施错误
Executing --> BudgetLimited : token 预算耗尽
Executing --> Blocked : 目标不可达
Executing --> Complete : GoalClassifier 确认完成
UserPaused --> Executing : 用户 Resume
BackOffPaused --> Executing : 间隔后 Resume
Chapter 7 · Tools and permissions
7.1 Full tool inventory
xai-grok-tools/src/implementations/grok_build/mod.rs is the new-architecture tools’ registration entry (NewTool trait):
| Group | Tool name | Function summary |
|---|---|---|
| File read | ReadFileTool |
read a file, supporting offset and line-count limit |
| File read | GrepTool |
regex search (underlying ripgrep) |
| File read | ListDirTool |
list a directory |
| File edit | SearchReplaceTool |
exact string replace (must Read first) |
| Exec | BashTool |
execute a shell command (with permission gating) |
| Exec | TaskTool |
spawn a background task |
| Exec | KillTaskTool / KillTerminalCommandTool |
kill a task |
| Task output | TaskOutputTool / WaitTasksTool / GetTerminalCommandOutputTool |
read background-task output / wait for completion |
| Plan | TodoWriteTool |
maintain a todo list |
| Goal | UpdateGoalTool |
update/complete a Goal Mode goal |
| Plan mode | EnterPlanModeTool / ExitPlanModeTool |
enter/exit read-only plan mode |
| Schedule | SchedulerCreateTool / SchedulerDeleteTool / SchedulerListTool |
create/delete/list scheduled tasks |
| Network | WebFetchTool |
fetch a URL to Markdown |
| Network | WebSearchTool |
web search |
| Monitor | MonitorTool |
monitor a background task’s streaming output |
| User interaction | AskUserQuestionTool |
ask the user a question (can be feature-flag closed) |
| Multimodal | ImageEditTool / ImageGenTool |
image edit/generate |
| Multimodal | ImageToVideoTool / ReferenceToVideoTool |
image-to-video / reference-image generate video |
| LSP | LspTool |
language-server integration (definition/references/diagnostics etc.) |
| Workflow | WorkflowTool |
trigger a predefined workflow |
| Deploy | DeployAppTool |
application deploy |
| Memory | (see implementations/memory/) |
cross-session memory read/write |
| Skills | (see implementations/skills/) |
load a skill manual on demand |
A significant difference from other agents: grok has multimedia generation tools (ImageGenTool/ImageEditTool/ImageToVideoTool/ReferenceToVideoTool), directly reflecting xAI’s multimodal layout; the SchedulerCreateTool series implements scheduled tasks (cron-style); WorkflowTool supports triggering predefined workflow scripts.
Tool-registration architecture: the old Tool trait and the new NewTool trait coexist (mod.rs comments have a "new-architecture" note); ToolBridge is the unified access façade (xai-grok-tools/src/bridge.rs); tool_definitions() and tool_definitions_builtins_only() respectively return definition lists with/without MCP tools. ToolBridge internally has a lock (Arc<internal lock>); tool-state changes (MCP registration, completion tracking, retry config) update lock-safely.
7.2 Bash tool special handling
Before execution BashTool must go through PermissionManager’s bash command classification (xai-grok-workspace/src/permission/bash_command_splitting.rs)—parse the bash AST with tree-sitter, multi-dimensional risk assessment:
- Safe-command allowlist: ls, cat, git read-only operations, kubectl get, etc. allowed immediately;
- Dangerous-command detection: rm, chmod, git push,
dd,mkfs, etc. trigger a prompt or refuse; - rg --pre risk:
rg --prefeeds file content to a preprocess command to execute, equivalent to arbitrary code execution, detected separately; - kubectl injection vectors:
--kubeconfig, auth-injection flags intercepted separately; - BSD ps environment leak: BSD-style
ps -eEetc. flags can print all process environment variables, marked separately; - Opaque shell structure: dynamic
eval, heredoc cannot be statically analyzed; conservative prompt rather than silent allow ("fail-safe" principle).
7.3 Permission arbitrator
xai-grok-workspace/src/permission/manager.rs (8759 lines, the permission system’s largest single file) implements three decision modes:
YOLO(总是批准)→ 用于 --yolo / bypassPermissions 模式
Auto(LLM 分类器)→ 用于 auto 模式,LLM 给出 allow/deny 判断
Ask(提示用户)→ 默认,弹出询问
Auto mode’s safety limits: - Consecutive auto-denies over 3 times → force fall back to Ask - Total auto-denies over 20 times → force fall back to Ask - Prevent the classifier in a wrong mode from infinitely denying and stalling the agent.
User-authorization persistence: the user’s approve decisions land on disk (exec_risk.rs + state.rs); next time a similar operation is not re-asked.
gate_preflight.rs: a preflight check before tool execution, doing a fast rule match before entering the LLM classifier or a popup (improves response speed).
flowchart TD
A["工具 execute() 被调用"] --> B["gate_preflight
快速规则匹配"]
B --> C{"permission_mode"}
C -->|bypassPermissions / YOLO| D["直接放行"]
C -->|plan| E["编辑工具? → deny
读取工具 → allow"]
C -->|auto| F["bash_command_splitting
tree-sitter 解析"]
F --> G{"风险级别"}
G -->|安全白名单| D
G -->|危险| H["LLM 分类器"]
H --> I{"分类结果"}
I -->|allow| D
I -->|deny| J["拒绝 + 记录
连续3次/总计20次 → 回落 Ask"]
C -->|default / acceptEdits| K{"是否首次或未记忆?"}
K -->|已批准| D
K -->|未知| L["弹窗询问用户
(Once / Always / Deny)"]
L -->|Once| D
L -->|Always| M["持久化批准决定
以后不再问"]
L -->|Deny| N["DeniedError → 模型收到错误"]
M --> D
Chapter 8 · Context compaction and memory
8.1 CompactionPolicy
xai-grok-agent/src/compaction.rs defines the compaction policy (defaults):
pub struct CompactionPolicy {
pub auto_compact_threshold_percent: u32, // 默认 85%
pub compact_model: Option<String>, // None = 用会话当前模型
pub memory_flush_enabled: bool, // 默认 false
pub wall_clock_budget_secs: u64, // 默认 300 秒
pub two_pass_enabled: bool, // 默认 false
}
Trigger: Agent.should_auto_compact() calls xai_token_estimation::exceeds_threshold(total_tokens, cw, threshold_percent) (agent.rs): returns true when total tokens reach 85% of the context window (configurable); the agent loop triggers compaction next round.
8.2 Two-pass compaction (two_pass_enabled)
This is grok’s most complex compaction mechanism compared with other agents (session/helpers/session_compact.rs, full_replace_compaction.rs):
- Single pass (default): near the threshold, the compaction agent generates a summary of the history’s front, keeps the tail (to guarantee continuity), the summary replaces old history;
- Two pass (two_pass_enabled = true):
- Pre-trigger (Pass 1, background speculation): when usage is approaching the threshold, generate NOTE₁ (a summary draft) of the history’s front in the background in advance, without waiting to actually hit the threshold;
- Real compaction (Pass 2, when the threshold triggers): generate the final summary from NOTE₁ + the recent tail.
This way summary quality is higher (two compressions reduce information loss), and when it truly triggers Pass 1’s result is already ready, latency lower.
wall_clock_budget_secs = 300: a single compaction generation runs at most 300 seconds; timeout truncates and retries—a dedicated defense against “reasoning models thinking too long” (comment original: "a generation exceeding it is cut and retried — the backstop for reasoning runaways token limits miss").
memory_flush_enabled = false: when on, before each compaction first run a memory flush turn—let the model extract what should be long-term remembered from the current conversation, write it into the memory system, then compact history. Default off, because it extra-consumes tokens and time.
session_recap.rs / session_summary.rs: generate a session summary (for the session list display and search index), independent of the compaction flow.
compaction_context.rs / memory_context.rs: prepare the context needed at compaction/memory flush (history slices, protected-paragraph selection, etc.).
8.3 Memory system
xai-grok-shell/src/session/memory/ has only mod.rs and hooks.rs two files, showing the memory system is hook-style integration rather than an independent module:
- AgentDefinition.memory field: each agent can declare its own memory scope (
MemoryScope), which can besession(session-level) or a more persistent scope; - When memory_flush_enabled = true: memory hooks fire before compaction, letting the model actively distill and store important information;
- UpdateGoalTool: when Goal Mode ends, calling this tool can write goal-completion status into memory;
implementations/memory/: concrete memory-tool implementations (read, write, retrieve).
Compared with opencode fully relying on human-maintained AGENTS.md, and Claude Code having an automatic memory mechanism, grok’s memory system is optional: default lightweight (session-level); when needed, turn on memory_flush or use UpdateGoalTool to write actively.
flowchart TD
A["每轮 turn 结束统计 token"] --> B{"总 token ≥ 上下文窗口的 85%?"}
B -->|否| C["继续"]
B -->|是| D{"two_pass_enabled?"}
D -->|是| E["Pass 1 已在后台生成 NOTE₁"]
D -->|否| F["直接进入单阶段压缩"]
E --> G["Pass 2: NOTE₁ + 尾段 → 最终摘要
wall_clock 超 300s → 截断重试"]
F --> G
G --> H{"memory_flush_enabled?"}
H -->|是| I["memory flush turn
模型摘出重要信息 → 记忆系统"]
H -->|否| J["摘要替换历史前段
保留尾部保证连贯"]
I --> J
J --> K["从新的历史基线继续"]
Chapter 9 · Sub-agents and multi-agent
Workflow manager (session/workflow/manager.rs): grok’s multi-agent concurrency-management core; key constraint: at most 4 workflows run concurrently (WorkflowManager hard cap). Each workflow has:
- a unique run ID + journal file (supports resume);
- CancellationToken (independently cancellable);
- on pause, first set the pause flag then send a cancel signal—distinguish “active pause” from “true cancel,” preventing state misjudgment;
- cancel_all_and_drain(): graceful clearing on close (including timeout).
Sub-agent spawn (TaskTool): the model calls TaskTool → background-start a new session actor (sub-agent) → the main agent can wait for the result (sync) or return immediately (async background).
AgentDefinition-level constraints:
- allowed_subagent_types: allowlist, only allow spawning specific-type sub-agents;
- session_tools_allowlist / session_tools_denylist: sub-agent tool-visibility control;
- inject_default_tools: master switch for default-tool injection into a sub-agent;
- capability_mode: SubagentCapabilityMode (from xai-tool-types), controlling the sub-agent’s capability set.
Agent discovery and priority (xai-grok-agent/src/discovery.rs):
项目级 (.grok/agents/ 或 .claude/agents/)
优先覆盖
用户级 (~/.grok/agents/ 或 ~/.claude/agents/)
优先于
打包级 (~/.grok/bundled/agents/)
优先于
内置(general-purpose / explore / plan)
Note: user-level agents cannot shadow built-in subagents (all_subagents()’s merge_subagents() has this restriction)—this guarantees built-in sub-agent behavior stability; only a project-level definition can truly override built-in behavior.
Plugin agent: by_name_in_cwd_with_plugins() supports plugin-name:agent-name qualified-name addressing; there is ambiguity detection (error if multiple plugins provide the same-named agent).
Goal Mode’s sub-agent architecture: Goal Mode itself is a multi-agent collaboration flow: - GoalPlanner: an independent sub-agent, dedicated to writing plan.md; - GoalStrategist: an independent sub-agent, dedicated to analyzing stuckness; - GoalClassifier: an independent sub-agent, dedicated to verifying goal completion; - GoalWorker: the executing-phase main agent (i.e. the current session actor’s own turn); these modules take the stage in turn, completing the “plan → execute → verify → recover” full closed loop, rather than one agent doing it all.
sequenceDiagram
participant User as 用户
participant Main as 主 SessionActor
participant WFM as WorkflowManager
participant GP as GoalPlanner (子 agent)
participant GW as Goal 执行 agent
participant GS as GoalStrategist (子 agent)
participant GC as GoalClassifier (子 agent)
User->>Main: /goal "重构认证模块"
Main->>WFM: 新建 workflow run (≤4 并发)
WFM->>GP: spawn GoalPlanner
GP-->>WFM: plan.md 写成 (Planned) / 失败 (FailClosed)
WFM->>GW: 开始 Executing 阶段
loop 执行循环
GW->>GW: 读 plan.md, 按步骤执行工具
GW->>GC: 每轮验证 (GoalClassifier)
GC-->>GW: Achieved / NotAchieved
alt N 次连续失败
GW->>GS: spawn GoalStrategist
GS-->>GW: strategy_note.md (PlanGuard 保护 plan.md)
end
alt stall 检测 / budget 超限
GW-->>WFM: NoProgressPaused / BudgetLimited
end
end
GC-->>WFM: Achieved → Complete
WFM-->>User: 目标完成通知
Chapter 10 · Ecosystem
10.1 Slash commands
grok’s commands are two classes: TUI application-layer commands (operate the UI) and server-side commands (manipulate agent behavior). Key server-side commands (session/commands.rs):
| Command | Function |
|---|---|
/goal <description> |
start a Goal Mode autonomous-task loop |
/compact |
manually trigger context compaction |
/recap |
generate a current-session summary |
/skills |
list available skills |
/agents |
list available agent definitions |
/model <name> |
switch model |
/effort <level> |
switch reasoning grade |
/memory |
view/manage memory |
Common TUI application-layer commands (accessed via the Ctrl+P command palette):
- Session management: new, search historical sessions (FTS);
- Workspace: switch working directory, git status;
- Settings: theme, keybindings, telemetry switch.
10.2 Skills (skill manuals)
Skills are grok’s lightweight extension mechanism (xai-grok-tools/src/implementations/skills/): write some knowledge (e.g. how to use a certain Rust library, a certain company’s internal API spec) as Markdown, put it in a specified directory; when the agent needs it, load it into context by name.
Discovery path (by priority):
1. .grok/skills/ or .grok/skill/ (project-level)
2. ~/.grok/skills/ (user-level)
3. ~/.claude/skills/ (compatible with Claude Code)
4. .agents/ and other convention directories
AgentDefinition’s discover_skills: true (default) auto-scans; inherit_skills: true inherits the skills list from the parent agent. The system prompt only puts the skills roster; the body loads on demand—“open the manual only when you use it,” saving tokens.
10.3 MCP (Model Context Protocol)
xai-grok-mcp crate + session/mcp_dispatcher.rs + session/mcp_servers.rs:
MCP Dispatcher (mcp_dispatcher.rs)’s core design: a 50ms rolling window—merge frequent MCP client events (connect/disconnect/state change) into batches, then send ACP notifications, preventing state-jitter screen flooding. last-write-wins policy: for the same (server, kind) pair within the window, keep only the latest state.
McpServerStatus: Ready / Initializing / Unavailable / NeedsAuth. NeedsAuth status prompts the user in the TUI to configure auth.
ShutdownState: tracks servers “actively deleted” (ConfigRemoved) and servers “with a restart task in flight,” preventing treating an actively deleted server as an unexpected drop and triggering auto-restart.
auto-restart policy: stdio server unexpected disconnect → spawn a restart task; HTTP server disconnect → in-place recover (do not re-spawn a process).
MCP tool naming: server_name_tool_name (sanitize processed), similar to opencode’s rule.
AgentDefinition.mcp_servers: each agent can declare its own dedicated MCP servers (McpServerRef list); mcp_inheritance controls whether to inherit global MCP config from the parent agent.
10.4 Hooks system
Under xai-grok-shell/src/session/extensions/ there is hooks.rs, plus an independent xai-grok-hooks crate. Hooks allow the user to inject custom shell commands or scripts at key event nodes (before/after tool execution, session start/end, turn start/end, etc.)—this is grok’s automation extension interface.
10.5 Plugin Marketplace
xai-grok-shell/src/plugin.rs implements a complete plugin lifecycle:
Install sources:
- Git repo (including GitHub shortcut owner/repo);
- Local directory (symlink, used in development);
- Marketplace (qualified name resolution, including owner/repo qualifier).
Safety control: allowlist filtering in restricted environments—an enterprise internal deploy can allow only whitelist plugin sources, preventing casually pulling external code.
InstallRegistry: persistently tracks each installed plugin repo (including git commit hash, plugin name, marketplace source), supporting version rollback precise to a commit.
Ambiguity detection: when multiple marketplaces provide a same-named plugin, error requiring a qualified name—do not allow “whoever installed first wins” fuzzy behavior.
flowchart TB
subgraph 命令来源
A["/goal / /compact / /recap"]
B["TUI Ctrl+P 命令面板"]
end
subgraph Skills
C[".grok/skills/ → ~/.grok/skills/
~/.claude/skills/ (兼容)"]
end
subgraph MCP
D["mcp_dispatcher
50ms 窗口合并 + last-write-wins"]
E["stdio auto-restart
HTTP in-place 恢复"]
end
subgraph Plugin
F["Git 仓库 / 本地目录 / Marketplace"]
G["InstallRegistry (commit hash 版本追踪)"]
H["allowlist 安全过滤 (企业级)"]
end
A --> LOOP["SessionActor 主循环"]
B --> LOOP
C --> AB["AgentBuilder
(discover_skills + inject)"]
D --> ACP_GW["ACP Gateway
x.ai/mcp/server_status"]
E --> D
F --> G --> LOOP
H --> G
AB --> LOOP
Chapter 11 · Features
Auth system: xai-grok-auth (auth-provider + retry-middleware two modules). Supported ways:
- xAI account (browser OAuth flow);
- API key (configured directly);
- OIDC (enterprise identity provider, hub_auth.rs);
- External auth providers (custom endpoints via xai-grok-config).
AuthRetryMiddleware (feature-gated): auto-refresh on token expiry, retry after failure—guarantees a long-running Goal Mode will not interrupt because of token expiry.
Models and reasoning grades: xai-grok-config configures the default model (~/.grok/config.toml); AgentDefinition can override (model / effort fields); /model and /effort commands switch at runtime. Different agents can use different models; Goal Mode’s planning/verification sub-agents can specify a higher-performance model.
Three run modes:
- Interactive TUI: default, full-screen Ratatui UI, mouse support, Elm-style architecture;
- Headless: grok -p "prompt" executes directly, stdout the result, fits CI/scripts;
- ACP mode: grok --acp exposes Agent Client Protocol; IDEs such as Zed embed grok through this protocol.
JJ (Jujutsu) VCS support (session/extensions/jj.rs): not only Git, also Jujutsu—a direct embodiment of xAI’s internal engineering practice (xAI’s engineering team uses Jujutsu as its primary VCS tool).
Telemetry (session/telemetry.rs, extensions/): detailed records of each tool call’s latency, classifier source, token consumption, compaction usage, etc.; supports enterprise-grade telemetry config and local off.
PR integration (session/extensions/pr.rs): built-in pull-request workflow support (create/view PR), similar to opencode’s GitHub Action integration but more deeply integrated.
Code navigation (session/extensions/code_nav.rs): with xai-codebase-graph’s codebase-index capability, supports go-to-definition, find-references, and other code-nav operations (LSPTool’s outward interface).
Worktree isolation (xai-fast-worktree, session/extensions/worktree.rs): Goal Mode can run in an independent git worktree, avoiding code changes during goal execution polluting the main workspace. The AgentDefinition.isolation field controls whether to enable.
Crash handling (xai-crash-handler): catch panic, generate a structured crash report, support reporting telemetry, guaranteeing a long-running Goal Mode has scene information after a crash for investigation.
Announcement system (xai-grok-announcements): periodically pull new-version notices, policy changes, etc. from xAI servers, display in the TUI.
Session search (session/storage/search_fts.rs): local full-text search (FTS), quickly retrieve in historical sessions; search_remote_sync.rs supports syncing to a remote index.
flowchart LR
subgraph 接入
TUI["交互 TUI
Ratatui 全屏"]
HL["无头模式
grok -p"]
ACP["ACP 模式
grok --acp (Zed 等)"]
end
subgraph 认证
OAUTH["xAI OAuth"]
APIKEY["API Key"]
OIDC["OIDC 企业 SSO"]
EXT["自定义端点"]
end
subgraph 特色
GOAL["Goal Mode
规划→执行→验证"]
JJ["JJ (Jujutsu) VCS"]
WT["Worktree 隔离"]
MEDIA["多媒体工具
图片/视频生成编辑"]
SCHED["定时任务
SchedulerCreateTool"]
end
TUI & HL & ACP --> SA["SessionActor"]
OAUTH & APIKEY & OIDC & EXT --> SA
SA --> GOAL & JJ & WT & MEDIA & SCHED
Chapter 12 · Summary: design philosophy and trade-offs
After reading the source, grok-build feels like: a Rust-native agent that puts “autonomous execution” and “enterprise-grade reliability” in equal position. Its distinctive ideas and highlights:
① Goal Mode is grok’s core bet. Most agents (Claude Code, opencode, Raven……) hand autonomy to “the model itself judging when to stop”—only grok built an independent, explicit autonomous-execution state machine (GoalTracker + GoalPlanner + GoalStrategist + GoalClassifier + GoalStopDetector). The model does not need to know “have I finished”—the Classifier judges. The model easily gets stuck—the Strategist rescues (and PlanGuard protects; rescue failure will not destroy the original plan). The model gives up early—StopDetector’s 9-class pattern recognition finds it. This mechanism lets grok, when handling a long-running task that needs hours and many tokens, autonomously persist more than other agents rather than quit halfway or quietly lie “I am done.”
② A Rust single binary is an engineering-faith statement. Choosing Rust is not only performance, it is a stance: “we think an agent should be as reliable as systems software.” No runtime dependency means install and run in CI, embedded Linux, offline enterprise environments are forever predictable. 60+ crates of modularity shows the team is seriously managing dependency boundaries, not piling everything in one large package. DotSlash locks toolchain versions; even “the tools needed to build this binary” are reproducible. This is the only mainstream coding agent besides CodeWhale (also Rust) built in Rust.
③ The bash permission system is among the industry’s most rigorous. tree-sitter parses the bash AST (same as opencode), but grok’s dangerous-pattern detection surface is wider: rg --pre preprocess-command injection, kubectl kubeconfig injection, BSD ps environment leak, heredoc’s static unanalyzability—all have dedicated detection. 8759-line manager.rs plus auto / YOLO / ask three grades + classifier-protection caps (consecutive 3 / total 20 auto-deny caps) is an extreme implementation of the philosophy “a permission system should rather annoy than cause an incident.”
④ ACP is grok’s “outward-facing” design. Similar to opencode’s “the server is the body,” grok uses ACP to free agent capability from the terminal—but ACP goes further: it is a formal protocol spec (independent crate xai-acp-lib), not just an HTTP API. Already integrated with Zed, meaning xAI is seriously pushing “agent collaboration protocol standardization.”
Obvious trade-offs:
- Does not accept external contributions: the repo is only a snapshot of xAI’s internal monorepo. This buys extremely high internal decision efficiency, but sacrifices open-source community participation. Code quality and architecture design show an internal professional team’s level, but a PR you file on GitHub has no meaning.
- Goal Mode’s learning curve: GoalTracker + GoalPlanner + GoalStrategist + GoalClassifier + GoalStopDetector five collaborating components, 3–4× more complex than any other agent’s loop. For a simple task (change one line, explain one function), this mechanism is overkill; the ordinary turn loop is more efficient. grok’s design assumption is “you will have a real long-running-task need”—if you do not, this complexity is given for free.
- Grok model binding: although the auth layer supports OIDC and custom endpoints, tool implementations (especially multimedia tools: ImageGenTool / VideoTool) are tailored for xAI model capability. Multimedia-generation tools shrink sharply when attaching other models.
- No side-by-side benchmark: grok has not published an objective performance comparison against Claude Code or opencode. 22k stars shows high market attention, but lacking an independent benchmark leaves “how much better is Goal Mode really” in doubt.
- Memory system lightweight: compared with Raven’s dual-track memory (EverOS + Curator), hermes-agent’s RAG memory, grok’s memory is optional (default session-level, memory_flush default off). This is deliberate restraint—“don’t automatically remember too much for the user”—but it also means long-term personalization needs the user to maintain it themselves via skills and AGENTS.md.
One-sentence summary: Claude Code is “Anthropic’s best terminal spokesperson built for Claude,” opencode is “an open agent platform built for every model and every client,” and grok is “an enterprise-grade agent xAI built in Rust, with Goal Mode autonomous execution as the core differentiator”—its Rust single binary guarantees a reliability foundation, Goal Mode pushes autonomous capability to the highest point among peers, and the ACP protocol gives it the ambition to become a standard IDE integration protocol.
mindmap root((grok-build
设计哲学)) 自主执行 Goal Mode 多阶段状态机 GoalPlanner Fail-Closed 规划 GoalStrategist Fail-Open 恢复 GoalClassifier 验证完成 GoalStopDetector 防提前放弃 系统可靠性 Rust 单二进制(DotSlash 锁工具链) wall_clock_budget 超时防护 two_pass 压缩减信息损失 8759行权限系统(最严谨之一) 企业级扩展 OIDC / 外部 auth / 公司代理 Plugin Marketplace(安全 allowlist) 遥测配置 + 崩溃报告 MCP 50ms窗口 + 自动重启 协议开放 ACP(Agent Client Protocol) Zed 编辑器集成 .claude/agents/ 兼容 Claude Code JJ VCS 支持 明显取舍 不接受外部贡献(内部快照) Goal Mode 对简单任务 overkill 多媒体工具深绑 xAI 模型 记忆系统默认轻量(选配 flush)
(End of lecture. Every crate/module citation in the text can be checked directly under crates/codegen/ at https://github.com/xai-org/grok-build; features marked “default off” must be explicitly enabled in ~/.grok/config.toml or AgentDefinition frontmatter. The SOURCE_REV file tracks this repo’s sync point with xAI’s internal monorepo.)