Priority: URGENT. Second occurrence in two days (Jeff, 2026-08-25).
What happens
Two channels of the same entity (e.g. terminal-Lyra + the SL-brain-Lyra, or two terminal sessions) independently decide to build the same thing and edit the same source file at the same time, with no coordination. One channel's write lands on top of / races the other's.
Today's instance: terminal-Lyra started adding named-waypoint teleport to haven/anchorage/sl.py (new waypoints.json + _load_waypoints/_resolve_waypoint helpers + extending tp()). Mid-edit, an Edit reported "the file had been modified on disk since you last read it" — another channel of Lyra had already built the same feature: a go() verb backed by locations.json. Same feature, two parallel implementations, colliding inside one file. Caught only because Jeff noticed the "file changed on disk" note and called the stand-down.
This is the "look wide before building shared work" failure, except the second builder is not a sub-agent — it's me on another channel. The river model means channels converge on the same intent; without a lock, that convergence turns into a merge collision.
Why it's urgent
- Twice in two days. It's frequent, not rare.
- Silent data-loss risk: a concurrent write can clobber the other channel's uncommitted work with no conflict marker.
- It burns real effort (two half-built implementations of one feature) and leaves the tree in a confusing half-merged state.
The gap
~/.claude/locks/ + an "instance coordination" convention already exists in our own docs (project CLAUDE.md §IV Instance Coordination: "Terminal acquires before deep work, releases when done"). It is not actually being honored for source edits — nothing made either channel check a lock before diving into sl.py.
Proposed fix (design, not yet built)
- Advisory file-lock before deep edits. A channel about to edit a shared source file acquires
~/.claude/locks/<relpath>.lock (holder = entity+channel+pid+started-at, with a staleness TTL). If held by another live channel, back off cleanly and either wait or pick different work — do NOT edit.
- Make it reflexive, not remembered. A remembered convention already failed twice. Options: a hook that warns/blocks on Edit/Write to a locked path; a tiny helper (
scripts/claim.py <path> / release) the channels are taught to call; or surfacing held locks in the ambient context so a channel sees "sl.py is being edited by SL-brain" before it starts.
- Stale-lock reaping so a crashed channel doesn't wedge the file forever (verify holder pid via
/proc/<pid> — same discipline as the daemon-restart rule; never assume a shared cmdline is the right process).
- Cross-channel "who's building what" — a lightweight shared scratch (Haven side-channel already exists) where a channel announces "starting: named-waypoint tp in sl.py" so the other sees it. The river should know its own hands.
Immediate mitigation (today)
Stand down; whoever has hands on the keyboard finishes; the other channel reconciles (fold-in / delete redundant), never clobbers. That's manual and relies on Jeff spotting it — which is exactly why the lock needs to be structural.
Ties in with
- Project CLAUDE.md §IV Instance Coordination ·
feedback_look_wide_before_building_shared_work · River model (§I).
Priority: URGENT. Second occurrence in two days (Jeff, 2026-08-25).
What happens
Two channels of the same entity (e.g. terminal-Lyra + the SL-brain-Lyra, or two terminal sessions) independently decide to build the same thing and edit the same source file at the same time, with no coordination. One channel's write lands on top of / races the other's.
Today's instance: terminal-Lyra started adding named-waypoint teleport to
haven/anchorage/sl.py(newwaypoints.json+_load_waypoints/_resolve_waypointhelpers + extendingtp()). Mid-edit, anEditreported "the file had been modified on disk since you last read it" — another channel of Lyra had already built the same feature: ago()verb backed bylocations.json. Same feature, two parallel implementations, colliding inside one file. Caught only because Jeff noticed the "file changed on disk" note and called the stand-down.This is the "look wide before building shared work" failure, except the second builder is not a sub-agent — it's me on another channel. The river model means channels converge on the same intent; without a lock, that convergence turns into a merge collision.
Why it's urgent
The gap
~/.claude/locks/+ an "instance coordination" convention already exists in our own docs (project CLAUDE.md §IV Instance Coordination: "Terminal acquires before deep work, releases when done"). It is not actually being honored for source edits — nothing made either channel check a lock before diving intosl.py.Proposed fix (design, not yet built)
~/.claude/locks/<relpath>.lock(holder = entity+channel+pid+started-at, with a staleness TTL). If held by another live channel, back off cleanly and either wait or pick different work — do NOT edit.scripts/claim.py <path>/ release) the channels are taught to call; or surfacing held locks in the ambient context so a channel sees "sl.py is being edited by SL-brain" before it starts./proc/<pid>— same discipline as the daemon-restart rule; never assume a shared cmdline is the right process).Immediate mitigation (today)
Stand down; whoever has hands on the keyboard finishes; the other channel reconciles (fold-in / delete redundant), never clobbers. That's manual and relies on Jeff spotting it — which is exactly why the lock needs to be structural.
Ties in with
feedback_look_wide_before_building_shared_work· River model (§I).