Core Components
Agent Mail: Agent Coordination
Advisory file reservations, hard leases, message threading, and intent broadcasting. Agents coordinate through data — conflicts are information, not errors.
Message Types
| Type | Description |
|---|---|
| task.help_needed | Agent needs help with a task |
| task.handoff | Agent hands off a task to another |
| task.claimed | Agent claimed a task |
| task.completed | Task finished successfully |
| task.failed | Task execution failed |
| task.progress | Task progress update |
| task.files_changed | Agent reports files modified during task |
| task.file_conflict | File reservation conflict detected |
| file.lock_request | Request exclusive file lock |
| file.lock_granted | File lock granted |
| file.lock_denied | File lock denied |
| coordination.sync | Coordination sync between agents |
| info.discovery | Information discovery broadcast |
| agent.started | Agent came online |
| agent.stopped | Agent went offline |
| agent.intent.announce | Agent announces intent (files it will touch) |
| agent.intent.complete | Agent completed announced intent |
| agent.workspace.declare | Agent declares workspace/files it will touch |
| reservation.conflict | File reservation conflict detected |
| reservation.released | File reservation released |
| system.shutdown | System shutdown signal |
| custom | Custom user-defined message type |
Message API
import { createLibSQLLocalDataLayer } from '@jetpack-agent/data';
const dataLayer = await createLibSQLLocalDataLayer('.jetpack/jetpack.db');
// Broadcast a message to all agents
await dataLayer.messages.broadcast(
'task.files_changed',
agentId,
{ files: ['src/auth.ts', 'src/middleware.ts'] }
);
// Send a message to a specific agent
await dataLayer.messages.send(
'task.file_conflict',
fromAgentId,
toAgentId,
{ filePath: 'src/auth.ts', conflictingAgent: 'agent-2' }
);
// Receive messages for an agent
const messages = await dataLayer.messages.receive(agentId);Dual Coordination Model
Jetpack uses two coordination mechanisms: advisory file reservations (non-blocking, conflicts as data) and hard leases (exclusive locks for critical sections). AgentHarness uses both — hard leases for atomic task claiming and advisory reservations for file coordination.
Advisory File Reservations
Multiple agents can reserve the same file. Conflicts surface as data — agents see who else is working nearby and can coordinate. Enforcement is optional via a pre-commit Git hook.
Agent-1 wants to edit Button.tsx
│
▼
reserve({ agentId, taskId, filePath, reservationType: 'edit' })
│
├─► Insert reservation into file_reservations table
├─► Check for other active reservations on same file
│ └─► If conflicts exist: RETURN { granted: true, conflicts: [...] }
│ └─► If no conflicts: RETURN { granted: true, conflicts: [] }
│
│ (Note: Reservation is ALWAYS granted — conflicts are advisory)
│
Agent-1 edits file, sees Agent-2 also working on it
│
▼
releaseAll(agentId) // Release all reservations for this agentHard Leases
For exclusive access (e.g., atomic task claiming), AgentHarness uses hard leases via dataLayer.leases.acquire() and dataLayer.leases.release().
Reservation API
// Reserve a file (always succeeds — advisory model)
const grant = await dataLayer.reservations.reserve({
agentId: 'agent-1',
taskId: 'task-1',
filePath: 'src/auth.ts',
reservationType: 'edit', // 'edit' | 'read' | 'create' | 'delete'
});
// Returns: { granted: true, reservationId, conflicts: [...] }
// Check conflicts for multiple files at once
const conflicts = await dataLayer.reservations.checkConflictsBatch(
['src/auth.ts', 'src/middleware.ts'],
'agent-1'
);
// Release all reservations for an agent
await dataLayer.reservations.releaseAll('agent-1');
// Cleanup old reservations (older than specified ms)
await dataLayer.reservations.cleanup(3600000); // 1 hourMessage Threading
// Messages can be organized into threads
const thread = await dataLayer.messages.getThread(threadId);Git Hook Enforcement
# Install optional pre-commit hook
jetpack hook install
# Manually check reservation conflicts
jetpack check-reservationsAdvisory Reservations vs Hard Leases
| Feature | Advisory Reservations | Hard Leases |
|---|---|---|
| Blocking | Never — always granted | Exclusive — acquire can fail |
| Conflicts | Returned as data array | Prevents concurrent access |
| Use case | File coordination between agents | Atomic task claiming |
| Cleanup | cleanup(olderThanMs) | Auto-expires via TTL |
| Enforcement | Optional (pre-commit Git hook) | Always enforced |
