pando-ai 0.6.5 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,13 +6,16 @@ normally while Pando applies local policy on each launch.
6
6
 
7
7
  Its jobs:
8
8
 
9
- 1. **Constrain tool use** — install the project-scoped Pando MCP server, deny
9
+ 1. **Constrain tool use** — install project-scoped Pando MCP servers, deny
10
10
  native tools where supported, and deny non-Pando MCP tools by default.
11
11
  2. **Inspect tool traffic** — use Claude Code hooks on every Claude launch and
12
12
  a local provider gateway where available to block off-policy tool calls and
13
13
  tool results.
14
14
  3. **Keep code local by default** — run indexing, search, snapshots, and edits
15
15
  locally; optional working-set memory is off unless explicitly enabled.
16
+ 4. **Prefer semantic operations** — give agents structured code tools for
17
+ search, references, renames, edits, snapshots, and shell execution instead of
18
+ making raw shell access the default control surface.
16
19
 
17
20
  It is built on the same indexing + MCP engine as the Pandō VS Code extension.
18
21
 
@@ -35,21 +38,22 @@ from `npx`. After installation you keep running `codex` and `claude` normally
35
38
 
36
39
  ## How it works
37
40
 
38
- Two choke points, one ruleset:
41
+ Four layers, one ruleset:
39
42
 
40
43
  - **Launch shim** (`~/.pando/bin` ahead of the real tools on PATH) — supervises
41
44
  every `codex`/`claude` invocation. It disables the agent's native tools where
42
- supported, dynamically injects the Pando MCP server (root-scoped to your
43
- project), and applies the MCP allow/deny policy via the agent's own launch
44
- flags. Pando does not permanently add itself to the user's MCP config files by
45
- default; supervised launches pass generated config on each run.
45
+ supported, dynamically injects root-scoped Pando MCP servers, and applies the
46
+ MCP allow/deny policy via the agent's own launch flags. Pando does not
47
+ permanently add itself to the user's MCP config files by default; supervised
48
+ launches pass generated config on each run.
46
49
  - **Wire gateway** (a local reverse proxy speaking the OpenAI Responses API and
47
50
  Anthropic Messages API) — sits inline on every supported request and forwards
48
- it to the upstream you control, so traffic stays local. It blocks off-policy
49
- tool definitions, tool calls, and tool results before they can cross the
50
- provider boundary, and blocks off-policy tool calls on model responses before
51
- the agent can execute them. When enabled, it runs the protocol-adapted
52
- working-set memory engine ported from `pando-proxy`.
51
+ it to the upstream you control. Policy enforcement happens locally before a
52
+ request is forwarded and before a model response reaches the agent. It blocks
53
+ off-policy tool definitions, tool calls, and tool results before they can
54
+ cross the provider boundary, and blocks off-policy tool calls on model
55
+ responses before the agent can execute them. When enabled, it runs the
56
+ protocol-adapted working-set memory engine ported from `pando-proxy`.
53
57
  - **Memory manager** (`PANDO_GATEWAY_MEMORY=1`, off by default) — maintains a
54
58
  per-session working set and archive recall path. The memory core is separate
55
59
  from policy enforcement: policy decides which tools are allowed; memory
@@ -61,6 +65,77 @@ Two choke points, one ruleset:
61
65
  are denied; Pando MCP is always allowed. See `[native_tools]`, `[other_mcp]`,
62
66
  `[proxy]`, `[firewall]`.
63
67
 
