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 refine while 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.db is per-machine, so each teammate sees different audit results for the same site
  • Nobody knows who is running what, so two crosslink runs 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 services on 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 -e the newsroom repo on their machine
  • Read this page and Getting Started end-to-end
  • Set up ANTHROPIC_API_KEY in .env (their own key, never shared)
  • Run python -m wire.chief gsc-setup and wait for data to succeed at least once
  • Read the current _ownership.yml or ask who owns what
  • Run python -m wire.build to 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