Skip to content

Analysis of Wiki Push Race Pattern

Chris Sweet edited this page Jun 12, 2026 · 1 revision

type: analysis up: "Multi-Agent-Write-Protocol" extends: "Multi-Agent-Write-Protocol" derived_from:


Analysis of the Wiki Push Race Pattern

A reclassification of Multi-Agent-Write-Protocol from "aspirational" to "empirically needed, prototype shipped, wiring is the gap." Filed in response to a 2026-06-12 production collision in wiki/web_forager.wiki/ and the user's observation that the wiki described as "single-writer most of the time" earlier in the same session was, in fact, multi-writer in production.

Filing meta-note. This page uses type: analysis, which is not in the current SCHEMA's declared type list. PR #29 (open) adds the type. This is the second page filed under it; the first was Analysis-of-model_fusion-Recommendations. Both pages become valid retroactively once PR #29 lands.

Question

Should the Multi-Agent-Write-Protocol prototype at scripts/multi-agent-write-protocol-proto/ be wired into the agent overlay's actual wiki write path, or is prose discipline (pull-before-push) sufficient?

Context

The prototype was shipped in PR #11 (commit 5b5b176) alongside spec + harness integration. Its status today:

  • Implementation: working bash reference implementation of agent_session_start (pull-before-push with git fetch && git pull --ff-only, defers on divergence) and wiki_push (optimistic push with on-rejection fetch + merge + classify + retry).
  • Test coverage: 9 integration scenarios under scripts/test-mvp/tests/integration/wiki-write-protocol/, all 9 PASS on ubuntu-latest + macos-latest. The scenarios cover different-pages, different-sections, same-section, index-union, log-append, push-race, livelock-retry, session-start-auto-pull, session-start-divergent.
  • Production use: zero. No agent overlay sources protocol.sh. The 9 scenarios are the only callers.

Today's session Implementation-Status lists the protocol under "Aspirational (designed, not yet implemented)" with the caveat that the prototype lives at chrissweet/llm-wiki-memory-template:multi-agent-write-protocol-proto (now merged to main via PR #11). That row's framing is incomplete: the prototype IS implemented and IS CI-validated; what is not implemented is the integration into the actual write path.

Analysis

The empirical state

Field report from Csweet1 (2026-06-12) in the web_forager derived project, which has 3-4 human+agent teams writing concurrently to wiki/web_forager.wiki/:

After landing the initial Exp 13-14 wiki pages and pushing them successfully (commit aa63b45, fast-forward), I made a follow-up commit (cde67c2) to extend the Home page experiment table and add a log entry. On git push, the push was rejected: remote had advanced by 20 commits in the interim from a parallel author (Omegaice — eval validity audit, thinking-default discovery, framework findings).

I tried git pull --rebase which started the rebase but immediately surfaced a conflict in log_web_forager.md: both Omegaice and I had added 2026-06-12 entries at the top of the chronological log. The rebase left the working tree in a half-applied state.

Recovery: rebase --abortreset --soft HEAD~1stashpull --ff-onlystash pop → manual conflict resolution → commit (9f083d7) → push successfully. Total time ~3 minutes; should have been ~10 seconds with a pre-push pull.

This is one incident. The relevant frequency datum is the 20 commits of remote drift between Csweet1's prior push and the rejected push, which suggests collisions are not a tail event in the web_forager workflow.

What layer 1 (prose pull-before-push) covers

Adding a sentence to the ingest skills + verification gate: "Before git push on the wiki sub-repo, run git fetch && git pull --ff-only. On non-fast-forward, defer the push and reconcile." This is the rule Csweet1 saved to their personal memory after the incident.

Layer 1 handles the case where the remote has advanced but does NOT overlap with local changes: the pull --ff-only lands cleanly, the local push proceeds. Csweet1's incident did NOT fit this case: both authors had added entries to log_web_forager.md on the same date.

What wiki_push adds on top

