From 481a913ed7bfc6b4712620ef526a79a98db56597 Mon Sep 17 00:00:00 2001 From: Ollie Agent Date: Wed, 29 Jul 2026 00:36:24 +0200 Subject: [PATCH] note that both shell AND promoted tools are sandboxed --- README.md | 2 +- doc/OBSERVATIONS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 51a891a..d346e59 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Monorepo with Git submodules. Each submodule has its own Go module (except `el` ### Tools and sandboxing -- **Sandboxed execution** — every tool call runs inside a Landlock sandbox with per-profile filesystem access rules +- **Sandboxed execution** — every tool call and every `shell` command runs inside a Landlock sandbox with per-profile filesystem access rules. Promoted tools are not exempt — they execute through the same sandbox path as inline shell commands. - **Extensible tools** — tools are executable scripts with header metadata; add one by dropping a file in a directory - **Lazy-loading tool registry** — all tools are discoverable; only loaded tools are callable. Write a tool name to `s/{sid}/tools` to promote it to a native callable function — no MCP server, no SDK, no protocol boilerplate - **Elevation** — commands that need to escape the sandbox can request elevation through a streaming protocol (frame-based, over unix socket) diff --git a/doc/OBSERVATIONS.md b/doc/OBSERVATIONS.md index 1bed306..b13fc84 100644 --- a/doc/OBSERVATIONS.md +++ b/doc/OBSERVATIONS.md @@ -8,6 +8,8 @@ **Lazy tool loading** — After transitioning from `execute_code`/`call_tool`/`pipe` to a unified `shell` primitive, ollie adopted a lazy loading architecture. The system has 7 primitives: `shell` (sandboxed), `tool_load`/`tool_list`/`tool_active`, `skill_load`/`skill_list`/`skill_active`, plus associated 9P filesystem endpoints. Tools are executable scripts discovered from `OLLIE_TOOLS_PATH`; skills are `SKILL.md` directories discovered from `OLLIE_SKILLS_PATH`. Both use session-scoped registries with per-session load tracking. The agent autonomously loads tools and skills as needed — no explicit user permission required. +**Both shell and tools are sandboxed** — Promoted tools are not exempt from sandboxing. They execute through the same `executeWithStdin` path as inline `shell` commands, running inside a Landlock sandbox with the same per-profile filesystem access rules. The sandbox applies to every code path that touches user data — there is no bypass by loading a tool. + **Error rates significantly improved after the facade layer** — The original architecture exposed `execute_code`/`call_tool`/`pipe` as the only primitives. Larger models with strong reasoning handled this well. Smaller and cheaper models consistently failed: wrong tool names, incorrect argument formats, confused execution modes, ignoring named tool scripts in favour of reimplementing them inline. The facade layer — `tool_load`, `tool_list`, `tool_active` — promotes a tool script to a first-class callable function with a JSON schema. Error rates dropped dramatically because the model no longer needs to construct the correct invocation string; it calls a native function with typed arguments. The tool scripts themselves are unchanged — they are still executable files on disk. The facade is purely a contract layer between the agent and the tool ecosystem. This preserves the simplicity of a small core while supporting a rich ecosystem of specialized capabilities, and it costs nothing for models that already reasoned well through the abstraction. **Parallel execution** — `execute_code` accepts a `steps` array of pipeline stages. A `{parallel: [...]}` stage fans out concurrently within the pipeline. Sequential stages chain stdout → stdin. All stages accept inline code and named tool scripts interchangeably.