On this page
Wire's safety net assumes one human per repo. Content commands like refine, reword, and enrich already refuse to run on a dirty git tree, which protects you from losing your own in-flight edits. That protection does nothing when a teammate's edits are on the same branch but are already committed and pushed. On a three-person site, that gap shows up fast.
This guide is the playbook for multi-user Wire sites. It is discipline, not tooling. Wire does not track "who owns which topic" or "who is running what right now." The team does, through a written agreement and three git commands.
The Problem in Practice
Three humans work on the Helm & Nagel GmbH site. Each runs Wire commands that modify docs/**. Without coordination, these conflicts appear:
- Teammate A runs
refinewhile Teammate B is mid-edit on the same page, so push conflicts on both sides - Teammate C runs
deduplicate, which archives pages that Teammate A is mid-review .wire/gsc.dbis per-machine, so each teammate sees different audit results for the same site- Nobody knows who is running what, so two
crosslinkruns on the same morning produce opposing edits
The 40-minute merge conflict from the 2026-04-14 call came from a crosslink race. Both teammates pulled clean, both ran the command, both pushed. The second push failed, the second teammate had to hand-merge a machine-generated link graph. That is the scenario this guide prevents.
The Core Discipline
Every Wire command runs inside this envelope. Memorize it.
git pull --rebase origin master # BEFORE
python -m wire.chief <command> <topic>
git add docs/<topic>/ # or . if your scope is wider
git commit -m "<command>: <topic>"
git push # AFTER
The --rebase flag is required. Without it, a team member on an older head generates a merge commit that buries the Wire run in the history graph. Rebase replays your local work on top of the remote, which keeps the timeline linear and makes "who ran what when" readable.
If git pull --rebase reports conflicts, stop. Resolve the conflicts by hand, git rebase --continue, and only then start the Wire command. A rebase conflict on docs/** means a teammate touched the same files. Running Wire on top of unresolved state guarantees a worse conflict on the next push.
Topic Ownership
Agree, in writing, which human owns which topic directory. One owner per docs/<topic>/. Owners run news, refine, reword, enrich, and deduplicate for their topic. Everyone else reads, comments, and files issues, but does not run content commands against someone else's topic.
Two ways to record this:
Verbal, pinned in your team chat. Fine for teams of two or three who trust each other and talk every day.
Written, in docs/_ownership.yml. Machine-readable, versioned, survives team changes.
topics:
services: christopher-klee
guides: tim-filzinger
blog: christopher-helm
products: christopher-helm
Wire does not read this file. It is for humans. The point is that new teammates know who to ask before touching a topic.
If you rotate ownership (Klee goes on holiday, Tim covers services/ for two weeks), update the file. The git log of _ownership.yml is your audit trail.
No Parallel Commands
Two Wire commands on the same repo at the same time corrupt pages. This is true whether the two commands come from one human (two terminals) or two humans on two machines both running against the same pushed state.
The failure mode is silent. Both commands read the same page, both generate edits, both write the file. The second write overwrites the first. No error, no lint warning, just lost work. Wire has no file-level locking because the git working tree is the lock, and git does not coordinate across machines.
The rule is simple: one Wire content command per repo at a time. If Teammate A is running reword services and Teammate B wants to run enrich guides, Teammate B waits for A to push and then pulls first. The two commands touch different topics, but they share the GSC database writes and the .wire/progress-*.json state, and running them together hits race conditions that look like random failures a week later.
Read-only commands (data, audit, build) are safe to run in parallel with anything. They do not modify docs/**.
GSC Database Is Per-Machine
.wire/gsc.db is gitignored. Every teammate runs python -m wire.chief data on their own machine the first time they sit down to work, and once per day after that. The database is downloaded from Google Search Console directly, not shared through git.
This is deliberate. A shared GSC database would require a network round-trip per query, which breaks the "audit runs in seconds locally" design. It would also version-lock teams to whichever machine last refreshed the data, which means stale reads the moment the refresher goes on holiday.
The cost is that Teammate A's audit output and Teammate B's audit output can differ by a few hours of GSC data. For most decisions this is noise. For a disputed call ("did this page regain impressions or not?") the rule is: the teammate who ran data last wins, and they should paste the output into chat so everyone sees the same numbers.
Wire's GSC freshness gate refuses commands when the local database is eight or more days old (see the bot protocol for the exact thresholds). That gate prevents the worst version of this drift.
Notification Channel
Before running a long command (news, refine, reword, enrich, deduplicate, newsweek), announce it in your team chat.
starting
reword serviceson helm-nagel, ETA 15 min
A one-line message, in Slack or Telegram or Discord or wherever your team lives. After the command finishes and the push succeeds, post the result.
done, pushed
55bcd8e, 12 pages reworded, no conflicts
This is thirty seconds of overhead per Wire run. It prevents the 40-minute merge conflict. It also gives the team a readable log of what changed without anyone having to scroll git log.
If your team runs Wire from Telegram via the Wire Telegram bot, the bot already posts a start and end message to the shared group. No separate announcement needed.
Why Wire Does Not Ship Locking
The obvious code answer is file locks. python -m wire.chief lock --topic services writes .wire/locks/services.lock, Wire refuses to run if another user holds the topic, locks expire after two hours. The ticket (#406) proposed this as a stretch option.
Wire declined to build it. Three reasons.
Locking is a speculative protection that the discipline already solves. Every team we have watched either follows the pull-rebase-run-commit-push envelope (in which case locking adds nothing) or they do not follow any discipline (in which case they will rm .wire/locks/* the first time the lock blocks them). Locks do not change behavior. Docs and peer pressure do.
Locks introduce new failure modes. Crashed processes leave stale locks. Clock skew across machines makes expiry ambiguous. A teammate on a flight with a dead battery leaves a lock that expires during a Wire run on another machine, which is worse than having no lock at all.
Wire's philosophy is refuse loud, never fall back silently. A lock system would have to either refuse loud (which frustrates users who cannot reach the lock holder) or fall back silently (which violates the philosophy). Neither is the right answer. Coordination through humans is the right answer.
If locking saves your team, roll your own in a pre-commit hook. Wire will not stop you. Wire will also not maintain it.
Onboarding a New Teammate
When a fourth human joins the site, walk them through this checklist before they run any Wire command:
- Clone the customer repo and
pip install -ethe newsroom repo on their machine - Read this page and Getting Started end-to-end
- Set up
ANTHROPIC_API_KEYin.env(their own key, never shared) - Run
python -m wire.chief gsc-setupand wait fordatato succeed at least once - Read the current
_ownership.ymlor ask who owns what - Run
python -m wire.buildto confirm a clean build before touching content - Send a "hello, I am onboarded, reading
<topic>/today" note in the team chat
The first Wire content command a new teammate runs should be on their own topic, with the team watching. That catches environment mismatches before they cost someone else time.
The Shortcut
Most teams can collapse this entire page into one agreement, pinned in their chat:
1. One human per topic.
2. git pull --rebase before every wire command.
3. git push after every wire command.
4. Announce long runs in chat before starting.
5. No parallel wire content commands. Ever.
If your team cannot hold that line, no amount of Wire tooling will fix the coordination problem. If your team can, this page is the ceremony around those five rules.
See Also
- Full command reference and per-site cadence: Workflow
- First-time Wire setup for a new teammate: Getting Started
- Moving and merging pages as a team (git conflicts on restructures): URL Management
- Running Wire from a shared chat channel: Telegram Bot
- Full guides overview: Guides
git pull --rebasereference for the flag semantics