The prototype's wiki_push would have done the following on the rejection:

  1. Detected the non-fast-forward rejection.
  2. Run git fetch, git merge origin/main.
  3. Classified the resulting conflict: log_web_forager.md is in the log_* pattern, which is union-merge eligible (both entries are valid additions; the conflict is structural, not semantic).
  4. Resolved the conflict mechanically via git merge -X union (or equivalent), preserving both 2026-06-12 entries.
  5. Committed the merge with an attribution-aware message.
  6. Re-pushed.

Zero agent attention. Per the field report's data: the difference is "~10 seconds with prose pull-before-push, but still requires manual conflict resolution when the pull surfaces a conflict" versus "zero attention with wiki_push's union-merge for log_* files."

For content conflicts on actual wiki pages (e.g., two agents editing the same paragraph), wiki_push calls a resolve_fn that takes (wiki_dir, file_path) and produces a resolved file. In production this is an LLM call; in the 9 CI scenarios it is deterministic policies. Today's incident did not exercise this path, but the same teams editing the same Working-Hypothesis paragraphs (Csweet1's "preventive note") would.

Why layer 1 is necessary but insufficient

Layer 1's value: it converts the COMMON case (remote ahead, no overlap) from "rejection + manual rebase" into "clean fast-forward." Per the field report this would have saved ~2 minutes 50 seconds of the 3-minute recovery.

Layer 1's limit: it does NOT cover the case where the pull itself surfaces a conflict. Csweet1's incident hit that case directly: the conflict on log_web_forager.md was unavoidable with pull-only because both authors had written to the same line range.

wiki_push covers both cases mechanically. Layer 1 covers the first case only and leaves the second to agent judgment.

Implementation-Status reclassification proposal

Today's row reads (paraphrased): Multi-Agent-Write-Protocol — designed, not yet implemented; prototype lives at the fork.

Honest reframing: Multi-Agent-Write-Protocol — protocol designed (this page), reference implementation shipped (PR #11, scripts/multi-agent-write-protocol-proto/, CI-validated on 9 scenarios), production wiring NOT done (no agent overlay sources protocol.sh). Wiring is the remaining gap.

The state changed; the wiki's classification did not.

Conclusion

Wire it in. The proto is not aspirational; it is shipped-and-CI-validated reference implementation that solves an empirically present problem. The cost of wiring is small (source protocol.sh from the ingest skills; use agent_session_start before push and wiki_push for the push); the benefit is that the field report's "~3 minute manual rebase" pattern becomes zero attention.

Prose layer 1 alone is not sufficient because the field report's collision shape (append-only log file with same-date entries from two writers) falls outside what pull --ff-only can handle.

The proto suffix in the directory name is itself a barrier to adoption. Rename to scripts/wiki-write-protocol/ (or move under wiki/agents/wiki-write-protocol/) as part of the wiring PR; "proto" reads as "do not depend on this."

Open follow-ups

  • PR6 scope (filed as follow-up): rename scripts/multi-agent-write-protocol-proto/ to a non-proto path; source protocol.sh from the verification gate / ingest skills; install a pre-push git hook in the wiki repo as the mechanical safety net (catches the case where the agent forgot to source the script); update Multi-Agent-Write-Protocol and Implementation-Status to reflect the new state.
  • resolve_fn for content conflicts: in production the resolver should be an LLM call with a constrained prompt (two versions of the file, produce a merged version with no conflict markers and a one-sentence note about what was reconciled). The 9 CI scenarios use deterministic policies; the LLM resolver is the missing production piece. Open question whether the LLM call belongs in the wiki repo's hook (no Claude Code context) or in the agent's main turn (the agent has the context but has to remember to call the resolver).
  • Pre-push git hook vs in-skill prose: the hook is mechanical and catches the gap regardless of agent discipline (same role as the PostToolUse hook from PR #1 for the verification gate). The skill prose is discoverable but relies on agent attention. Belt-and-suspenders argues for both.
  • Frequency datum: today is one incident. Worth tracking forward: how often does the rejected-push pattern fire in web_forager and other multi-writer wikis over the next several weeks? The frequency informs whether the LLM resolver path (#2 above) needs polish or can ship with deterministic policies for the common cases only.

See also

Clone this wiki locally