feat(agent-config): AOI-1 drop instance-scope disable for plugins and MCP #742

Merged
charles merged 1 commit from code-lead/730 into main 2026-05-02 12:42:49 +00:00
Collaborator

Make the type-level capability surface (plugins, MCP servers) a non-negotiable contract: instances cannot disable inherited entries with enabled=false. Resolver drops instance-scope enabled=false rows; write path returns 400 with the prescribed message; migration 003 rebuilds plugin_binding/mcp_server with CHECK constraints and coalesces AOI-5's prune.

Test plan

  • Resolver unit tests for plugin + MCP shadow rule and additive instance-scope rows
  • HTTP test asserts POST enabled=false at instance scope returns 400 with the exact error message
  • renderForInstance test updated to verify the CHECK rejects the legacy shadow attempt while the type baseline survives
  • Existing bun x turbo run test (3074 tests) green

Closes #730

Make the type-level capability surface (plugins, MCP servers) a non-negotiable contract: instances cannot disable inherited entries with `enabled=false`. Resolver drops instance-scope `enabled=false` rows; write path returns 400 with the prescribed message; migration 003 rebuilds `plugin_binding`/`mcp_server` with CHECK constraints and coalesces AOI-5's prune. ## Test plan - Resolver unit tests for plugin + MCP shadow rule and additive instance-scope rows - HTTP test asserts POST `enabled=false` at instance scope returns 400 with the exact error message - `renderForInstance` test updated to verify the CHECK rejects the legacy shadow attempt while the type baseline survives - Existing `bun x turbo run test` (3074 tests) green Closes #730
feat(agent-config): AOI-1 drop instance-scope disable for plugins and MCP
All checks were successful
qa / dockerfile (pull_request) Successful in 7s
qa / qa (pull_request) Successful in 2m52s
c6f355cc84
Make the type-level capability surface (plugins, MCP servers) a
non-negotiable contract — instances cannot silently break the role
baseline by shadowing inherited entries with `enabled=false`.

- Resolver: `resolvePlugins` + `resolveMcpServers` ignore rows where
  `scope='instance' AND enabled=false`, so legacy rows during the
  migration window cannot win the layer-merge.
- Write path: `upsertRow` throws `AddOnlyInheritanceError` for the
  same shape, with the prescribed per-artifact message; PUT/fork/restore
  return 400.
- Migration 003: rebuilds `plugin_binding` and `mcp_server` with
  `CHECK (NOT (scope='instance' AND enabled=0))` constraints, coalescing
  AOI-5's prune by skipping stale rows during the copy.

Closes #730

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
reviewer approved these changes 2026-05-02 12:10:25 +00:00
reviewer left a comment

Three-layer enforcement (write-path → SQL CHECK → resolver filter) is correct and complete. All AC met: resolver ignores scope=instance AND enabled=false for both plugins and MCP; assertAddOnlyInheritance blocks the write at every entry point (PUT/fork/restore); migration 003 is idempotent and coalesces AOI-5. CI green.

Three-layer enforcement (write-path → SQL CHECK → resolver filter) is correct and complete. All AC met: resolver ignores `scope=instance AND enabled=false` for both plugins and MCP; `assertAddOnlyInheritance` blocks the write at every entry point (PUT/fork/restore); migration 003 is idempotent and coalesces AOI-5. CI green.
charles deleted branch code-lead/730 2026-05-02 12:42:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks!742
No description provided.