68
+ ## Security model
69
+
70
+ Pando's security model has three separate jobs:
71
+
72
+ - **Containment**: the `pando_workspace` MCP process runs model-triggered
73
+ workspace mutation in an OS sandbox. The sandbox limits the process to the
74
+ project root, sandbox-local home/cache/temp directories, and no network by
75
+ default. This is the hard boundary for broad operations such as shell
76
+ commands and generated code.
77
+ - **Audit and recovery**: mutating Pando tools and `shell-command` create Pando
78
+ snapshots around workspace changes. These are local, commit-like history
79
+ records for inspection and restore; they are not commits to the user's Git
80
+ repository.
81
+ - **Semantic control**: Pando tools give the agent structured operations such as
82
+ `find-nodes`, `find-references`, `rename`, `replace`, `insert`,
83
+ `filter-map-reduce`, `snapshot-worktree`, and `restore-files`. These tools
84
+ keep requests bounded, make intent inspectable, require stable paths/hashes
85
+ where relevant, and reduce the need for raw shell/file access.
86
+
87
+ The sandbox and snapshots are the fallback safety boundary. The Pando tools are
88
+ the preferred control plane: they make ordinary coding work narrower, more
89
+ auditable, and more semantically meaningful than arbitrary command execution.
90
+ Shell remains available for tests, builds, package managers, generated files,
91
+ unsupported languages, and tasks where a structured Pando operation is not the
92
+ right tool.
93
+
94
+ ### Workspace sandbox and privileged helper
95
+
96
+ Supervised launches split Pando into two MCP roles:
97
+
98
+ - `pando_core` runs trusted read/search/planning/index operations.
99
+ - `pando_workspace` runs model-triggered workspace mutation and shell commands.
100
+
101
+ The workspace role re-execs into the OS sandbox before serving mutating tools.
102
+ On macOS this uses Seatbelt; on Linux it uses bubblewrap. The sandbox is
103
+ configured to allow the project root, sandbox-local home/cache/temp directories,
104
+ and the minimal runtime/toolchain paths needed to start common commands. Network
105
+ is denied by default. There is no silent unsandboxed fallback for workspace
106
+ mutation.
107
+
108
+ Install-time security setup also provisions dedicated local users
109
+ (`pando-workspace` and `pando-core`) and a root-owned helper daemon. The helper
110
+ is intentionally narrow: it can only launch Pando's known roles for validated
111
+ project roots over stdio. It is not a general command runner and does not accept
112
+ custom argv, shells, or arbitrary commands.
113
+
114
+ The helper entrypoint is:
115
+
116
+ ```bash
117
+ pando-ai security launch --role <core|workspace> --project-root <path> --stdio
118
+ ```
119
+
120
+ The unprivileged CLI validates the request, connects to the local helper socket,
121
+ and sends only the fixed launch request. The root-owned daemon validates again,
122
+ selects the role's dedicated user when privilege is available, starts the fixed
123
+ Pando MCP server invocation, and lets the normal workspace sandbox apply before
124
+ mutating tools are served.
125
+
126
+ Security setup is normally invoked by install/uninstall, but can be run
127
+ directly:
128
+
129
+ ```bash
130
+ pando-ai security setup-users
131
+ ```
132
+
133
+ Diagnostics use the same JSONL log as the gateway and installer:
134
+ `~/.pando-data/gateway-debug.jsonl` by default, or `PANDO_GATEWAY_LOG_FILE` when
135
+ set. Logging is on by default and can be forced with `PANDO_DEBUG=1`; set
136
+ `PANDO_DEBUG=0` to disable default helper logging. Useful event prefixes include
137
+ `security_helper_client_*` and `security_helper_daemon_*`.
138
+
64
139
  ### Supported model APIs
65
140
 
66
141
  The gateway supports the current agent-facing APIs used by the supervised
@@ -77,20 +152,21 @@ Legacy completion APIs, including OpenAI chat/completions and Anthropic
77
152
  | Capability | Claude Code | Codex |
78
153
  | --- | --- | --- |
79
154
  | Disable native tools | ✅ `--tools ""` (MCP stays available) + gateway/hook block | ⚠️ read-only sandbox + web search disabled + request/response gateway block |
