Skip to content

Follow up Grok CLI upstream updates: sandbox.toml deny-glob ignore surface (project scope now documented), per-handler hook env dropped #2498

Description

@dyoshikawa

Summary

Two Grok CLI surfaces are unfollowed as of upstream v0.2.114 (2026-07-29): project-scope .grok/sandbox.toml custom-profile deny globs are now documented, giving grokcli a real path-deny surface for rulesync's ignore feature (currently unsupported), and the per-handler hook env map is silently dropped on generate and import.

Baseline: #2418's gaps were fixed in #2447 (.grok/rules/, skill invocation flags, http hooks) and .grok/commands/ support has since landed too (src/features/commands/grokcli-command.ts). This pass verified against a clone of xai-org/grok-build at commit 500129c (2026-07-29, version 0.2.114) and the changelog window v0.2.100–v0.2.114 (x.ai/build/changelog).

Gaps

1. ignore — .grok/sandbox.toml custom-profile deny globs (project + global)

  • Upstream: sandbox doc — "Custom profiles can be defined in ~/.grok/sandbox.toml (user-level) or project .grok/sandbox.toml (project-level)", example [profiles.my-profile] with extends = "workspace", restrict_network = true, deny = ["/secrets", "**/.env", "**/*.pem"]. Source-confirmed at 0.2.114: crates/codegen/xai-grok-sandbox/src/profiles.rs load_sandbox_config(workspace) reads ~/.grok/sandbox.toml then merges <workspace>/.grok/sandbox.toml; a custom profile's deny list is "kernel-enforced (read + write/rename)". The glob shape is exactly what rulesync's ignore feature expresses.
  • rulesync: ignore is unsupported for grokcli. .grokignore genuinely does not exist upstream (re-verified at 0.2.114), so the old verdict was right for the wrong surface — Follow up Grok CLI upstream updates: .grok/commands/ and .grok/rules/ surfaces unmodeled, skill invocation flags dropped, http hook type #2418 declined to file this when the docs listed [sandbox] as global-only, and that reasoning no longer holds now that the project-scope file is documented.
  • Design caveats (shape, don't block): the deny list only bites while the named profile is active (grok --sandbox <name>, [sandbox] profile, or GROK_SANDBOX), and merge_project_profiles keeps a globally-defined profile of the same name, so a project file cannot silently override a user profile.

2. hooks — per-handler env silently dropped

  • Upstream: crates/codegen/xai-grok-hooks/src/config.rsRawHandler parses env: HashMap<String, String> ("Extra env vars, merged into HookSpec::extra_env"); env_expand.rs documents that ${VAR}/$VAR substitution in command and url "prefers a per-hook extra_env map over the process environment". Source-confirmed at 0.2.114; the hooks doc lists only type/command/url/timeout, so this is undocumented-but-real.
  • rulesync (project + global): canonical HookDefinition already carries env (src/types/hooks.ts), and qwencode-hooks.ts emits it on command hooks — but GROKCLI_CONVERTER_CONFIG (src/features/hooks/grokcli-hooks.ts) has no passthrough entry for env, and the shared buildToolHooks emits env for nobody by default. A user who sets env on a hook gets it dropped for grokcli with no warning, even though Grok honours it.

Proposed Follow-up

  1. Add a GrokcliIgnore adapter writing a rulesync-owned profile (e.g. [profiles.rulesync] with extends = "workspace" and the deny array) to .grok/sandbox.toml (project) and ~/.grok/sandbox.toml (global). The file holds other user-authored profiles, so declare it through the shared-config gateway with ownedKeys scoped to the single profiles.rulesync table. Document plainly that the profile must be activated to take effect.
  2. Forward env on command hooks for grokcli (mirroring qwencode-hooks.ts) and round-trip it on import. Implementation note from feat(grokcli): write non-root rules to .grok/rules, and stop dropping skill flags and http hooks #2447: the hooks registry carries a second copy of the supported-type list driving the "skipped" warning — check whether a field-level equivalent needs the same treatment so the run does not report success for a field it dropped.

Non-gaps (verified at 0.2.114, do not re-file)

  • Hook events: all 14 distinct upstream events (15 variants; SubagentEnd aliases subagent_stop) are in GROKCLI_HOOK_EVENTS.
  • Hooks in config.toml (v0.2.114, 2026-07-24): HookProvenance admits config-file hooks only from managed/user-tier files (/etc/grok/managed_config.toml, $GROK_HOME/managed_config.toml, requirements.toml, $GROK_HOME/config.toml); project config.toml stays limited to [mcp_servers]/[plugins]/[permission] per the settings reference. The .grok/hooks/*.json surface rulesync writes remains correct at both scopes.
  • mcp: full key passthrough (cwd, headers, bearer_token_env_var, startup_timeout_sec, tool_timeout_sec, tool_timeouts all survive); no new transport.
  • permissions: the verbose [permission] rules form is deliberately left user-owned; the compact arrays are the higher-fidelity mapping.
  • commands / rules / skills / subagents / checks: all match upstream discovery and frontmatter; .grokignore still does not exist.
  • Workflows (.grok/workflows/*.rhai) are Rhai orchestration scripts, not markdown prompts — they do not map onto commands.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    consideringenhancementNew feature or requestmaintainer-scrapRough notes for AI implementation. Not for human eyes.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions