Skip to content

Loom Entities Reference

Complete reference for all entities (data structures) in the Loom system.

Table of Contents

  1. Agent
  2. Bead
  3. Provider
  4. Project
  5. Decision
  6. Persona
  7. Workflow

Agent

An autonomous AI entity with a specific role and behavioral instructions.

Model Definition

Database Table: agents

Fields:

Field Type Description
id UUID Unique agent identifier
name string Human-readable agent name
project_id UUID Associated project ID
persona_id UUID Persona (role) definition ID
role string Org chart role (CEO, CFO, Engineer, etc.)
status string Current status: idle, working, paused, complete
description string What this agent does
capabilities string JSON array of capabilities
current_bead_id UUID Currently assigned bead (if working)
messages string Message log (JSON)
created_at timestamp Creation time
updated_at timestamp Last update time

Status Transitions

┌─────┐
│idle │ ─── provider_down ──→ ┌────────┐
└──┬──┘                        │paused  │
   │                           └──┬─────┘
   │ assign_bead                  │ provider_up
   │                              │
   ▼                              ▼
┌─────────┐                    ┌─────┐
│working  │  ─── complete ──→  │idle │
└─────────┘                    └─────┘

Naming

When spawning an agent without a custom name, the display name is auto-derived from the persona path: - default/web-designer -> Web Designer (Default) - default/engineering-manager -> Engineering Manager (Default) - projects/myapp/specialist -> Specialist (myapp)

The agent ID is generated as agent-{unix_timestamp}-{display_name}.

Lifecycle

  1. Creation: Agent created when assigned to a project
  2. Initial State: paused (waiting for provider)
  3. Provider Activation: Transitions to idle when provider becomes healthy
  4. Work Assignment: Receives bead, transitions to working
  5. Completion: Bead processed, transitions to idle
  6. Pause: On provider health issue

Example

{
  "id": "agent-ceo-default",
  "name": "CEO (Default)",
  "project_id": "proj-loom",
  "persona_id": "persona-ceo",
  "role": "ceo",
  "status": "idle",
  "description": "Chief Executive Officer - Strategic oversight",
  "capabilities": ["decision_making", "strategic_planning", "escalation"],
  "created_at": "2026-01-20T08:00:00Z",
  "updated_at": "2026-01-20T08:15:00Z"
}

Bead

A discrete unit of work (task, story, decision request) in the system.

Model Definition