80
- | Install Pando MCP, root-scoped | ✅ dynamic `--mcp-config` + `--strict-mcp-config` | ✅ dynamic required `-c mcp_servers.pando.*` with Pando tools pre-approved |
81
- | `other_mcp: deny_all` | ✅ `--strict-mcp-config` (Pando only), Claude project built-ins disabled, gateway/hook block | ✅ request/response gateway block |
155
+ | Install Pando MCP, root-scoped | ✅ dynamic `--mcp-config` + `--strict-mcp-config` | ✅ dynamic required `pando_core` / `pando_workspace` MCP config with Pando tools pre-approved |
156
+ | `other_mcp: deny_all` | ✅ `--strict-mcp-config` with generated Pando-only config + gateway/hook block | ✅ request/response gateway block |
82
157
  | `other_mcp: allow_list` | ✅ strict config with Pando + named servers + gateway/hook block | ✅ request/response gateway block |
83
158
  | `other_mcp: deny_list` | ✅ `--disallowedTools` removes denied names + gateway/hook block | ✅ request/response gateway block |
84
159
  | Route traffic through local gateway | ✅ API-key/token/helper auth via `ANTHROPIC_BASE_URL`; hooks are always on | ✅ provider override |
85
160
 
86
161
  - **Codex** has no documented strict-MCP switch and no exact `--tools ""`
87
162
  equivalent, so launch-time stripping is best-effort. Pando marks its MCP
88
- server required, sets `default_tools_approval_mode="approve"` for Pando's own
89
- MCP tools so non-interactive Codex launches can use them, disables Codex web
90
- search when native tools are denied, strips off-policy tool definitions from
91
- `/v1/responses` requests, blocks provider-bound off-policy tool call/result
92
- transcript items before they reach the model provider, and blocks off-policy
93
- tool calls in model responses before Codex can execute them.
163
+ servers required, sets `default_tools_approval_mode="approve"` for Pando's
164
+ own MCP tools so non-interactive Codex launches can use them, disables Codex
165
+ web search when native tools are denied, strips off-policy tool definitions
166
+ from `/v1/responses` requests, strips historical off-policy tool call/result
167
+ transcript items from resumed requests before they reach the model provider,
168
+ and blocks new off-policy tool calls in model responses before Codex can
169
+ execute them.
94
170
  - **Claude Code** always gets Pando hook settings for tool-call/tool-result
95
171
  enforcement. API-key, auth-token, or Claude Code `apiKeyHelper` auth also
96
172
  enables gateway mode through `ANTHROPIC_BASE_URL`. Subscription-only launches
@@ -100,16 +176,18 @@ Legacy completion APIs, including OpenAI chat/completions and Anthropic
100
176
  native tools, MCP config, plugins, custom settings, IDE attachment, or bypass
101
177
  permissions (`--tools`, `--mcp-config`, `--settings`, `--plugin-dir`,
102
178
  `--permission-mode`, `--allowedTools`, dangerous permission/channel flags,
103
- and related aliases). Pando also sets `ENABLE_CLAUDEAI_MCP_SERVERS=false`,
104
- injects `--disable-slash-commands` when supported, and injects `--bare` /
105
- `--no-chrome` on Claude builds that expose those flags. If Claude settings
106
- set `disableAllHooks=true`, Pando refuses to launch Claude because hooks are
107
- required for subscription-mode enforcement.
179
+ and related aliases). Pando also sets `ENABLE_CLAUDEAI_MCP_SERVERS=false`
180
+ and injects `--no-chrome` on Claude builds that expose it. Pando intentionally
181
+ does not pass `--bare`, because it can force API-key billing paths and skip
182
+ hooks on some Claude builds. Slash commands/skills are left enabled for now;
183
+ tool execution is constrained through `--tools ""`, strict MCP config, hooks,
184
+ and the gateway. If Claude settings set `disableAllHooks=true`, Pando refuses
185
+ to launch Claude because hooks are required for subscription-mode enforcement.
108
186
  - **Claude Code built-in/project MCP state** is stricter than normal Claude
