mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
fix(grok): allow external-directory reads so the pr-reviewer can work
Live NAS run showed the Grok pr-reviewer claim the review and fetch the diff, then write it to /tmp and FAIL to read it back: opencode auto-denied "external_directory (/tmp/*)" — its file tools refuse paths outside the project cwd, and in headless serve/run mode an "ask" permission auto-rejects (no human). Add permission.external_directory (default "allow", env ROBOCO_GROK_EXTERNAL_DIR_PERMISSION) to the generated opencode.json. The container is the sandbox and secret-scrub still blocks credential-file reads, so allowing in-container external-dir reads is safe and unblocks legitimate scratch use (e.g. the pr-reviewer grepping a large diff in /tmp). Verified live against grok-build-0.1: with external_directory:"allow" the Read tool reads a file outside cwd and returns its contents (no auto-reject); the plain-string form is accepted by opencode 1.17.8. Needs a rebuild of roboco-agent-grok + a pr-reviewer re-run on the NAS to confirm.
This commit is contained in:
@@ -94,13 +94,17 @@ class XaiTarget:
|
|||||||
class OpencodeGuards:
|
class OpencodeGuards:
|
||||||
"""Tunable runtime guards baked into a Grok ``opencode.json``.
|
"""Tunable runtime guards baked into a Grok ``opencode.json``.
|
||||||
|
|
||||||
``bash``/``edit`` gate the command/file tools; the timeouts bound a single
|
``bash``/``edit`` gate the command/file tools; ``external_directory`` gates
|
||||||
model call and abort an idle stream; ``disable_subagents`` removes the
|
reading paths outside the project cwd (opencode auto-DENIES an ``ask`` in
|
||||||
subagent ``task`` tool entirely.
|
headless mode, which blocked the pr-reviewer from reading a diff it wrote to
|
||||||
|
/tmp — so default ``allow``: the container is the sandbox and secret-scrub
|
||||||
|
still blocks credential files); the timeouts bound a single model call and
|
||||||
|
abort an idle stream; ``disable_subagents`` removes the subagent ``task`` tool.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
bash_permission: str = "allow"
|
bash_permission: str = "allow"
|
||||||
edit_permission: str = "allow"
|
edit_permission: str = "allow"
|
||||||
|
external_directory_permission: str = "allow"
|
||||||
request_timeout_ms: int = _DEFAULT_REQUEST_TIMEOUT_MS
|
request_timeout_ms: int = _DEFAULT_REQUEST_TIMEOUT_MS
|
||||||
chunk_timeout_ms: int = _DEFAULT_CHUNK_TIMEOUT_MS
|
chunk_timeout_ms: int = _DEFAULT_CHUNK_TIMEOUT_MS
|
||||||
disable_subagents: bool = True
|
disable_subagents: bool = True
|
||||||
@@ -160,6 +164,11 @@ def build_opencode_config(
|
|||||||
"permission": {
|
"permission": {
|
||||||
"bash": guards.bash_permission,
|
"bash": guards.bash_permission,
|
||||||
"edit": guards.edit_permission,
|
"edit": guards.edit_permission,
|
||||||
|
# Reading paths outside the project cwd (e.g. /tmp scratch). opencode
|
||||||
|
# auto-denies an "ask" in headless mode, which blocked the pr-reviewer
|
||||||
|
# from reading a diff it wrote to /tmp; "allow" since the container is
|
||||||
|
# the sandbox and secret-scrub still blocks credential files.
|
||||||
|
"external_directory": guards.external_directory_permission,
|
||||||
},
|
},
|
||||||
"instructions": instruction_paths,
|
"instructions": instruction_paths,
|
||||||
# Command guard / secret-scrub (bash-guard parity). Baked into the image.
|
# Command guard / secret-scrub (bash-guard parity). Baked into the image.
|
||||||
@@ -198,6 +207,9 @@ def main() -> int:
|
|||||||
)
|
)
|
||||||
guards = OpencodeGuards(
|
guards = OpencodeGuards(
|
||||||
bash_permission=os.environ.get("ROBOCO_GROK_BASH_PERMISSION", "allow"),
|
bash_permission=os.environ.get("ROBOCO_GROK_BASH_PERMISSION", "allow"),
|
||||||
|
external_directory_permission=os.environ.get(
|
||||||
|
"ROBOCO_GROK_EXTERNAL_DIR_PERMISSION", "allow"
|
||||||
|
),
|
||||||
request_timeout_ms=_env_int(
|
request_timeout_ms=_env_int(
|
||||||
"ROBOCO_GROK_REQUEST_TIMEOUT_MS", _DEFAULT_REQUEST_TIMEOUT_MS
|
"ROBOCO_GROK_REQUEST_TIMEOUT_MS", _DEFAULT_REQUEST_TIMEOUT_MS
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -103,6 +103,23 @@ def test_build_opencode_config_bash_permission_is_tunable() -> None:
|
|||||||
assert cfg["permission"]["edit"] == "allow"
|
assert cfg["permission"]["edit"] == "allow"
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_opencode_config_allows_external_directory_by_default() -> None:
|
||||||
|
# opencode auto-denies an "ask" external-dir read in headless mode (the
|
||||||
|
# pr-reviewer couldn't read a diff it wrote to /tmp); default "allow".
|
||||||
|
cfg = build_opencode_config(_MCP, _TARGET, instruction_paths=[])
|
||||||
|
assert cfg["permission"]["external_directory"] == "allow"
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_opencode_config_external_directory_is_tunable() -> None:
|
||||||
|
cfg = build_opencode_config(
|
||||||
|
{},
|
||||||
|
_TARGET,
|
||||||
|
instruction_paths=[],
|
||||||
|
guards=OpencodeGuards(external_directory_permission="ask"),
|
||||||
|
)
|
||||||
|
assert cfg["permission"]["external_directory"] == "ask"
|
||||||
|
|
||||||
|
|
||||||
def test_build_opencode_config_disables_subagent_task_tool_by_default() -> None:
|
def test_build_opencode_config_disables_subagent_task_tool_by_default() -> None:
|
||||||
# The subagent `task` tool must be hard-disabled: a RoboCo role never uses
|
# The subagent `task` tool must be hard-disabled: a RoboCo role never uses
|
||||||
# opencode-internal subagents, and one spawned on grok-build-0.1 hung the run.
|
# opencode-internal subagents, and one spawned on grok-build-0.1 hung the run.
|
||||||
|
|||||||
Reference in New Issue
Block a user