Modern coding-agent workflows often run several agents in parallel. Each
agent works in its own Git worktree and branch, while all changes eventually
need to land on a shared target branch such as main.
This model provides isolation and speed, but introduces a difficult question:
How can multiple agents work concurrently without losing commits,
overwriting changes, or silently creating a semantically broken
integration?
This article presents the design of the Integration Guard, the subsystem implemented in Vibe Kanban Alternative, an independent, self-hosted fork of Vibe Kanban, to coordinate parallel agents and safely integrate their work.
The problem with parallel worktrees
A typical setup looks like this:
Each agent has its own isolated filesystem and branch. This prevents agents
from directly modifying each other’s working directories.
However, the target branch can change while an agent is still working:
Agent A starts at main = H0
Agent B completes and updates main = H1
Agent A finishes using its original branch
Agent A now needs to integrate into H1
A naïve implementation usually chooses one of these approaches:
- Force the agent to rebase before merging.
- Let the agent update the target branch directly.
- Use a temporary filesystem lock.
- Compare only filenames.
- Assume Git conflicts are the only problem.
Each approach has weaknesses.
A rebase is not always necessary. If Agent A changes auth.rs and Agent B
changes billing.rs, their work can usually be integrated safely even though
main advanced.
A temporary lock such as /tmp/vk-merge-lock does not coordinate separate
backend processes reliably.
A blind reference update can silently overwrite another agent’s commit.
And Git does not detect every semantic conflict. Two agents can modify
different lines in the same function and still produce incompatible behavior.
The Integration Guard architecture
The system separates three responsibilities:
1. Agent Activity Observer
The observer exposes which agents are currently active, what they intend to
change, and which workspaces they belong to.
A declaration can include:
- Agent name
- Execution owner
- Workspace
- Intent
- Expected files
- Expected symbols
- Semantic dependencies
- Execution ID
- Lease expiration time
The UI can then show information such as:
Agent A — implementing merge_changes in crates/git/src/lib.rs
Agent B — updating complete_workspace_card in crates/mcp/src/...
This information is available through the backend and MCP, rather than
relying on Mem0 or an agent’s conversation history.
### 2. Soft reservations
Agent declarations are intentionally soft reservations.
If Agent A declares auth.rs and Agent B declares auth.rs, Agent B is warned,
but is not automatically blocked.
This is important because the developer may know that the two agents are
working on independent sections of the same file.
The system therefore separates:
- Awareness during development
- Enforcement during integration
Agents can continue working in parallel. The Integration Guard performs the
final validation before writing to the shared target branch.
3. Integration Guard
The Integration Guard is responsible for the short critical section where a
branch is validated and integrated.
It uses a database-backed lease scoped to the repository. This serializes the
validation and Git write across backend processes.
The lease prevents two independent backend requests from simultaneously
validating the same target and then racing to update it.
The HEAD-aware integration algorithm
The central idea is to use the task’s original branch point as the common
ancestor.
Let:
- H0 = original common ancestor between the task branch and target branch
- Ht = current target branch HEAD
- Ha = current agent branch HEAD
The Integration Guard computes:
task_diff = diff(H0, Ha)
target_diff = diff(H0, Ht)
The complete flow is:
The important detail is that an advanced target branch does not automatically
force a rebase.
Independent changes
Suppose:
H0: initial project state
Agent A: changes auth.rs
Agent B: changes billing.rs
Ht: includes Agent B's changes
Ha: includes Agent A's changes
The three-way merge can combine both changes:
H0
├── target_diff: billing.rs
└── task_diff: auth.rs
Result:
├── billing.rs
└── auth.rs
Agent A does not need to rewrite its branch history merely because Agent B
finished first.
Real textual conflicts
If both agents modify the same lines or incompatible hunks, Git reports a
conflict.
The Integration Guard then:
- Does not move the target branch forward
- Does not mark the card as Done
- Returns a structured conflict
- Leaves the card open for review
The operator can then decide whether to resolve the conflict manually, rebase
intentionally, or change the task scope.
Semantic conflicts beyond Git
Git detects textual overlap. It does not understand contracts, APIs, or
behavior.
For example:
Agent A changes:
UserService::create_user()
Agent B changes:
API code that depends on the return value of create_user()
These changes may touch different files and different lines, yet still be
incompatible.
The current semantic detector uses declared dependencies:
This is intentionally conservative. It is not a full AST or behavioral
analysis system, but it catches a class of conflicts that file-level
comparison cannot.
A semantic conflict is reported before Git writes to the target branch.
Why Mem0 is not the coordination layer
Mem0 is useful for durable project knowledge:
“The merge API now requires a validation step.”
“This module owns the authentication contract.”
But it is not suitable for real-time coordination because it can be:
- Asynchronous
- Temporarily unavailable
- Stale
- Inconsistent with the current transaction state
The system therefore uses:
Sources of truth
- Current active agents: Database
- Work declarations: Database
- Leases and reservations: Database
- Merge serialization: Integration Guard lease
- Durable architectural decisions: Mem0
- Operator visibility: Backend API and UI
Mem0 stores semantic memory. The database stores current state.
The pipeline integration
Previously, a pipeline could instruct an agent to manually:
- Rebase its branch
- Create a commit
- Update the target ref
- Use a temporary merge lock
- Verify the result by checking the moving branch tip
That approach put repository coordination logic inside an agent prompt.
The new pipeline contract is simpler:
Agent completes implementation and verification
↓
Agent calls complete_workspace_card
↓
Backend invokes Integration Guard
↓
Guard validates and integrates safely
↓
Card moves to Done only after success
The agent no longer needs to know how the target branch is updated.
The pipeline stage is now named:
Integration Guard → Done
The agent is explicitly instructed not to manually rebase, update refs, or
use temporary locks.
The technical result may still be a single integration commit, but the
responsibility belongs to the backend integration layer rather than the
agent.
Concurrency control
The database lease protects the critical integration sequence:
This prevents the classic race:
Request A reads main = H1
Request B reads main = H1
Request A writes main = H2
Request B writes main = H3
Without serialization, the second operation may be based on stale state.
Failure behavior
The Integration Guard follows a strict rule:
A card is marked Done only after the target branch has been successfully updated.
Typical outcomes
- Target advanced with independent changes: Three-way integration succeeds.
- The same lines changed: Git reports a conflict and the card remains open.
- A declared semantic dependency overlaps: The merge is blocked for review.
-
Another integration is active: The request waits or returns
integration_in_progress. - The target worktree is dirty: Integration is refused.
-
Integration succeeds: The declaration is released and the card moves to
Done.
This makes failure visible instead of silently converting an incomplete
integration into a completed card.
Testing strategy
The implementation includes automated Git safety tests for:
- Target branch advancing before integration
- Independent changes being merged successfully
- Delete-versus-modify conflicts
- Base reference remaining unchanged after a conflict
- Dirty target worktrees
- Concurrent integration safety
The repository also contains a manual acceptance runbook for testing with two
real agents:
- Start Agent A in Workspace A.
- Confirm its declaration appears before the first edit.
- Start Agent B in Workspace B.
- Confirm both agents are visible in the Active Agents panel.
- Declare a semantic dependency conflict.
- Attempt integration while both declarations are active.
- Confirm the merge is blocked.
- Release Agent B’s declaration.
- Retry integration.
- Confirm the target branch changes only after successful validation.
This manual test is important because it crosses real process boundaries:
- Backend
- Database
- MCP
- Executor
- UI
- Git worktrees
Current limitations
The system is intentionally conservative and local-first.
The semantic detector currently relies on declared files, symbols, and
dependencies. It does not replace:
- AST analysis
- Type checking
- Integration tests
- Human review
- Product-level reasoning
The UI currently presents active work through a polling activity panel.
Future improvements could include:
- Event-driven activity updates
- Richer symbol extraction
- Automatic dependency discovery
- Historical integration timelines
- Conflict visualization
- Strong reservations for critical symbols
Conclusion
Parallel coding agents are valuable only if their work can be integrated
safely.
The Integration Guard addresses this by combining:
- Real-time agent observability
- Soft work declarations
- Database-backed integration serialization
- HEAD-aware diff calculation
- Semantic overlap detection
- Git three-way integration
- Explicit conflict handling
The key design decision is simple:
An advanced target branch is not automatically a reason to rebase. Compare the task against its original branch point, let Git perform a three-way integration, and require review only when there is a real textual or semantic conflict.
This allows multiple agents to work independently while keeping the shared
target branch protected, predictable, and auditable.
The main implementation lives in:
-
crates/server/src/routes/workspaces/git.rs— Integration Guard flow -
crates/git/src/lib.rs— Git diff and three-way integration logic -
crates/db/src/models/agent_work.rs— Agent work declarations -
crates/db/src/models/integration_guard.rs— Repository integration lease
The complete implementation is available on GitHub.
Feedback and technical discussion are welcome in the repository issues.





Top comments (0)