From 3e515d54ebcd707f9f3c129265fd67a642c8ec4f Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Fri, 8 May 2026 13:24:30 +0200 Subject: [PATCH] feat(opencode): allow agents to read external Rust crate source @make, @test, @check often need to inspect dependency source (trait definitions, impl details, test patterns) to inform implementation or verify findings. Opencode applies a CWD check on tool access, so reads outside the worktree previously prompted for each access. - Add permission.read/grep/glob path allowlists for the three locations cargo deps live: ~/.cargo/registry/src/, ~/.cargo/git/checkouts/, and /nix/store/*-vendor-*/ for crane / buildRustPackage projects. - Document the discovery pattern in each agent: `cargo metadata --format-version 1` returns absolute paths via packages[].manifest_path. - Cross-reference the registry paths from the permission.bash allowlist comment so future readers see the bash inspection commands (rg/ls) intentionally accept paths outside CWD. - @check gets its first permission block (was tools-only before). Path-pattern syntax for read/grep/glob isn't fully documented; if opencode rejects it, fall back to `permission: { external_directory: allow }` at the project config level. --- config/opencode/agents/check.md | 28 ++++++++++++++++ config/opencode/agents/make.md | 59 +++++++++++++++++++++++++++++++++ config/opencode/agents/test.md | 42 +++++++++++++++++++++++ 3 files changed, 129 insertions(+) diff --git a/config/opencode/agents/check.md b/config/opencode/agents/check.md index 18210dd..7fbc7b1 100644 --- a/config/opencode/agents/check.md +++ b/config/opencode/agents/check.md @@ -6,6 +6,24 @@ tools: write: false edit: false bash: false +permission: + # ── External-directory reads (registry / git deps / nix-vendored) ── + # Opencode applies a CWD check on tool access; these patterns whitelist + # the cargo dependency source trees so the Read/Grep/Glob tools don't + # prompt for each access. @check sometimes needs to verify a finding + # against a dependency's actual source (trait bounds, impl details). + read: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + grep: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + glob: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow --- @@ -15,6 +33,16 @@ You are a senior engineer who catches expensive mistakes before they ship. Your **Note:** This agent reviews user-provided artifacts (diffs, specs, configs). It does not independently fetch code from repos. +**External crate source (Rust):** when verifying a finding against a dependency's actual source (trait bounds, impl details, behavior under specific inputs), you can read from these paths via Read/Grep/Glob (no permission prompt — see frontmatter): + +| Source | Path pattern | +|---|---| +| Registry crates | `~/.cargo/registry/src/index.crates.io-*/-/` | +| Git deps | `~/.cargo/git/checkouts/-//` | +| Nix-vendored deps | `/nix/store/-vendor-*/-/` | + +The caller (`@check`'s dispatcher in the workflow) typically passes the dependency's name and version inline; you locate the path under the registry root. Use this sparingly — only when the finding's correctness genuinely depends on knowing the dep's source, not for general curiosity. + ## Scope You review: diff --git a/config/opencode/agents/make.md b/config/opencode/agents/make.md index a9f0013..7e9f270 100644 --- a/config/opencode/agents/make.md +++ b/config/opencode/agents/make.md @@ -6,6 +6,23 @@ tools: edit: true bash: true permission: + # ── External-directory reads (registry / git deps / nix-vendored) ── + # Opencode applies a CWD check on tool access; these patterns whitelist + # the cargo dependency source trees so the Read/Grep/Glob tools (and + # bash inspection commands like `rg`/`ls`) don't prompt for each access. + # See "Reading External Crate Source" below for the discovery pattern. + read: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + grep: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + glob: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow bash: # Default deny "*": deny @@ -25,6 +42,12 @@ permission: "cargo": allow # ── Read-only inspection ── + # The wildcarded patterns below accept any path argument, including + # paths *outside* the worktree. This is intentional — see "Reading + # External Crate Source" below. Specifically reachable: + # ~/.cargo/registry/src/index.crates.io-*/-/ (registry) + # ~/.cargo/git/checkouts/-// (git deps) + # /nix/store/*-vendor-*/-/ (nix-vendored) "ls *": allow "ls": allow "wc *": allow @@ -146,6 +169,42 @@ The devshell guarantees the right toolchain versions are available. Detect once A task may legitimately span multiple languages (e.g. a Rust binary plus its Python test harness). Run the appropriate verification per file area; document each in the verification block. +## Reading External Crate Source + +For Rust tasks, you may need to inspect dependency source (trait definitions, impl bodies, usage examples) to inform your implementation. External source is reachable via the Read/Grep/Glob tools and via `rg`/`ls` in bash. **Do not edit external source — it's read-only reference material.** + +**Where dependency source lives:** + +| Source | Path pattern | +|---|---| +| Registry crates (most deps) | `~/.cargo/registry/src/index.crates.io-*/-/` | +| Git deps | `~/.cargo/git/checkouts/-//` | +| Nix-vendored deps (crane, buildRustPackage) | `/nix/store/-vendor-*/-/` | +| Workspace-local deps | inside the worktree itself, no special handling | + +**Discovering the exact path** for a specific dependency: + +``` +nix develop -c cargo metadata --format-version 1 +``` + +The JSON output's `packages[].manifest_path` field has the absolute path to each `Cargo.toml`; the source files are siblings under that crate's directory. The registry must be populated first — `cargo check` (or any prior build) downloads everything in `Cargo.lock`. If `cargo metadata` fails because deps haven't been fetched, run `nix develop -c cargo check` once. + +**Reading patterns:** + +- Search across a crate: `rg "trait Serialize" ~/.cargo/registry/src/index.crates.io-*/serde-1.*/src/` +- List a crate's modules: `ls ~/.cargo/registry/src/index.crates.io-*/tokio-1.*/src/` +- Read a specific file: use the Read tool with the absolute path (no permission prompt; the path is reachable). + +**When to consult external source:** +- The task asks you to implement a trait from an external crate, and you need the trait definition. +- An external API is being misused and you want to verify the correct usage. +- A test failure points at a behavior of an external dep that's not obvious from its public docs. + +**When *not* to consult external source:** +- For routine usage that's covered by `cargo doc` / docs.rs (you don't have web access, but the task spec or existing code in the worktree is usually enough). +- To "study" a dependency you're not actively using in this task. + ## Dependency Constraint **No new dependencies or lockfile changes** unless explicitly included in acceptance criteria. diff --git a/config/opencode/agents/test.md b/config/opencode/agents/test.md index b3699b9..5e80864 100644 --- a/config/opencode/agents/test.md +++ b/config/opencode/agents/test.md @@ -6,6 +6,23 @@ tools: edit: true bash: true permission: + # ── External-directory reads (registry / git deps / nix-vendored) ── + # Opencode applies a CWD check on tool access; these patterns whitelist + # the cargo dependency source trees so the Read/Grep/Glob tools (and + # bash inspection commands like `rg`/`ls`) don't prompt for each access. + # See "Reading External Crate Source" below for the discovery pattern. + read: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + grep: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow + glob: + "~/.cargo/registry/src/**": allow + "~/.cargo/git/checkouts/**": allow + "/nix/store/*-vendor-*/**": allow bash: # Default deny "*": deny @@ -28,6 +45,12 @@ permission: "cargo fmt*": allow # ── Read-only inspection ── + # The wildcarded patterns below accept any path argument, including + # paths *outside* the worktree. This is intentional — see "Reading + # External Crate Source" below. Specifically reachable: + # ~/.cargo/registry/src/index.crates.io-*/-/ (registry) + # ~/.cargo/git/checkouts/-// (git deps) + # /nix/store/*-vendor-*/-/ (nix-vendored) "ls *": allow "ls": allow "wc *": allow @@ -126,6 +149,25 @@ Rust: **Anti-patterns — refuse the path even if it would technically be writable:** - `src/tests/foo.rs` and similar regular submodule paths under `src/`. These are not `#[cfg(test)]` modules — they are normal modules that would require a `mod tests;` declaration in production code (`lib.rs` / `main.rs`), which you cannot add. Report as `BLOCKED` and suggest either `tests/.rs` (integration) or a `#[cfg(test)] mod tests` block inside the relevant `src/.rs`. +## Reading External Crate Source + +When you need to inspect a dependency's source — to understand a trait you're testing against, find a known-good test pattern from a well-tested crate, or check a dep's behavior under specific conditions — external source is reachable via the Read/Grep/Glob tools and via `rg`/`ls` in bash. **Do not edit external source.** + +**Where dependency source lives:** + +| Source | Path pattern | +|---|---| +| Registry crates | `~/.cargo/registry/src/index.crates.io-*/-/` | +| Git deps | `~/.cargo/git/checkouts/-//` | +| Nix-vendored deps (crane, buildRustPackage) | `/nix/store/-vendor-*/-/` | + +Discover paths via `nix develop -c cargo metadata --format-version 1`; the JSON has `packages[].manifest_path` per dep. The registry must be populated — run `nix develop -c cargo check` once if the metadata call shows missing source. + +Read patterns: +- `rg "trait Serialize" ~/.cargo/registry/src/index.crates.io-*/serde-1.*/src/` +- `ls ~/.cargo/registry/src/index.crates.io-*/tokio-1.*/tests/` — useful for borrowing test patterns +- Read tool with absolute path for a specific file. + ## Test Philosophy **Contract tests + regression.** Write tests that verify: