docs: Add EPIC-202 and tickets for Claw-based agent build
- EPIC-202: Build Claw-Architecture Agent - TICKET-203: ToolPermissionContext - TICKET-204: ExecutionRegistry - TICKET-205: Session Persistence Replaces idle Allegro-Primus with real work capability.
This commit is contained in:
138
epics/EPIC-202-claw-agent.md
Normal file
138
epics/EPIC-202-claw-agent.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# EPIC-202: Build Claw-Architecture Agent
|
||||
|
||||
**Status:** In Progress
|
||||
**Priority:** P0
|
||||
**Milestone:** M1: Core Architecture
|
||||
**Created:** 2026-03-31
|
||||
**Author:** Allegro
|
||||
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Create a NEW autonomous agent using architectural patterns from [Claw Code](http://143.198.27.163:3000/Timmy/claw-code), integrated with Gitea for real work dispatch.
|
||||
|
||||
## Problem Statement
|
||||
|
||||
**Allegro-Primus is IDLE.**
|
||||
- Gateway running (PID 367883) but zero meaningful output
|
||||
- No Gitea issues created
|
||||
- No PRs submitted
|
||||
- No actual work completed
|
||||
|
||||
This agent will **replace** Allegro-Primus with real capabilities.
|
||||
|
||||
---
|
||||
|
||||
## Claw Patterns to Adopt
|
||||
|
||||
### 1. ToolPermissionContext
|
||||
```python
|
||||
@dataclass
|
||||
class ToolPermissionContext:
|
||||
deny_tools: set[str]
|
||||
deny_prefixes: tuple[str, ...]
|
||||
|
||||
def blocks(self, tool_name: str) -> bool:
|
||||
return tool_name in self.deny_tools or \
|
||||
any(tool_name.startswith(p) for p in self.deny_prefixes)
|
||||
```
|
||||
|
||||
**Why:** Fine-grained tool access control vs Hermes basic approval
|
||||
|
||||
### 2. ExecutionRegistry
|
||||
```python
|
||||
class ExecutionRegistry:
|
||||
def command(self, name: str) -> CommandHandler
|
||||
def tool(self, name: str) -> ToolHandler
|
||||
def execute(self, context: PermissionContext) -> Result
|
||||
```
|
||||
|
||||
**Why:** Clean routing vs Hermes model-decided routing
|
||||
|
||||
### 3. Session Persistence
|
||||
```python
|
||||
@dataclass
|
||||
class RuntimeSession:
|
||||
prompt: str
|
||||
context: PortContext
|
||||
history: HistoryLog
|
||||
persisted_path: str
|
||||
```
|
||||
|
||||
**Why:** JSON-based sessions vs SQLite - more portable, inspectable
|
||||
|
||||
### 4. Bootstrap Graph
|
||||
```python
|
||||
def build_bootstrap_graph() -> Graph:
|
||||
# Setup phases
|
||||
# Context building
|
||||
# System init messages
|
||||
```
|
||||
|
||||
**Why:** Structured initialization vs ad-hoc setup
|
||||
|
||||
---
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Core Architecture (2 days)
|
||||
- [ ] Create new Hermes profile: `claw-agent`
|
||||
- [ ] Implement ToolPermissionContext
|
||||
- [ ] Create ExecutionRegistry
|
||||
- [ ] Build Session persistence layer
|
||||
|
||||
### Phase 2: Gitea Integration (2 days)
|
||||
- [ ] Gitea client with issue querying
|
||||
- [ ] Work scheduler for autonomous cycles
|
||||
- [ ] PR creation and review assistance
|
||||
|
||||
### Phase 3: Deployment (1 day)
|
||||
- [ ] Telegram bot integration
|
||||
- [ ] Cron scheduling
|
||||
- [ ] Health monitoring
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
| Criteria | How We'll Verify |
|
||||
|----------|-----------------|
|
||||
| Receives Telegram tasks | Send test message, agent responds |
|
||||
| Queries Gitea issues | Agent lists open P0 issues |
|
||||
| Permission checks work | Blocked tool returns error |
|
||||
| Session persistence | Restart agent, history intact |
|
||||
| Progress reports | Agent sends Telegram updates |
|
||||
|
||||
---
|
||||
|
||||
## Resource Requirements
|
||||
|
||||
| Resource | Status |
|
||||
|----------|--------|
|
||||
| Gitea API token | ✅ Have |
|
||||
| Kimi API key | ✅ Have |
|
||||
| Telegram bot | ⏳ Need @BotFather |
|
||||
| New profile | ⏳ Will create |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Claw Code Mirror](http://143.198.27.163:3000/Timmy/claw-code)
|
||||
- [Claw Issue #1 - Architecture](http://143.198.27.163:3000/Timmy/claw-code/issues/1)
|
||||
- [Hermes v0.6 Profiles](../docs/profiles.md)
|
||||
|
||||
---
|
||||
|
||||
## Tickets
|
||||
|
||||
- #203: Implement ToolPermissionContext
|
||||
- #204: Create ExecutionRegistry
|
||||
- #205: Build Session Persistence
|
||||
- #206: Gitea Integration
|
||||
- #207: Telegram Deployment
|
||||
|
||||
---
|
||||
|
||||
*This epic supersedes Allegro-Primus who has been idle.*
|
||||
39
tickets/TICKET-203-tool-permission.md
Normal file
39
tickets/TICKET-203-tool-permission.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 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`
|
||||
44
tickets/TICKET-204-execution-registry.md
Normal file
44
tickets/TICKET-204-execution-registry.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# TICKET-204: Create ExecutionRegistry
|
||||
|
||||
**Epic:** EPIC-202
|
||||
**Priority:** P0
|
||||
**Status:** Ready
|
||||
**Assignee:** Allegro
|
||||
**Estimate:** 6 hours
|
||||
|
||||
## Description
|
||||
|
||||
Create ExecutionRegistry for clean command/tool routing, replacing model-decided routing.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `ExecutionRegistry` class
|
||||
- [ ] `register_command(name, handler)` method
|
||||
- [ ] `register_tool(name, handler)` method
|
||||
- [ ] `command(name) -> CommandHandler` lookup
|
||||
- [ ] `tool(name) -> ToolHandler` lookup
|
||||
- [ ] `execute(prompt, context)` routing method
|
||||
- [ ] Permission context integration
|
||||
- [ ] Tests pass
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Pattern from Claw `src/execution_registry.py`:
|
||||
|
||||
```python
|
||||
class ExecutionRegistry:
|
||||
def __init__(self):
|
||||
self._commands: dict[str, CommandHandler] = {}
|
||||
self._tools: dict[str, ToolHandler] = {}
|
||||
|
||||
def register_command(self, name: str, handler: CommandHandler):
|
||||
self._commands[name] = handler
|
||||
|
||||
def command(self, name: str) -> CommandHandler | None:
|
||||
return self._commands.get(name)
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Claw: `src/execution_registry.py`
|
||||
- Claw: `src/runtime.py` for usage
|
||||
43
tickets/TICKET-205-session-persistence.md
Normal file
43
tickets/TICKET-205-session-persistence.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# TICKET-205: Build Session Persistence
|
||||
|
||||
**Epic:** EPIC-202
|
||||
**Priority:** P0
|
||||
**Status:** Ready
|
||||
**Assignee:** Allegro
|
||||
**Estimate:** 4 hours
|
||||
|
||||
## Description
|
||||
|
||||
Build JSON-based session persistence layer, more portable than SQLite.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] `RuntimeSession` dataclass
|
||||
- [ ] `SessionStore` class
|
||||
- [ ] `save(session)` writes JSON
|
||||
- [ ] `load(session_id)` reads JSON
|
||||
- [ ] `HistoryLog` for turn tracking
|
||||
- [ ] Sessions survive agent restart
|
||||
- [ ] Tests pass
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Pattern from Claw `src/session_store.py`:
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class RuntimeSession:
|
||||
session_id: str
|
||||
prompt: str
|
||||
context: dict
|
||||
history: HistoryLog
|
||||
persisted_path: Path
|
||||
|
||||
def save(self):
|
||||
self.persisted_path.write_text(json.dumps(asdict(self)))
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Claw: `src/session_store.py`
|
||||
- Claw: `src/history.py`
|
||||
Reference in New Issue
Block a user