How Agent Graph Handles Git Worktree Scheduling for Child Sessions in Apache Maka
Agent Graph schedules child Sessions using deterministic Git worktrees leased through GitWorktreeChildExecutor and serializes every scheduling change through monotonic schedule revisions stored in SQLite.
The Agent Graph is the internal DAG that drives all Maka Sessions. When a parent Session spawns a linked child Session—a durable sub-agent—the runtime must provide an isolated, reproducible filesystem where that child can check out its own branch, apply patches, and resume after crashes. Apache Maka solves this by allocating a host-owned Git worktree for each child Session and serializing every scheduling decision through the Agent Graph schedule revision system.
Git Worktree Allocation with GitWorktreeChildExecutor
The GitWorktreeChildExecutor class in packages/storage/src/git-worktree-child-executor.ts manages deterministic, idempotent worktree provisioning for child Sessions.
Lease Identity and Deterministic Paths
Each child Session supplies a leaseId (for example, subagent_worktree_7a3f…). The executor derives a deterministic leaseSuffix from this ID and creates the worktree at a fixed path:
.../subagent-worktrees/<leaseSuffix>
This design guarantees that retries and recoveries always resolve to the same filesystem location.
Atomic Provisioning and Branch Leasing
The provision() method implements several critical safety mechanisms:
- Deduplication via
inFlightmap — Checks for existing provisioning promises to prevent duplicate worktree creation during retries (lines 99–104). - Private branch creation — Establishes a branch named
maka/subagent/<leaseSuffix>in the source repository. - Lease metadata in Git config — Records two keys:
branch.<branch>.maka‑worktree‑lease— stores the lease IDbranch.<branch>.maka‑worktree‑base— stores the base commit where the child started
The high-level provisioning flow occupies lines 44–73, with lease validation at 99–104 and creation logic at 106–119.
Agent Graph Schedule Revisions for Linearized Updates
Every change to a child Session's execution plan—whether "run this turn," "pause and wait," or "cancel"—is recorded as an AgentGraphScheduleUpdate row. This revision system ensures strict linearization across concurrent operations.
Schedule Update Schema
| Field | Purpose |
|---|---|
graphId |
Shared identifier linking parent and child Sessions |
revision |
Monotonically increasing integer; parent's current revision must match child's expectedRevision |
source / target |
Session IDs affected by this update |
updateId |
Stable identifier enabling idempotent retries |
Schedule Operations in sqlite-session-metadata-store.ts
The packages/storage/src/sqlite-session-metadata-store.ts file implements core schedule persistence:
currentAgentGraphScheduleRevision(line 3105) — Reads the latest revision from theagent_graph_schedule_updatestable.commitAgentGraphScheduleUpdate(lines 3242–3250) — Validates requests viaassertAgentGraphScheduleUpdateRequest, detects conflicts viaAgentGraphScheduleRevisionConflictError, and atomically writes new rows with incremented revisions.
These mechanisms guarantee that a child Session never observes stale schedules, and concurrent modifications fail fast with explicit conflict errors.
Linking Worktrees to Schedule Updates
When SessionMetadata.createSubagent instantiates a child Session, four coordinated steps occur:
- Spawn claim — The parent claims a sub-agent spawn identity including the
leaseIdfor the worktree. - Worktree provisioning —
GitWorktreeChildExecutor.provision()adopts existing worktrees or creates fresh ones, establishing branch leases and recordingbaseCommit. - Operator provision — The parent creates an
AgentGraphOperatorProvisionrow binding child Session ID, worktree lease, and current schedule revision. - Schedule advancement — The parent may push schedule updates; the child reads from
agent_graph_schedule_updates, validates its lease, and executes against the worktree-bound branch.
All three components—lease-bound worktree, schedule revision, and operator provision—persist in SQLite, enabling crash recovery with exact state reconstruction.
Practical Code Examples
Provision a Child Session Worktree
import { createGitWorktreeChildExecutor } from '@maka/storage';
// Initialize executor with Maka data directory
const executor = createGitWorktreeChildExecutor({
storageRoot: '/var/maka/data'
});
// Provision worktree using lease ID from parent Session
const binding = await executor.provision({
leaseId: 'subagent_worktree_7a3f9c2e5d1a4b8c9d0e1f2a3b4c5d6e',
sourceCwd: '/home/user/project',
sourceProjectId: 'proj-123',
sourceSessionId: 'sess-parent-001',
});
The returned binding contains worktreePath, branch, gitCommonDir, and the original leaseId.
Create Child Session and Advance Schedule
// Parent Session manager constructs child header
const childHeader = {
id: 'sess-child-002',
backend: 'maka',
subagentParent: {
subagentParentSessionId: 'sess-parent-001',
graph: {
graphId: 'graph-abc',
workId: 'work-001',
operatorId: 'op-001',
},
},
};
const child = await store.createSubagent(childHeader);
// Atomically provision worktree and record operator provision
await executor.ensure(childHeader.subagentParent?.worktreeBinding!);
// Commit schedule update for child's first turn
await store.commitAgentGraphScheduleUpdate({
graphId: 'graph-abc',
source: 'sess-parent-001',
target: 'sess-child-002',
updateId: 'upd-001',
sourceRevision: 0, // parent's current revision
targetRevision: 0, // child's current revision
schedule: { turnId: 'turn-1' },
});
The commitAgentGraphScheduleUpdate call verifies revision matches and inserts a row with revision = 1. The child later reads via readAgentGraphScheduleUpdateSync and executes its worktree-bound branch.
Recover After Crash
// Host restart recovery sequence
const liveBindings = await executor.listLiveBindings();
await executor.recover(liveBindings);
// Reload schedule revision for graph continuity
const revision = store.currentAgentGraphScheduleRevision('graph-abc');
console.log('Current schedule revision:', revision);
If the worktree persists and the lease validates, the child Session resumes at the exact schedule revision recorded before the crash.
Recovery and Cleanup Mechanisms
Maka implements dual cleanup strategies to prevent resource leaks:
- Worktree orphan detection —
GitWorktreeChildExecutor.recover()scans the worktree root directory, matches live bindings, and retires orphaned worktrees. - Schedule orphan cleanup —
reconcileOrphanedAgentGraphRetirements()in the metadata store walksagent_graph_operator_provisions, deletes Sessions with tombstoned parents, and marks associated worktrees for removal.
These routines ensure that neither stale worktrees nor schedule rows accumulate across long-running deployments.
Summary
- GitWorktreeChildExecutor in
packages/storage/src/git-worktree-child-executor.tsprovides deterministic, idempotent worktree allocation using lease-derived paths and Git config metadata. - Agent Graph schedule revisions in
packages/storage/src/sqlite-session-metadata-store.tsserialize all child Session scheduling through monotonic integers with conflict detection. - Three-persistence design (worktree lease + schedule revision + operator provision) enables crash recovery with exact state reconstruction.
- Atomic operations throughout prevent duplicate worktrees, stale schedule observations, and concurrent modification races.
Frequently Asked Questions
How does Maka prevent duplicate worktrees when provisioning retries occur?
The GitWorktreeChildExecutor maintains an inFlight map that checks for existing provisioning promises before creating new worktrees. When a retry arrives with the same leaseId, the executor adopts the in-flight promise rather than creating a duplicate. This guarantee is implemented in lines 99–104 of packages/storage/src/git-worktree-child-executor.ts.
What happens when two processes attempt concurrent schedule updates?
The commitAgentGraphScheduleUpdate function validates that the caller's sourceRevision matches the current stored revision. If another process has already advanced the revision, the operation throws AgentGraphScheduleRevisionConflictError and fails fast. This linearization mechanism appears in lines 3242–3250 of packages/storage/src/sqlite-session-metadata-store.ts.
Can a child Session resume after complete host restart?
Yes. The three-persistence design stores worktree leases in Git config, operator provisions in SQLite, and schedule revisions in agent_graph_schedule_updates. On restart, GitWorktreeChildExecutor.recover() validates live bindings against the filesystem, and the parent Session reloads the current schedule revision via currentAgentGraphScheduleRevision. If all components match, the child resumes execution at the exact turn where it stopped.
Why does Maka use Git worktrees instead of container filesystems or clones?
Git worktrees provide copy-on-write efficiency (sharing the source repository's object database), deterministic branch isolation through the lease system, and native Git operations for patch application and history manipulation. The maka/subagent/<suffix> branch naming convention and config-based lease tracking enable the runtime to reconstruct exact filesystem states without full repository duplication.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →