Appendix A - 13. Agent registry (append-only log + marker cache)

The Structure of Agent registry (append-only log + marker cache) — its shape at a glance:

Every lifecycle tool dual-writes the append-only log and a fast marker cache; the log is authoritative, and a cleanup gate queries a chain of it before reclaiming anything.

flowchart LR
  Tools[Lifecycle tools] -->|dual-write| Log[(Append-only registry)]
  Tools -->|dual-write| Cache[(Marker cache)]
  Log -->|authoritative| Gate{cleanup / tombstone gate}
  Cache -->|fast index| Gate
  Gate -->|marker present = live| Refuse([Refuse to reclaim])

Accessible description: every lifecycle tool dual-writes an append-only registry and a fast marker cache; the registry is authoritative and the cache a fast index; a cleanup or tombstone gate reads them and refuses to reclaim any agent whose live marker is present.

Projected from the catalogue entry lifecycle-and-observability / Agent registry (append-only log + marker cache).

On this page: Intent · Motivation · Applicability · Structure · Sample Code · Consequences · Example use within DocAble · Related Patterns

Intent

Intent — An append-only registry, dual-written by every lifecycle tool, that is the authoritative record of which agents are in flight, so cleanup, tombstone, and merge decisions read a fact instead of guessing from filesystem timestamps.

Motivation

With a fleet of concurrent agents living in worktrees, "which agents are live right now?" is the central question for every reclaim decision: cleanup, tombstoning, merge readiness. Answer it by scanning worktree directories and comparing mtimes and you get a heuristic that races with live agents: an agent mid-work can look identical to a stale one and have its worktree destroyed under it (the worktree-destruction-mid-flight incident). The failure is unsafe reclaim of live work, and it recurs on every cleanup pass.

Applicability

Structure

The Structure diagram appears at the top of this page.

Sample Code

Liveness becomes a lookup against a recorded fact, not an inference from a timestamp. Every lifecycle tool appends to the log; a reclaim gate reads it and refuses to touch an agent still marked live — the recorded fact cannot race the way an mtime can.

import json, os

REGISTRY = "agent-registry.jsonl"

def record(agent_id: str, event: str) -> None:
    with open(REGISTRY, "a") as f:                    # append-only: every tool dual-writes here + a marker
        f.write(json.dumps({"agent": agent_id, "event": event}) + "\n")
    open(f".markers/{agent_id}", "w").close() if event == "dispatched" else None

def is_live(agent_id: str) -> bool:
    state = None
    for line in open(REGISTRY):                        # registry wins over the cache on any divergence
        row = json.loads(line)
        if row["agent"] == agent_id:
            state = row["event"]
    return state == "dispatched"

def may_reclaim(agent_id: str) -> bool:
    return not is_live(agent_id)                       # gate consults the fact before any destructive op

Consequences

Example use within DocAble

Contents
© James C. Davis, 2026–present