The coordination layer enables parallel agent operation without conflicts. S2 is proactive (prevents conflicts) not just reactive (resolves conflicts). Apply these protocols whenever multiple agents work concurrently.
With PACT Task integration, the TaskList serves as a shared state mechanism for coordination:
| Use Case | How TaskList Helps |
|---|---|
| Conflict detection | Query TaskList to see what files/components other agents are working on |
| Parallel agent visibility | All in_progress agent Tasks visible via TaskList |
| Convention propagation | First agent's metadata (decisions, patterns) queryable by later agents |
| Resource claims | Agent Tasks can include metadata about claimed resources |
Coordination via Tasks:
Before parallel dispatch:
1. `TaskList` → check for in_progress agents on same files
2. If conflict detected → sequence or assign boundaries
3. Dispatch agents with Task IDs
4. Monitor via `TaskList` for completion/blockers
S2 manages information flow between agents:
| From | To | Information |
|---|---|---|
| Earlier agent | Later agents | Conventions established, interfaces defined |
| Orchestrator | All agents | Shared context, boundary assignments |
| Any agent | Orchestrator → All others | Resource claims, conflict warnings |
TaskList |
All agents | Current in_progress work, blockers, completed decisions |
Before invoking parallel agents, the orchestrator must:
-
Identify potential conflicts:
- Shared files (merge conflict risk)
- Shared interfaces (API contract disagreements)
- Shared state (database schemas, config, environment)
-
Define boundaries or sequencing:
- If conflicts exist, either sequence the work or assign clear file/component boundaries
- If no conflicts, proceed with parallel invocation
- Persist
s2_boundaries:TaskUpdate(codePhaseTaskId, metadata={"s2_boundaries": {"agent_name": ["file_paths"]}})
-
Establish resolution authority:
- Technical disagreements → Architect arbitrates
- Style/convention disagreements → First agent's choice becomes standard
- Resource contention → Orchestrator allocates
When analyzing parallel work, emit proactive coordination signals:
S2 Pre-Parallel Check:
- Shared files: [none / list with mitigation]
- Shared interfaces: [none / contract defined by X]
- Conventions: [pre-defined / first agent establishes]
- Anticipated conflicts: [none / sequencing X before Y]
Example:
S2 Pre-Parallel Check:
- Shared files:
src/types/api.ts— Backend defines, Frontend consumes (read-only)- Shared interfaces: API contract defined in architecture doc
- Conventions: Follow existing patterns in
src/utils/- Anticipated conflicts: None
| Conflict Type | Resolution |
|---|---|
| Same file | Sequence agents OR assign clear section boundaries |
| Interface disagreement | Architect arbitrates; document decision |
| Naming/convention | First agent's choice becomes standard for the batch |
| Resource contention | Orchestrator allocates; others wait or work on different tasks |
When "first agent's choice becomes standard," subsequent agents need to discover those conventions:
-
Orchestrator responsibility: When invoking parallel agents after the first completes:
- Extract key conventions from first agent's output (naming patterns, file structure, API style)
- Include in subsequent agents' prompts: "Follow conventions established: {list}"
-
Handoff reference: Orchestrator passes first agent's key decisions to subsequent agents
-
For truly parallel invocation (all start simultaneously):
- Orchestrator pre-defines conventions in all prompts
- Or: Run one agent first to establish conventions, then invoke the rest concurrently
- Tie-breaker: If agents complete simultaneously and no first-agent convention exists, use alphabetical domain order (backend, database, frontend) for convention precedence
-
Persist
established_conventions:TaskUpdate(codePhaseTaskId, metadata={"established_conventions": {"naming": "...", "patterns": "...", "style": "..."}})
State recovery: After compaction, read the journal's
s2_state_seededevent fors2_boundariesandestablished_conventions; fall back toTaskGet(codePhaseTaskId).metadataif unavailable. See pact-state-recovery.md for the full recovery hierarchy.
All agents operating in parallel must:
- Use project glossary and established terminology
- Use standardized handoff structure (see Phase Handoffs)
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Sequential by default | Missed parallelization opportunity | Run QDCL; require justification for sequential |
| Ignoring shared files | Merge conflicts; wasted work | QDCL catches this; sequence or assign boundaries |
| Over-parallelization | Coordination overhead; convention drift | Limit parallel agents; use S2 coordination |
| Analysis paralysis | QDCL takes longer than the work | Time-box to 1 minute; default to parallel if unclear |
| Single agent for batch | 4 bugs → 1 coder instead of 2-4 coders | 4+ items = multiple agents (no exceptions) |
| "Simpler to track" rationalization | Sounds reasonable, wastes time | Not a valid justification; invoke concurrently anyway |
| "Related tasks" conflation | "Related" ≠ "dependent"; false equivalence | Related is NOT blocked; only file/data dependencies block |
| "One agent can handle it" excuse | Can ≠ should; missed efficiency | Capability is not justification for sequential |
Recovery: If in doubt, default to parallel with S2 coordination active. Conflicts are recoverable; lost time is not.
When you find yourself thinking these thoughts, STOP—you're rationalizing sequential dispatch:
| Thought | Reality |
|---|---|
| "They're small tasks" | Small = cheap to invoke together. Split. |
| "Coordination overhead" | QDCL takes 30 seconds. Split. |
Valid reasons to sequence (cite explicitly when choosing sequential):
- "File X is modified by both" → Sequence or define boundaries
- "A's output feeds B's input" → Sequence them
- "Shared interface undefined" → Define interface first, then parallel
After each specialist completes work:
- Extract key decisions, conventions, interfaces established
- Propagate to subsequent agents in their prompts
- Update shared context for any agents still running in parallel
This transforms implicit knowledge into explicit coordination, reducing "surprise" conflicts.
When dispatching agents during parallel execution, the codebase may have changed since earlier agents were briefed. Use the file tracking system to detect environment drift.
Before dispatching a new agent (when other agents have already modified files):
- Check the team's
file-edits.json(maintained byfile_tracker.py) for files modified since the session started or since the last dispatch - If files relevant to the new agent's scope were modified, include an environment delta in the dispatch prompt:
"Since your context was set, these files were modified:
src/auth.ts(by backend-coder),src/types.ts(by database-engineer). Review before making assumptions about their current state." - This is not a full re-briefing — just a delta awareness signal
When an agent completes and another agent is still running:
- Check if the completing agent modified files in the running agent's scope
- If so, send a brief
SendMessageto the running agent: "Environment changed: {file} was modified by {agent}. Verify your assumptions about it."
Skip when: Single-agent execution (no parallel agents = no drift risk).
Sequence: Database delivers schema → Backend implements ORM.
| Database Engineer Owns | Backend Engineer Owns |
|---|---|
| Schema design, DDL | ORM models |
| Migrations | Repository/DAL layer |
| Complex SQL queries | Application queries via ORM |
| Indexes | Connection pooling |
Collaboration: If Backend needs a complex query, ask Database. If Database needs to know access patterns, ask Backend.