109
- config. When policy blocks non-Pando MCP servers, Pando disables matching
110
- project-level Claude MCP entries such as `computer-use` in `~/.claude.json`
111
- and removes stale Pando-owned top-level MCP entries. Generated Pando MCP
112
- config is still passed dynamically on each supervised launch.
187
+ config. When policy blocks non-Pando MCP servers, Pando launches Claude with
188
+ strict generated MCP config containing only allowed servers. Generated Pando
189
+ MCP config is passed dynamically on each supervised launch, and Pando leaves
190
+ the user's on-disk Claude MCP config untouched by default.
113
191
  - **Claude Desktop general chat**: not part of the strong-enforcement claim;
114
192
  transparent interception is not reliable there without app-level controls.
115
193
 
@@ -207,6 +285,8 @@ pando-ai serve [path] # stdio MCP server for MCP clients
207
285
  pando-ai serve-http # explicit HTTP MCP server for debugging/integrations
208
286
  pando-ai gateway # run the firewall gateway in the foreground (debug)
209
287
  pando-ai proxy status|enable|disable [codex|claude]
288
+ pando-ai security setup-users
289
+ pando-ai security launch --role <core|workspace> --project-root <path> --stdio
210
290
  pando-ai login|logout|whoami
211
291
  pando-ai config set telemetry false
212
292
  ```
@@ -242,6 +322,35 @@ Use stdio MCP for agents:
242
322
  pando-ai serve /path/to/project
243
323
  ```
244
324
 
325
+ Supervised Codex and Claude launches register two Pando MCP server entries for
326
+ the same project:
327
+
328
+ - `pando_core` exposes read, search, indexing, graph, planning, and snapshot
329
+ inspection tools.
330
+ - `pando_workspace` exposes workspace-mutating tools such as rename, replace,
331
+ insert, delete, signature changes, filter-map-reduce, shell execution,
332
+ restore operations, and exclude-dir changes.
333
+
334
+ The split is process-level. Each server process starts with a
335
+ `PANDO_PROCESS_ROLE` value, and tools outside that role are not registered. A
336
+ manual `pando-ai serve /path/to/project` command without `PANDO_PROCESS_ROLE`
337
+ starts a combined server for direct integrations; supervised Codex and Claude
338
+ launches use the split servers.
339
+
340
+ The `pando_workspace` process re-execs into a local workspace sandbox by
341
+ default. In that sandbox:
342
+
343
+ - `HOME`, temp, and package-manager cache paths point under `.pando-sandbox/`.
344
+ - Network is denied by default.
345
+ - The process can read and write the project root.
346
+ - Pando workspace data created by the sandboxed process stays sandbox-local.
347
+
348
+ Auth is handled separately from the sandbox home. The launcher passes the user's
349
+ real auth home through `PANDO_AUTH_HOME_OVERRIDE`, so the sandboxed workspace
350
+ process can read the existing `~/.pando-ai/session.json` without making the
351
+ real home its writable `HOME` and without opening network login inside the
352
+ sandbox.
353
+
245
354
  `serve-http` remains available as an explicit command for debugging or
246
355
  integrations that need HTTP:
247
356
 
@@ -293,10 +402,13 @@ The CLI does not send source code, file paths, file names, or symbol names.
293
402
 
294
403
  ## Support level
295
404
 
296
- - TypeScript / JavaScript / Clojure: supported in the standalone CLI distribution
297
- - Python / Java / C# / Dart / C / C++: not included in the standalone CLI distribution
405
+ - TypeScript / JavaScript / Clojure / C# / C / C++: included in the standalone
406
+ CLI distribution.
407
+ - Python / Java / Dart: adapters exist in the source tree, but their helper
408
+ assets are not included in the published npm package yet.
298
409
 
299
410
  ## Notes
300
411
 
301
412
  - Some host-only extension tools are intentionally omitted from the CLI in V1.
302
- - If non-TS helpers are missing, the CLI should degrade with clear tool-level errors instead of failing startup.
413
+ - If a language helper is missing, the CLI should degrade with clear tool-level
414
+ errors instead of failing startup.