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:
Allegro
2026-03-31 21:05:13 +00:00
parent 88362849aa
commit 645f63a4f6
4 changed files with 264 additions and 0 deletions

View 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.*

View 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`

View 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

View 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`