docs: spec how several agents share one repo without clobbering each other - #54
Merged
Conversation
…other C3 has no cross-process coordination for source files. cli/tools/edit.py:20 guards same-file edits with a threading.Lock, but every Claude Code session spawns its own c3-mcp stdio server, so two sessions can tear each other's writes -- and there is no staleness check anywhere in edit.py. Nothing today stops two agents refactoring the same module for ten minutes. FleetDeck (the standalone lock daemon) cannot cover this either: its PreToolUse hook matches Edit|Write|MultiEdit|NotebookEdit, while C3 blocks those tools and routes edits through mcp__c3__c3_edit. In a C3 project its gate never fires, so the two systems currently cancel out. This is the design, not the implementation. It separates torn writes (a cross-process file lock, ~15 LOC, no daemon) from overlapping work (leases with TTL and fencing tokens, adopting FleetDeck's semantics verbatim so both systems name the same file the same way). It puts lock state in the target project rather than the caller's, so cross-project writes coordinate. It records the trap that a per-call backend fallback splits agents across two namespaces and collides them silently while still badging the repo green. Coverage is stated honestly: c3_shell running arbitrary code, non-Claude substrates, humans in editors, and repos without .c3/ are not covered and the UI must not pretend otherwise. Phasing lets the empirical question decide the expensive part -- ship the file lock and a two-line FleetDeck fix first, read the denial log, then judge whether leases earn their ~600 LOC. Claude-Session: https://claude.ai/code/session_01Sbd9NbQfDcoJvvURD7KCVf
This was referenced Jul 30, 2026
drknowhow
added a commit
that referenced
this pull request
Jul 30, 2026
…off (#58) Four merged PRs (#54-#57) had accumulated past the v2.64.0 tag, so the version no longer identified the code: the installed build reported 2.64.0 while running leases, a new tool, a new CLI command and a new Hub tab. MINOR, not patch. I earlier called this 2.64.1; that was wrong. It adds c3_locks, `c3 locks`, a Hub tab and a config section — new surface, not a fix. What ships: - Agent Locks. Two mechanisms for two different problems. A cross-process file lock stops two c3-mcp processes tearing each other's writes (and now covers create mode, which ran outside the lock entirely). Leases stop two agents doing overlapping work, carrying the intent from the edit summary so the blocked agent is told who holds the file and why. TTL is the real release mechanism, so a crashed agent cannot wedge a repo. - c3_locks tool, `c3 locks` CLI with the human-only force-release, and a Hub Locks tab that badges an unreadable project UNREADABLE rather than showing it with zero leases. - Access Guard built-in opt-out, two-key: a config entry AND a keyring attestation. Either alone leaves the built-in enforcing, so an agent that writes config.json cannot grant itself write access to ~/.claude/settings.json. The credential vault stays absolute. The changelog states coverage honestly rather than implying it: leases gate C3's own tool surfaces, and a raw c3_shell redirect, a non-Claude agent, or a human in an editor is not covered. 1805 pass, ruff clean, both version constants bumped (test_version_sync guards the pair). Claude-Session: https://claude.ai/code/session_01Sbd9NbQfDcoJvvURD7KCVf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Design spec for Agent Locks — letting several agents work in one repo, or across several C3 projects, without clobbering each other.
docs/agent-locks.md, 14 sections, house style matchingdocs/access-guard.md.Design only. No code, no behaviour change. The status line in the doc says DRAFT, not frozen.
Why
Two gaps, both live today:
cli/tools/edit.py:20guards same-file edits with athreading.Lock, but every Claude Code session spawns its ownc3-mcpstdio server — so concurrent sessions can tear each other's writes. No mtime/hash staleness check exists either.Edit|Write|MultiEdit|NotebookEdit(fleetdeck/hook.py:23), while C3 blocks those tools and routes edits throughmcp__c3__c3_edit. In a C3 project its collision gate never fires. The two systems currently cancel out.What the spec settles
c3_project(action='edit')writes across projects, and caller-scoped state would put the two agents in different files.fleetdeck/paths.py,fleetdeck/locks.py) so both systems name the same file the same way.modedecides open or closed, never a namespace switch.Coverage, stated honestly
Section 9 is a matrix.
c3_shellrunning arbitrary code, non-Claude substrates, humans in editors, and repos without.c3/are not covered, and the Hub badge must not pretend otherwise.Phasing
The expensive part is gated on evidence, not opinion:
_FileLockinedit.py— ~15 LOC, ships standalonec3_locks+ gates — ~400 LOC, gated on P2 denial dataTracked as C3 tasks
40e21392bbae,5b0f7cee2dce,f9ee34510da8,2a55f706d170(tagagent-locks; dependencies wired P3 blocked by P1+P2, P4 blocked by P3).Review focus
Section 10 (namespace trap) and Section 11 (C3 vs FleetDeck ownership) are the load-bearing decisions. Section 14 lists four open questions — implicit vs explicit lease acquisition is the one most likely to change the shape.
https://claude.ai/code/session_01Sbd9NbQfDcoJvvURD7KCVf