Skip to main content

State Management

Genie tracks state primarily in PostgreSQL via the embedded pgserve database. Wishes, tasks, boards, projects, agents, teams, mailboxes, and team chat all live in PG tables. Legacy JSON file state has been replaced by database-backed equivalents.

Wish State Machine

Wish execution is tracked in PostgreSQL via the task service. A wish becomes a parent task, and each execution group becomes a child task with dependency edges.

State Transitions

Dependency Resolution

When a group completes, completeGroup() recalculates all dependent groups. If every dependency of a blocked group is now done, that group transitions to ready.
The wish state machine stores state in the PG tasks + task_dependencies tables. PG handles concurrency natively — no file locks are needed for wish state.

Board State

Boards provide project-scoped Kanban pipelines. Each board has ordered columns with gate types and action skills: Tasks are assigned to board columns via column_id. Use genie board reconcile to fix orphaned column references after pipeline changes.

Project State

Projects group boards and tasks into named scopes: Tasks scope to projects via project_id. When running genie task list inside a repo, it auto-scopes to that repo’s project.

Agent Registry

Every spawned agent is tracked in the PostgreSQL agents table. The registry stores provider metadata, transport info, and lifecycle state.

Agent States

Agent Record

Each agent record includes:
PostgreSQL handles concurrency natively — no file locks needed.

Team Management

Teams are stored in the PostgreSQL teams table. Each team owns an isolated clone of the repository.

Team Lifecycle

Isolation Model

Teams use git clone --shared instead of git worktree to avoid a known bug where Claude Code agents can flip core.bare=true on the parent repo via shared .git metadata, silently corrupting it.

Mailbox

Messages persist to the PostgreSQL mailbox table before any push delivery attempt. This ensures durability — even if tmux delivery fails, the message is stored in the database.

Message Format

Delivery is state-aware: messages are queued and pushed to tmux panes only when the agent is idle (not mid-turn). A sent message log is also kept in an append-only JSONL outbox file.
Mailbox delivery is best-effort. Messages are persisted to PostgreSQL (durable), but tmux pane injection is not retried. If a pane dies, the message stays with deliveredAt: null.

Team Chat

Each team has a group chat stored in the PostgreSQL team_chat table.
Team chat is scoped per team — each team maintains its own chat history in the database.