Coord layer
The coord layer was extracted from years of running multiple Claude Code / Cursor / Codex / OpenCode 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, OpenCode (through a plugin), 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,
Harnery finds the parent from the branch’s transcript (copied rows that keep
the parent’s session id, or the parent’s message uuids), stamps forked_from
on the branch’s name-history row, and uses it in several places. Session-start
context names the parent, and when the parent is still running it also names
the parent’s task and files and says not to end that session, because the
branch is about to read a transcript full of that exact name asserting work
that is not its own. The peer table and agents status label the parent
“your fork parent, live” and the branch “your fork”. agents identity assume,
agents end, and agents lifecycle --session-id refuse a target that is the
caller’s fork ancestor, since a branch acting on its parent is usually a
session misled by its scrollback; --force-ancestor overrides it when the
operator intends it. 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 and
ADR 0202.
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.