-
Notifications
You must be signed in to change notification settings - Fork 7
Closed
Description
Parent: #204 | Phase 1: Single Rig, Single Polecat
Goal
The Rig DO is the core state machine that holds beads, agents, mail, and the PR review queue for a single rig. This is the authoritative data store — all state lives in DO SQLite.
New Worker
cloud/cloudflare-gastown/
├── src/
│ ├── index.ts # Hono router, DO exports
│ ├── types.ts # Shared types
│ ├── rig-do.ts # Rig Durable Object
│ ├── town-do.ts # Town Durable Object (stub in Phase 1)
│ ├── agent-identity-do.ts # Agent Identity Durable Object
│ └── db/
│ └── rig-schema.sql # SQLite schema for Rig DO
├── wrangler.jsonc
├── package.json
└── tsconfig.json
Rig DO SQLite Schema
CREATE TABLE beads (
id TEXT PRIMARY KEY,
type TEXT NOT NULL, -- 'issue', 'message', 'escalation', 'merge_request'
status TEXT NOT NULL DEFAULT 'open',
title TEXT NOT NULL,
body TEXT,
assignee_agent_id TEXT,
convoy_id TEXT,
molecule_id TEXT,
priority TEXT DEFAULT 'medium',
labels TEXT DEFAULT '[]', -- JSON array
metadata TEXT DEFAULT '{}', -- JSON object
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
closed_at TEXT
);
CREATE TABLE agents (
id TEXT PRIMARY KEY,
role TEXT NOT NULL,
name TEXT NOT NULL,
identity TEXT NOT NULL UNIQUE,
cloud_agent_session_id TEXT,
status TEXT NOT NULL DEFAULT 'idle',
current_hook_bead_id TEXT REFERENCES beads(id),
last_activity_at TEXT,
checkpoint TEXT, -- JSON: crash-recovery data
created_at TEXT NOT NULL
);
CREATE TABLE mail (
id TEXT PRIMARY KEY,
from_agent_id TEXT NOT NULL REFERENCES agents(id),
to_agent_id TEXT NOT NULL REFERENCES agents(id),
subject TEXT NOT NULL,
body TEXT NOT NULL,
delivered INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
delivered_at TEXT
);
CREATE INDEX idx_mail_undelivered ON mail(to_agent_id) WHERE delivered = 0;
CREATE TABLE review_queue (
id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL REFERENCES agents(id),
bead_id TEXT NOT NULL REFERENCES beads(id),
branch TEXT NOT NULL,
pr_url TEXT,
status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'merged', 'failed'
summary TEXT,
created_at TEXT NOT NULL,
processed_at TEXT
);
CREATE TABLE molecules (
id TEXT PRIMARY KEY,
bead_id TEXT NOT NULL REFERENCES beads(id),
formula TEXT NOT NULL, -- JSON: step definitions
current_step INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL DEFAULT 'active',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);RPC API Surface
class RigDO extends DurableObject<Env> {
// -- Beads --
async createBead(input: CreateBeadInput): Promise<Bead>
async getBead(beadId: string): Promise<Bead | null>
async listBeads(filter: BeadFilter): Promise<Bead[]>
async updateBeadStatus(beadId: string, status: string, agentId: string): Promise<Bead>
async closeBead(beadId: string, agentId: string): Promise<Bead>
// -- Agents --
async registerAgent(input: RegisterAgentInput): Promise<Agent>
async getAgent(agentId: string): Promise<Agent | null>
async getAgentByIdentity(identity: string): Promise<Agent | null>
async listAgents(filter?: AgentFilter): Promise<Agent[]>
async updateAgentSession(agentId: string, sessionId: string | null): Promise<void>
async updateAgentStatus(agentId: string, status: string): Promise<void>
// -- Hooks (GUPP) --
async hookBead(agentId: string, beadId: string): Promise<void>
async unhookBead(agentId: string): Promise<void>
async getHookedBead(agentId: string): Promise<Bead | null>
// -- Mail --
async sendMail(input: SendMailInput): Promise<void>
async checkMail(agentId: string): Promise<Mail[]> // marks as delivered
// -- Review Queue --
async submitToReviewQueue(input: ReviewQueueInput): Promise<void>
async popReviewQueue(): Promise<ReviewQueueEntry | null>
async completeReview(entryId: string, status: 'merged' | 'failed'): Promise<void>
// -- Prime (context assembly) --
async prime(agentId: string): Promise<PrimeContext>
// -- Checkpoint --
async writeCheckpoint(agentId: string, data: unknown): Promise<void>
async readCheckpoint(agentId: string): Promise<unknown | null>
// -- Done --
async agentDone(agentId: string, input: AgentDoneInput): Promise<void>
// -- Health (called by alarms) --
async witnessPatrol(): Promise<PatrolResult>
}Wrangler Config
Acceptance Criteria
- New
cloudflare-gastownworker with project scaffolding - Rig DO with SQLite schema applied on first access
- All RPC methods implemented and unit tested
- Town DO and Agent Identity DO stubs exported
- Wrangler config with DO bindings and migrations
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
{ "name": "gastown", "main": "src/index.ts", "compatibility_date": "2025-01-01", "durable_objects": { "bindings": [ { "name": "RIG", "class_name": "RigDO" }, { "name": "TOWN", "class_name": "TownDO" }, { "name": "AGENT_IDENTITY", "class_name": "AgentIdentityDO" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": ["RigDO", "TownDO", "AgentIdentityDO"] } ] }