Coord layer
The coord layer was extracted from years of running multiple Claude Code / Cursor / Codex sessions against the same checkout. It solves three failure modes that hit you the moment you run more than one agent at a time:
- Commit contamination: Agent A’s unstaged changes get swept into Agent B’s commit
- Overlapping edits: both agents edit the same file, and the second write clobbers the first
- Submodule-pointer thrash: Agent A bumps a submodule pointer, and Agent B unwittingly folds the wrong bump into a commit
How it works
Section titled “How it works”Three primitives on disk, plus hook scripts wired into Claude Code, Cursor, Codex, and git:
.harnery/ledgers/v3/: canonical append-only ledger, validating catalog, and immutable control pair.harnery/active/<id>.json: disposable generation-bound caches projected from the ledger.harnery/journal/: operator and peer messages that remain separate from event authority
The hooks fire before an edit lands (claim time) and before a commit lands (commit time), block conflicts, and record structured V3 events. The web UI reads the same validated projection.
The agent sees nothing when nothing’s going wrong. Single-agent runs are indistinguishable from no coord layer at all.
Resumed sessions keep their name; forked ones get a new one
Section titled “Resumed sessions keep their name; forked ones get a new one”Names are assigned per instance, and the assignment is idempotent, so resuming a session recovers the name it already had. Forking is different. When an adapter branches a conversation to try a second direction, it mints a new conversation id, so the coord layer sees a new session and draws a fresh name from the pool. That is the right outcome, since the branches edit files independently and each needs its own claims.
The relationship itself is recorded, not just tolerated. On Claude Code the
branch’s transcript preserves the parent’s message uuids, so Harnery detects the
parent, stamps forked_from on the branch’s name-history row, and uses it in
two places. Session-start context names the parent (“branched from agent-X’s
session…”), because the branch is about to read a transcript full of that exact
name asserting a task and file claims that are not its own. And
agents identity assume refuses a target that is the caller’s fork ancestor,
since a branch trying to become its parent is usually a session misled by its
scrollback rather than a deliberate successor; --force-ancestor overrides it
when succession is the intent. Adapters with no detectable parent signal fall
back to a generic clause stating that any different name in earlier context was
inherited. Full rationale:
ADR 0057.
One cosmetic seam remains. Adapters usually title a conversation once and never
revise it, so a forked chat keeps the parent’s title even though it is now a
different agent. Harnery cannot rename it. The first non-empty set-task of
any session prints a suggested_session_name, and that is the value to
retitle to.
Cross-machine presence
Section titled “Cross-machine presence”The primitives above are machine-local. When more than one machine shares a
repo (two people, or one person on a desktop and a laptop), presence closes
the gap: each machine publishes its live sessions to
refs/harnery/presence/<machine> on the repo’s own origin (zero config: repo access is the credential), and peers render them in the agents list,
status box, and peer tables, labeled @<machine>. An optional
end-to-end-encrypted relay upgrades latency from minutes to seconds. Remote
peers are advisory: they inform, but they do not grant or block local claim
authority. Details:
harn presence and
decision record 0016.