Database Table: beads
File Storage: .beads/beads/*.yaml

Fields:

Field Type Description
id string Unique identifier (required)
type string Work type: feature, bugfix, test, decision, analysis, review
title string Short description
description string Detailed work description
project_id UUID Associated project
assigned_to UUID Agent assignment (null = unassigned)
status string open, in_progress, blocked, done
priority int 1-5 (5 = highest)
parent_id string Parent bead ID (for sub-tasks)
blocked_by []string IDs of blocking beads
blocks []string IDs of beads this blocks
children_ids []string Sub-task IDs
created_at timestamp Creation time
updated_at timestamp Last update time
completed_at timestamp Completion time

Status Transitions

┌──────┐
│open  │ ─── assign ──→ ┌─────────────┐
└──────┘                │in_progress  │
   ▲                    └──┬──────────┘
   │                       │ complete
   │ unblock               │
   │                       ▼
┌──────────┐            ┌─────┐
│blocked   │            │done │
└──────────┘            └─────┘

Dependencies

Blocking Logic: - A bead can't transition to in_progress if any blocked_by beads are not done - When a bead completes, dependent beads become available - Circular dependencies are detected at load time

Hierarchy: - Parent/child relationships for sub-tasks - Parent completion doesn't require all children done - Children inherit some priority from parent

Example YAML

id: bd-001-feature-auth
type: feature
title: Implement OAuth Integration
description: |
  Add OAuth 2.0 support for GitHub and Google login.
  Must support token refresh and logout.
project_id: proj-app
assigned_to: agent-engineering-001
status: in_progress
priority: 4
blocked_by:
  - bd-001-deps-oauth-lib
blocks:
  - bd-002-feature-user-settings
parent_id: null
children_ids:
  - bd-001-sub-github-oauth
  - bd-001-sub-google-oauth
created_at: "2026-01-20T08:00:00Z"
updated_at: "2026-01-20T09:30:00Z"

Type Conventions

Type Purpose Typical Duration
feature New capability Hours to days
bugfix Issue fix Minutes to hours
test Quality assurance Minutes to hours
decision Approval workflow Real-time to hours
analysis Investigation Minutes to hours
review Code/design review Minutes to hours

Provider

An LLM service endpoint. In practice, this is TokenHub -- I delegate all model routing and provider management to it.

Model Definition

Database Table: providers
Registration: API or bootstrap.local

Fields:

Field Type Description
id string Unique provider identifier (typically tokenhub)
name string Display name
type string Always openai (TokenHub speaks OpenAI-compatible API)
endpoint string Base URL for API calls
model string Default model ID
selected_model string Currently active model
status string pending, active, healthy, error, failed
requires_key bool Whether API key needed
key_id string Reference to encrypted key in keymanager
last_heartbeat_at timestamp Last health check time
last_heartbeat_latency_ms int Response time of last check
last_heartbeat_error string Last error message
created_at timestamp Registration time
updated_at timestamp Last update time

Status Workflow

┌─────────┐
│pending  │ ──── health_check ───→ ┌────────┐
└─────────┘                        │active  │
                                   └───┬────┘
                                       │ heartbeat_fail
                                    ┌──────┐
                                    │error │
                                    └──────┘

Health Check

  • Initial: Performed immediately on registration
  • Periodic: Every 30 seconds
  • Check: GET /v1/models endpoint
  • Activation: Automatic when first successful check
  • Agent Resume: Agents resume automatically when TokenHub becomes active

Example

{
  "id": "tokenhub",
  "name": "TokenHub",
  "type": "openai",
  "endpoint": "http://localhost:8090/v1",
  "model": "anthropic/claude-sonnet-4-20250514",
  "status": "healthy",
  "requires_key": true,
  "last_heartbeat_at": "2026-02-21T08:30:00Z",
  "last_heartbeat_latency_ms": 45,
  "last_heartbeat_error": "",
  "created_at": "2026-02-21T08:00:00Z",
  "updated_at": "2026-02-21T08:30:00Z"
}

Project

A container for beads, agents, and related work.

Model Definition

Database Table: projects
Configuration: config.yaml or UI

Fields:

Field Type Description
id string Unique identifier
name string Display name
description string Project purpose
git_repo string Git repository URL
branch string Git branch to track
beads_path string Path to beads (relative to repo)
is_sticky bool Auto-register on startup
is_perpetual bool Never closes, continuous operation
status string active, archived, suspended
created_at timestamp Creation time
updated_at timestamp Last update time

Lifecycle

  1. Creation: Defined in config.yaml or created via UI
  2. Initialization: Beads loaded from git
  3. Operation: Agents assigned, work dispatched
  4. Completion: When all beads done (unless perpetual)
  5. Archive: Marked complete, beads no longer processed

Example

id: loom
name: Loom
description: Agent orchestration and workflow engine
git_repo: https://github.com/jordanhubbard/loom
branch: main
beads_path: .beads
is_sticky: true
is_perpetual: true
created_at: "2026-01-20T07:00:00Z"
updated_at: "2026-01-20T08:00:00Z"

Decision

An escalation request requiring human/agent approval.

Model Definition

Database Table: decisions

Fields:

Field Type Description
id string Unique identifier
project_id UUID Associated project
question string Decision being made
requester_id UUID Agent requesting decision
status string pending, approved, denied
options []string Possible responses
response string Chosen response
responder_id UUID Who made decision
created_at timestamp Request time
responded_at timestamp Response time

Workflow

Agent Requests Decision
Decision Created (status=pending)
UI Shows for Approval
Human/CEO Approves or Denies
Decision Updated (status=approved/denied)
Agent Notified via Signal
Agent Resumes Work

Example

{
  "id": "decision-001",
  "project_id": "proj-app",
  "question": "Should we proceed with 50K infrastructure investment?",
  "requester_id": "agent-cfo",
  "status": "approved",
  "options": ["approve", "deny", "defer"],
  "response": "approve",
  "responder_id": "agent-ceo",
  "created_at": "2026-01-20T08:00:00Z",
  "responded_at": "2026-01-20T08:05:00Z"
}

Persona

Instructions, guidelines, and behavioral rules for agent roles.

Model Definition

File Storage: personas/*/name.md
Categories: personas/default/ (standard roles), personas/loom/ (system roles)

