40 lines
979 B
Markdown
40 lines
979 B
Markdown
|
|
# TICKET-203: Implement ToolPermissionContext
|
||
|
|
|
||
|
|
**Epic:** EPIC-202
|
||
|
|
**Priority:** P0
|
||
|
|
**Status:** Ready
|
||
|
|
**Assignee:** Allegro
|
||
|
|
**Estimate:** 4 hours
|
||
|
|
|
||
|
|
## Description
|
||
|
|
|
||
|
|
Implement the ToolPermissionContext pattern from Claw Code for fine-grained tool access control.
|
||
|
|
|
||
|
|
## Acceptance Criteria
|
||
|
|
|
||
|
|
- [ ] `ToolPermissionContext` dataclass created
|
||
|
|
- [ ] `deny_tools: set[str]` field
|
||
|
|
- [ ] `deny_prefixes: tuple[str, ...]` field
|
||
|
|
- [ ] `blocks(tool_name: str) -> bool` method
|
||
|
|
- [ ] Integration with Hermes tool registry
|
||
|
|
- [ ] Tests pass
|
||
|
|
|
||
|
|
## Implementation Notes
|
||
|
|
|
||
|
|
```python
|
||
|
|
@dataclass(frozen=True)
|
||
|
|
class ToolPermissionContext:
|
||
|
|
deny_tools: set[str] = field(default_factory=set)
|
||
|
|
deny_prefixes: tuple[str, ...] = ()
|
||
|
|
|
||
|
|
def blocks(self, tool_name: str) -> bool:
|
||
|
|
if tool_name in self.deny_tools:
|
||
|
|
return True
|
||
|
|
return any(tool_name.startswith(p) for p in self.deny_prefixes)
|
||
|
|
```
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- Claw: `src/permissions.py`
|
||
|
|
- Hermes: `tools/registry.py`
|