Coordination Primitives
The Principle
Issues, claims, dependencies—the graph of work.
When multiple agents collaborate, they need shared understanding of work. Not just tasks, but relationships between tasks. This is coordination infrastructure.
The Work Graph
Work isn't a list—it's a graph:
┌──────────────┐
│ Ethos │
│ (org values) │
└──────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Project A │ │ Project B │ │ Project C │
│ (website) │ │ (API) │ │ (mobile) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
┌──────┼──────┐ │ ┌──────┼──────┐
│ │ │ │ │ │ │
Issue Issue Issue Issue Issue Issue Issue
│ │ │ │ │ │ │
└──────┴──────┴───────┴────────┴──────┴──────┘
│
(dependencies)
Agents navigate this graph to find work, understand context, and coordinate.
Issues: The Atomic Unit
An issue is the smallest trackable unit of work:
interface Issue {
id: string;
title: string;
description: string;
status: 'open' | 'in_progress' | 'closed';
type: 'task' | 'bug' | 'feature' | 'epic';
priority: number;
assignee?: string;
dependencies: string[]; // IDs of blocking issues
created_at: Date;
updated_at: Date;
closed_at?: Date;
reason?: string; // Why it was closed
}
Issue States
┌─────────┐ claim ┌─────────────┐ close ┌────────┐
│ open │ ──────────→ │ in_progress │ ──────────→ │ closed │
└─────────┘ └─────────────┘ └────────┘
↑ │
└─────── release ─────────┘
- Open: Work is defined, not started
- In Progress: An agent has claimed this work
- Closed: Work is complete (or abandoned with reason)
Claims: Work Ownership
When an agent starts work, it claims the issue:
// Claiming prevents collisions
async function claimIssue(issueId: string, agentId: string): Promise<boolean> {
const issue = await getIssue(issueId);
if (issue.status !== 'open') {
return false; // Already claimed
}
await updateIssue(issueId, {
status: 'in_progress',
assignee: agentId,
updated_at: new Date()
});
return true;
}
Claim Etiquette
- Claim before working → Prevents duplicate effort
- Release if blocked → Others can proceed
- Complete or close → Don't abandon silently
- Small claims → Claim one issue at a time
Dependencies: The Blocking Relationship
Issues can depend on other issues:
// Add dependency: issueA depends on issueB
await addDependency('issue-A', 'issue-B');
// Check if ready (no open dependencies)
async function isReady(issueId: string): Promise<boolean> {
const issue = await getIssue(issueId);
for (const depId of issue.dependencies) {
const dep = await getIssue(depId);
if (dep.status !== 'closed') {
return false; // Blocked by open dependency
}
}
return true;
}
Dependency Patterns
Sequential:
A ──→ B ──→ C
(B waits for A, C waits for B)
Parallel:
┌──→ B ──┐
A ──┤ ├──→ D
└──→ C ──┘
(B and C can run together after A)
Diamond:
┌──→ B ──┐
A ──┤ ├──→ D
└──→ C ──┘
(D waits for both B and C)
Ready Work
An agent finds work by querying for ready issues:
async function getReadyIssues(): Promise<Issue[]> {
const openIssues = await db
.prepare(`
SELECT * FROM issues
WHERE status = 'open'
ORDER BY priority DESC
`)
.all();
const ready: Issue[] = [];
for (const issue of openIssues.results) {
if (await isReady(issue.id)) {
ready.push(issue);
}
}
return ready;
}
Agents work on what's ready, not what's urgent.
The Beads System
CREATE SOMETHING uses Beads for agent-native task management:
Core Commands
# Find ready work
bd ready
# Show issue details
bd show <issue-id>
# Claim work
bd update <issue-id> --status=in_progress
# Complete work
bd close <issue-id> --reason="Description of what was done"
# Create new issue discovered during work
bd create --title="Discovered issue" --type=task
# Add dependency
bd dep add <issue> <depends-on>
Session Workflow
# Start session: Find work
bd ready
# → Shows prioritized list of unblocked issues
# Claim issue
bd update beads-xxx --status=in_progress
# Work happens...
# Discover related work
bd create --title="Need to also handle edge case" --type=task
bd dep add beads-yyy beads-xxx # New issue depends on current
# Complete work
bd close beads-xxx --reason="Implemented feature with tests"
# Sync to remote
bd sync
Graph Queries
Powerful queries reveal system state:
What's Blocking Everything?
-- Find issues that block the most other issues
SELECT
i.id,
i.title,
COUNT(d.issue_id) as blocks_count
FROM issues i
JOIN dependencies d ON i.id = d.depends_on
WHERE i.status != 'closed'
GROUP BY i.id
ORDER BY blocks_count DESC
LIMIT 10;
Critical Path
// Find the longest chain of dependencies
function findCriticalPath(issues: Issue[]): Issue[] {
const graph = buildDependencyGraph(issues);
let longestPath: Issue[] = [];
for (const issue of issues) {
const path = findLongestPathFrom(issue, graph);
if (path.length > longestPath.length) {
longestPath = path;
}
}
return longestPath;
}
Orphaned Work
-- Issues with no project connection
SELECT * FROM issues
WHERE project_id IS NULL
AND status = 'open';
Coordination Protocols
Handoff Protocol
When an agent can't complete work:
- Document current state in issue
- Release claim (status back to open)
- Add note explaining where it stopped
- Next agent can see context and continue
bd update beads-xxx --status=open
bd comment beads-xxx "Completed steps 1-3, blocked on API access for step 4"
Escalation Protocol
When an issue needs human attention:
- Tag issue with priority/needs-attention
- Add detailed context
- Continue with other work
bd update beads-xxx --priority=1 --labels="needs-human"
bd comment beads-xxx "Architecture decision needed: should we use X or Y approach?"
Completion Protocol
When closing an issue:
- Verify work is actually done
- Add reason explaining what was done
- Close any resolved dependencies
- Trigger downstream work
bd close beads-xxx --reason="Implemented auth middleware with JWT validation"
# Downstream issues with dependency on beads-xxx now become ready
Anti-Patterns
Orphan Issues
Issue created → No dependencies → No project → Lost in the void
Always connect issues to projects or parent issues.
Circular Dependencies
A depends on B
B depends on C
C depends on A ← Cycle!
Validate when adding dependencies.
Over-Granular Issues
Issue: Add semicolon to line 45
Issue: Add semicolon to line 46
Issue: Add semicolon to line 47
Issues should be meaningful units of work.
Under-Granular Issues
Issue: Rebuild the entire application
Issues should be completable in reasonable time.
Reflection
Before the praxis:
- How do you currently track work relationships?
- What would a dependency graph of your current project look like?
- How often does duplicate work happen due to poor coordination?
Praxis: Set up a coordination system for a real project.
Cross-Property References
Canon Reference: Coordination primitives enable Tool Complementarity—agents that work together rather than in isolation.
Research Depth: Study Understanding Graphs for how dependency relationships encode project understanding.
Practice: The Beads coordination system (
bdCLI) demonstrates these primitives in action.