Structure:

# Role Name

## Description
What this role does and its responsibilities.

## Instructions
Detailed behavioral instructions and guidelines.

## Capabilities
- List of capabilities
- What this agent can request
- What decisions it can make

## Constraints
- Limitations and guardrails
- Escalation triggers

Example: CFO Persona

# Chief Financial Officer (CFO)

## Description
Responsible for financial oversight, budget approval, and cost management.

## Instructions
- Review all budget requests over $10,000
- Monitor ongoing project costs daily
- Alert CEO of cost overruns > 20%
- Approve or deny capital requests

## Capabilities
- Decision approval (budget, capital)
- Financial queries
- Cost analysis
- Budget forecast

## Constraints
- Cannot approve over $500,000 (needs CEO)
- Must document all decisions
- Escalate financial anomalies

Workflow

A multi-step process definition used by the workflow engine.

Key Characteristics

  • Durable: Survives process crashes/restarts
  • Observable: Full execution history
  • Composable: Steps can chain and branch

Entity Relationships

┌─────────┐
│Project  │
└────┬────┘
     ├─── 1 to Many ──→ ┌──────┐
     │                  │Bead  │
     │                  └──────┘
     └─── 1 to Many ──→ ┌───────┐
                        │Agent  │
                        └───┬───┘
                        assigned_to
                        ┌──────┐
                        │Bead  │
                        └──────┘

┌──────────┐
│Provider  │
└────┬─────┘
     │ serves
┌──────────────┐
│Agent         │
└──────────────┘
     │ requests
┌──────────────┐
│Decision      │
└──────────────┘

Activity

Purpose: Record of important events across the system for team activity tracking

Model Definition

type Activity struct {
    ID               string                 `json:"id"`
    EventType        string                 `json:"event_type"`
    Timestamp        time.Time              `json:"timestamp"`
    Source           string                 `json:"source"`
    ActorID          string                 `json:"actor_id,omitempty"`
    ActorType        string                 `json:"actor_type,omitempty"`
    ProjectID        string                 `json:"project_id,omitempty"`
    AgentID          string                 `json:"agent_id,omitempty"`
    BeadID           string                 `json:"bead_id,omitempty"`
    ProviderID       string                 `json:"provider_id,omitempty"`
    Action           string                 `json:"action"`
    ResourceType     string                 `json:"resource_type"`
    ResourceID       string                 `json:"resource_id"`
    ResourceTitle    string                 `json:"resource_title,omitempty"`
    Metadata         map[string]interface{} `json:"metadata,omitempty"`
    AggregationKey   string                 `json:"aggregation_key,omitempty"`
    AggregationCount int                    `json:"aggregation_count"`
    IsAggregated     bool                   `json:"is_aggregated"`
    Visibility       string                 `json:"visibility"`
}

Event Types

Activities are created from these EventBus events: - bead.created, bead.assigned, bead.status_change, bead.completed - agent.spawned, agent.status_change, agent.completed - project.created, project.updated, project.deleted - provider.registered, provider.deleted, provider.updated - decision.created, decision.resolved - motivation.fired, motivation.enabled, motivation.disabled - workflow.started, workflow.completed, workflow.failed

