| name | exclusive-lock-dispatch |
| description | Pre-dump-then-dispatch for tools holding an exclusive lock (Ghidra, migrations, single-writer caches). Use when fanning out parallel agents needing a non-concurrent resource. |
| user-invocable | false |
| allowed-tools | Read, Glob, Grep, TodoWrite |
| model | opus |
| created | "2026-04-24T00:00:00.000Z" |
| modified | "2026-07-18T00:00:00.000Z" |
| compatibility | claude-code |
| reviewed | "2026-05-09T00:00:00.000Z" |
Exclusive-Lock Dispatch
The dispatch-time pattern for tools that hold an exclusive lock during
execution. Running such a tool from multiple parallel agents is a guaranteed
failure; running the same tool's outputs through many parallel agents is
the right shape.
When to Use This Skill
| Use this skill when… | Use parallel-agent-dispatch alone when… |
|---|
| Two or more candidate agents would invoke the same lock-holding tool | No candidate agent touches a locked resource |
| A prior wave emitted lock-contention errors | Agents only read pre-computed artefacts |
| You are debating "serialise the agent or pre-dump the artefacts?" | File scopes are disjoint and lock-free |
| The tool in question is slow (decompilation, migration, compile) so re-running per agent would burn minutes | The lock holder is cheap enough to serialise without pre-dump |
Canonical Locked Resources
| Tool / Resource | Lock Behaviour | Typical Symptom |
|---|
Ghidra project (.gpr) | Single writer; second invocation fails | Project is locked by another instance |
| Database migration lock | Single writer per database | Migration tool blocks or errors |
Git index on shared checkout (.git/index.lock) | Single writer per working tree | index.lock exists / cannot git add |
Taskwarrior bulk modify (task modify, task done ranges) | Effectively single-writer for the task store | Sporadic "task database is locked" or lost edits |
| Single-writer build caches (ccache, cargo target/, Bazel action cache) | First writer serialises others | Spurious build failures or cache corruption |
| Decompiler output caches | Re-analysis on every access | Minutes-per-agent rerun when artefacts could be shared |
The Anti-Pattern
Wave plan:
Agent A: ghidra -process BIN --script ExtractStrings.java
Agent B: ghidra -process BIN --script ExtractXrefs.java
Agent C: ghidra -process BIN --script ExtractStructs.java
Dispatched in parallel.
Second invocation refuses to open the project. The orchestrator receives
two "failed" returns and, without this skill's discipline, dispatches
more agents to "retry" — multiplying the lock contention.
The Pattern
Step 1 — One serialised run emits every artefact
Run the locked tool exactly once (or once per distinct artefact kind),
writing everything downstream agents will need into gitignored scratch.
Keep the outputs under a stable path that the brief can reference:
tmp/decomp/strings.txt
tmp/decomp/xrefs.json
tmp/decomp/structs.json
tmp/ghidra/analysis.log
The pre-dump agent runs alone in its wave. Its return contract includes
the artefact paths as "produced" so downstream waves can cite them.
Step 2 — Downstream agents read, do not re-analyse
Parallel agents in the next wave take the pre-computed artefacts as input
and produce their implementation slabs from those. No lock-holder
invocations, no re-analysis, no contention.
Briefs must reference artefacts by path:
"Input artefacts: tmp/decomp/strings.txt, tmp/decomp/xrefs.json.
Treat as read-only. Do not re-run Ghidra."
Step 3 — Wave boundaries enforce exclusivity
The orchestrator never places two lock-contenders in the same wave.
workflow-wave-dispatch handles the scheduling; this skill is the
pre-work that makes wide parallelism possible afterwards.
When to Pre-Dump vs Dispatch Directly
| Situation | Decision |
|---|
| N ≥ 2 candidate agents would each need a fresh analysis of the same source | Pre-dump: one serialised run, then fan out |
| Exactly one agent needs the lock and no siblings do | Dispatch directly: the lone agent serialises itself |
| Lock holder is fast (< 10s) and agents need fresh state | Dispatch serially: skip pre-dump, run agents one at a time |
| Lock holder is slow and agents need only a stable snapshot | Pre-dump: amortises the cost across the fan-out |
The pre-dump cost is paid once. Serialising N agents pays the lock cost
N times and removes any parallelism benefit.
Ghidra Specifics
Ghidra is the most common pre-dump target. The 12.x release changed
scripting:
| Concern | Current-as-of-2026 Answer |
|---|
| Scripting language | .java post-scripts (Jython removed in 12.x) |
| First-time vs re-run | -import on first run; -process once the binary is in the project |
| Skip analyzers on re-run | -noanalysis |
| Headless wrapper | analyzeHeadless <project_dir> <project_name> |
| Output destination | Post-script writes to stdout or to a file under tmp/ |
A typical pre-dump recipe:
analyzeHeadless tmp/ghidra/ myproj -import path/to/bin \
-postScript ExtractEverything.java tmp/decomp/
analyzeHeadless tmp/ghidra/ myproj -process bin -noanalysis \
-postScript RefreshStrings.java tmp/decomp/
Taskwarrior Specifics
The ~/.task/ store is single-writer in practice. Dispatching five
agents to each task modify different filters produces sporadic
"database is locked" errors and, worse, silently lost edits when one
agent's write races another's.
The rule is the same: one orchestrator-owned agent (or the orchestrator
itself) performs the bulk mutation, derived tasks the parallel siblings
need are emitted to gitignored scratch (tmp/tasks.json), and the
parallel wave reads from scratch.
Quick Reference
Pre-Dispatch Checklist
Common Mistakes
| Mistake | Correct Approach |
|---|
| Dispatching N agents that each run the locked tool | Pre-dump once, fan out on artefacts |
| Retrying the locked agent on failure | Diagnose the lock, then either serialise or pre-dump |
Committing tmp/decomp/ or tmp/ghidra/ | .gitignore the scratch directory |
| Briefing "and run Ghidra again to double-check" | Once the artefacts exist, treat them as authoritative |
Related
parallel-agent-dispatch — overall dispatch contract; §Wave Splits cites this skill
workflow-wave-dispatch — wave scheduling between lock-holder and parallel waves
.claude/rules/parallel-safe-queries.md — commands that exit 1 on empty, a different form of parallel foot-gun
Evidence: six-wave renderer landing shipped with zero lock-contention
retries after adopting pre-dump for the decompiler and the task queue.
Before this discipline, ad-hoc parallel dispatches frequently consumed
an entire wave recovering from lock errors.