Following up on your review of #2621 — first, thank you. I'm genuinely impressed by the depth and care of the review; the trust and seriousness you extended to a contributor's PR is not something I take for granted. You caught a real mismatch between #2195's intent and my implementation, and you're right about it.
Before I implement it, I want to check one product-level decision with you, because you've thought about this project far longer than I have, and I don't want to make this call unilaterally.
My position: ship least-privilege as the default — but I want to talk it through
I'm convinced the right end state is: workers run naked — no MCP, no plugins — unless the user explicitly opts them in. A worker should just do the work it's given; it should not inherit the orchestrator's keys to the safe. That's the principle behind #2195's "workers default to none, opt in explicitly," and you're holding me to it in the review, correctly.
The mechanism exists, so the code is not the blocker:
- MCP isolation:
--strict-mcp-config with no --mcp-config loads zero MCP servers (verified against claude --help and the CLI reference). MCPConfig{Strict: true, Configs: []} already validates and is tested.
- Plugin isolation:
--settings '{"enabledPlugins": {...all false...}}' disables plugins per-session without --bare/--safe-mode (which would also kill AO's hooks). Verified: claude --settings '{"enabledPlugins": {"context7@claude-plugins-official": false}}' plugin list shows Status: ✘ disabled. So plugin least-privilege is achievable too, without breaking AO.
So I'm ready to ship lockdown-by-default.
The one thing giving me pause
The only reason I'm raising this instead of just shipping it: flipping the default silently changes behavior for every existing project. A worker that quietly used a filesystem MCP tool or a plugin now runs half-blind until the user configures worker.mcp.configs / a plugin allowlist — and the user finds out from a failed tool call, not from AO. With ~8k users on the project, that's a lot of quiet breakage delivered in a PR that advertises itself as "add per-role config."
That's not enough to change my mind on the direction — I still think naked-by-default is correct. But it's enough that I want to hear yours before I land it, because there are a few rollout shapes and you'll know which fits the project:
- Naked-by-default for everyone + a loud changelog/migration note. Cleanest end state, sharpest transition.
- Naked-by-default, but only for newly-created projects — existing projects keep inherit until they migrate. Gentler; more surface.
- Naked as an opt-in now (e.g. a per-project lockdown flag, default off), default flips to naked in a later major version. Slowest; least surprise.
I'd vote (1) or (2). But you have the longer view on the project and its users, so: which rollout do you want? Once you pick, I'll implement it in the split per-issue PRs (the combined PR is being split per your one-issue-per-PR point — #2195 backend config, #2230 desktop keep-alive), reference this issue there, and ship the isolation however you decide here.
Tagging you because you're already the reviewer on #2621 and this is the one judgment call in the review I didn't want to make alone.
Following up on your review of #2621 — first, thank you. I'm genuinely impressed by the depth and care of the review; the trust and seriousness you extended to a contributor's PR is not something I take for granted. You caught a real mismatch between #2195's intent and my implementation, and you're right about it.
Before I implement it, I want to check one product-level decision with you, because you've thought about this project far longer than I have, and I don't want to make this call unilaterally.
My position: ship least-privilege as the default — but I want to talk it through
I'm convinced the right end state is: workers run naked — no MCP, no plugins — unless the user explicitly opts them in. A worker should just do the work it's given; it should not inherit the orchestrator's keys to the safe. That's the principle behind #2195's "workers default to none, opt in explicitly," and you're holding me to it in the review, correctly.
The mechanism exists, so the code is not the blocker:
--strict-mcp-configwith no--mcp-configloads zero MCP servers (verified againstclaude --helpand the CLI reference).MCPConfig{Strict: true, Configs: []}already validates and is tested.--settings '{"enabledPlugins": {...all false...}}'disables plugins per-session without--bare/--safe-mode(which would also kill AO's hooks). Verified:claude --settings '{"enabledPlugins": {"context7@claude-plugins-official": false}}' plugin listshowsStatus: ✘ disabled. So plugin least-privilege is achievable too, without breaking AO.So I'm ready to ship lockdown-by-default.
The one thing giving me pause
The only reason I'm raising this instead of just shipping it: flipping the default silently changes behavior for every existing project. A worker that quietly used a filesystem MCP tool or a plugin now runs half-blind until the user configures
worker.mcp.configs/ a plugin allowlist — and the user finds out from a failed tool call, not from AO. With ~8k users on the project, that's a lot of quiet breakage delivered in a PR that advertises itself as "add per-role config."That's not enough to change my mind on the direction — I still think naked-by-default is correct. But it's enough that I want to hear yours before I land it, because there are a few rollout shapes and you'll know which fits the project:
I'd vote (1) or (2). But you have the longer view on the project and its users, so: which rollout do you want? Once you pick, I'll implement it in the split per-issue PRs (the combined PR is being split per your one-issue-per-PR point — #2195 backend config, #2230 desktop keep-alive), reference this issue there, and ship the isolation however you decide here.
Tagging you because you're already the reviewer on #2621 and this is the one judgment call in the review I didn't want to make alone.