Aggregation

Activities with the same aggregation_key within a 5-minute window are grouped: - Aggregation key format: {event_type}.{date-hour}.{project_id}.{actor_id} - aggregation_count tracks number of similar events - Example: 5 bead creations → 1 activity with aggregation_count: 5

Visibility

  • project: Visible only to users with projects:read permission on the project
  • global: Visible to all users (provider events, system events)

Example

{
  "id": "act-abc123",
  "event_type": "bead.created",
  "timestamp": "2026-01-31T10:30:00Z",
  "action": "created",
  "resource_type": "bead",
  "resource_id": "bead-xyz",
  "resource_title": "Fix login bug",
  "project_id": "proj-1",
  "actor_id": "agent-123",
  "aggregation_count": 5,
  "is_aggregated": true,
  "visibility": "project"
}

Notification

Purpose: User-specific alerts for important events requiring attention

Model Definition

type Notification struct {
    ID         string                 `json:"id"`
    UserID     string                 `json:"user_id"`
    ActivityID string                 `json:"activity_id,omitempty"`
    EventType  string                 `json:"event_type"`
    Title      string                 `json:"title"`
    Message    string                 `json:"message"`
    Link       string                 `json:"link,omitempty"`
    Status     string                 `json:"status"`
    Priority   string                 `json:"priority"`
    Metadata   map[string]interface{} `json:"metadata,omitempty"`
    CreatedAt  time.Time              `json:"created_at"`
    ReadAt     *time.Time             `json:"read_at,omitempty"`
    ArchivedAt *time.Time             `json:"archived_at,omitempty"`
}

Status Values

  • unread: Notification not yet seen by user
  • read: User has viewed the notification
  • archived: User has archived the notification

Priority Levels

  • low: Informational, non-urgent
  • normal: Standard priority (default)
  • high: Important, requires timely attention
  • critical: Urgent, requires immediate action

Notification Rules

Users receive notifications for: 1. Direct Assignment: Bead or decision assigned to them 2. Critical Priority: P0 beads created 3. Decision Required: Decision requires their input 4. System Alerts: Provider failures, workflow errors

Preferences

Users can configure: - enable_in_app: Enable/disable in-app notifications - subscribed_events: List of event types (empty = all) - min_priority: Minimum priority threshold - quiet_hours_start/end: Suppress notifications during hours (HH:MM format) - digest_mode: Delivery mode (realtime, hourly, daily) - project_filters: Only notify for specific projects

Example

{
  "id": "notif-123",
  "user_id": "user-admin",
  "activity_id": "act-abc123",
  "event_type": "bead.assigned",
  "title": "Bead Assigned to You",
  "message": "You've been assigned to bead: Fix login bug",
  "link": "/beads/bead-xyz",
  "status": "unread",
  "priority": "high",
  "created_at": "2026-01-31T10:30:00Z"
}

Data Persistence

All entities are persisted to:

  1. SQLite Database (loom.db)
  2. Primary storage for agents, beads, providers, projects, decisions
  3. Transactional consistency
  4. Auto-backup capability

  5. YAML Files (Beads)

  6. .beads/beads/*.yaml in each project repo
  7. Source of truth for work definitions
  8. Versioned in git

Entity Lifecycle Summary

Entity Created Modified Deleted Persisted
Agent On project assignment Status changes On project delete Database
Bead On project load Status/assignment changes Manual Database + YAML
Provider UI/API/config Health status UI/API Database
Project config.yaml/UI Config changes UI Database
Decision Agent escalation Response Auto-cleanup Database
Persona File creation Content edit File delete File + Database
Workflow Workflow engine Step completion Timeout Database
Activity On important events Aggregation updates Retention policy Database
Notification Rule evaluation Read status User archive Database