Background
PR #13 introduced three plugin capability tiers — read-only, state-only, full — enforced via scoped registry wrappers in src/deckhand/plugins/capabilities.py.
The reviewer on PR #13 noted that ScopedActionRegistry.run() only denies the read-only tier, which means a state-only plugin can invoke arbitrary registered actions (including agent.start, agent.cancel, agent.input). Since actions are the primary lever for orchestrator commands, this arguably contradicts the intent of withholding orchestrator access from state-only plugins.
Investigate
- Decide what
state-only is actually meant to allow. Two reasonable interpretations:
state-only = read state + write state + register signals, no action invocation. Tighten ScopedActionRegistry.run to also deny state-only.
state-only = above + may invoke actions registered by other (full) plugins, since orchestrator access is already mediated through the action layer. Document this explicitly.
- Whichever way it goes, update the docstring at the top of
capabilities.py so the tier semantics are unambiguous.
- Add a test that pins the chosen behavior.
Why
The capability tiers are a security boundary. Any ambiguity about what each tier permits will erode trust in the model and make plugin reviews harder.
Background
PR #13 introduced three plugin capability tiers —
read-only,state-only,full— enforced via scoped registry wrappers in src/deckhand/plugins/capabilities.py.The reviewer on PR #13 noted that
ScopedActionRegistry.run()only denies theread-onlytier, which means astate-onlyplugin can invoke arbitrary registered actions (includingagent.start,agent.cancel,agent.input). Since actions are the primary lever for orchestrator commands, this arguably contradicts the intent of withholding orchestrator access fromstate-onlyplugins.Investigate
state-onlyis actually meant to allow. Two reasonable interpretations:state-only= read state + write state + register signals, no action invocation. TightenScopedActionRegistry.runto also denystate-only.state-only= above + may invoke actions registered by other (full) plugins, since orchestrator access is already mediated through the action layer. Document this explicitly.capabilities.pyso the tier semantics are unambiguous.Why
The capability tiers are a security boundary. Any ambiguity about what each tier permits will erode trust in the model and make plugin reviews harder.