From 218de9811b48192f5fa56cd82b411cbeb679992d Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Sun, 30 Aug 2026 00:23:08 +0300 Subject: [PATCH 1/2] ci: say why the checkouts take no submodules The template's checkout steps carried 'submodules: recursive' for the vendored tinybus the module half needed. Both went away together, so the option was dropped -- but a removed line explains nothing to the next reader, and a reviewer flagged exactly that. This repository has no .gitmodules and no gitlink in its tree. Says so at the first checkout step. Co-authored-by: Medulla --- .github/workflows/ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6368346..a94287e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,12 @@ jobs: # This job executes repository code (cargo build/test); don't persist # the token in git config. persist-credentials: false + # No `submodules:` entry on purpose: this repository has no + # submodules. The template it came from vendored `vendor/tinybus` for + # the loadable-module half, which was removed along with that half — + # there is no `.gitmodules` and no gitlink in the tree. Adding one + # back would be a no-op that implies a dependency this crate does not + # have. - uses: dtolnay/rust-toolchain@stable with: From 3fe451147a5aaadd45dc15f6a771b83c1c4fccd7 Mon Sep 17 00:00:00 2001 From: Steven Enamakel Date: Sun, 30 Aug 2026 00:40:53 +0300 Subject: [PATCH 2/2] docs: count ToolScope::All among the permissive defaults Codex again, and again correct. The section added in the previous commit listed scope() among the cautious defaults, but ToolScope::All is the widest setting there is -- it offers the tool to the autonomous agent loop, the CLI and RPC alike. A tool that should only ever be driven deliberately by a human has to say CliRpcOnly; leaving the default hands it to the loop. Three permissive defaults became four, and the two that are genuinely cautious are now named as such rather than implied. Also adds the workspace module to the README's public-surface table. WorkspaceDescriptor and SandboxMode were exported when that module landed, but the table predates it. Co-authored-by: Medulla --- README.md | 1 + crates/tinytools/src/tool/types.rs | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 42438cf..9481c6d 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ compiles neither the harness nor the host. | `classification` | `ToolScope`, `ToolCategory` — where a tool may run, and which belt it is on | | `call` | `ToolCallOptions`, `ToolTimeout` — per-invocation inputs that are not arguments | | `context` | `ToolRunContext` — the narrow seam onto a live run | +| `workspace` | `WorkspaceDescriptor`, `SandboxMode` — the root a tool may touch, and how strictly it is sandboxed | | `naming` | `humanize_tool_name`, `context_detail_from_args` — rendering a call for a human | ## What is deliberately not here diff --git a/crates/tinytools/src/tool/types.rs b/crates/tinytools/src/tool/types.rs index ba93e6f..d8e6c46 100644 --- a/crates/tinytools/src/tool/types.rs +++ b/crates/tinytools/src/tool/types.rs @@ -25,11 +25,12 @@ use crate::spec::ToolSpec; /// That split is the point. A tool never enforces policy on itself — it /// describes itself accurately and the host enforces. /// -/// # The defaults are not uniformly safe, and two of them fail OPEN +/// # The defaults are not uniformly safe — four of them are permissive /// -/// Most defaults are the cautious answer — [`Self::scope`] is `All`, -/// [`Self::is_concurrency_safe`] is `false`, [`Self::timeout_policy`] inherits -/// the host's bound. Three are not, and a tool author who assumes otherwise +/// Two defaults are genuinely cautious: [`Self::is_concurrency_safe`] is +/// `false`, so nothing is dispatched in parallel unless a tool says it is safe, +/// and [`Self::timeout_policy`] inherits the host's bound rather than opting +/// out of it. **Four are permissive**, and a tool author who assumes otherwise /// ships a hole: /// /// - **[`Self::external_effect`] defaults to `false`.** A tool that sends an @@ -45,8 +46,12 @@ use crate::spec::ToolSpec; /// - **[`Self::permission_level`] defaults to /// [`PermissionLevel::ReadOnly`]**, not [`PermissionLevel::None`], because /// most tools genuinely read — but a writing tool must say so. +/// - **[`Self::scope`] defaults to [`ToolScope::All`]**, the *widest* setting: +/// the tool is offered to the autonomous agent loop, the CLI and RPC alike. A +/// tool that should only ever be driven deliberately by a human has to say +/// [`ToolScope::CliRpcOnly`]; leaving the default hands it to the loop. /// -/// If you are reviewing a `Tool` impl, those three are what to check for +/// If you are reviewing a `Tool` impl, those four are what to check for /// absence. The rest are safe to leave alone. #[async_trait] pub trait Tool: Send + Sync {