SC-5 Plugin + marketplace + MCP swap (single source of truth in DB) #627
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks#627
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
User story
As a platform engineer, I want
agent-env-sync.renderForInstanceto be the only writer ofenabledPlugins,extraKnownMarketplaces, andmcpServerskeys in each per-agent env dir, so that agent-type and per-instance overrides land coherently andagents.json::plugins+ the per-env.claude.json/settings.jsonstop being mutable surfaces.Acceptance criteria
Renderer is the only writer
renderForInstance(SC-2) is the only code path that writessettings.json::enabledPlugins,settings.json::extraKnownMarketplaces, and.claude.json::mcpServers. Existing writers (e.g. one-shot bootstrap calls inagent-env-syncandcontainers-rebuild) delegate to it.agents.json::types[].plugins[]becomes a builtin-only input.builtin-syncreads it and writes oneplugin_bindingrow per(type, plugin)pair underscope = 'builtin'.config/mcp-builtin.jsonis read bybuiltin-syncand producesmcp_serverrows.config/marketplaces-builtin.jsonproducesplugin_marketplacerows.Container rebuild integration
just containers-rebuild [NAME]triggers arenderForInstancefor every affected instance after the rebuild, so the new container boots with up-to-date plugin / marketplace / MCP state.container-reconcile.tslearns to delegate drift recovery torenderForInstanceinstead of mutatingsettings.jsondirectly.Secret refs
envrows can carry${SECRET:NAME}placeholders.renderForInstanceresolves them via the secrets table (SC-6) and writes plaintext only to the rendered.claude.jsonon disk.MissingSecretErrorper SC-2's error contract.Tests
instance-scopeplugin_bindingrow enabling a plugin not on the type appears in the instance's renderedenabledPlugins.instance-scopeplugin_bindingwithenabled = falseremoves a plugin that the type enables.mcp_serverrow withenv = { "FORGEJO_TOKEN": "${SECRET:FORGEJO_TOKEN_DEV}" }resolves to the decrypted token at render time.just containers-rebuild dev-defaultproduces a freshly-rendered env dir.Out of scope
References
specs/agent-config-customization.md§Story SC-5apps/server/src/infrastructure/agent-env-sync/— current materialiserapps/server/src/infrastructure/container/container-reconcile.tsandcontainer-watchdog.ts~/.config/claude-hooks/agent-env/<agent>/settings.jsonand.claude.json— the rendered files