v0.14.0 — 同じファイルでも競合しない
「同じファイルでも、違う行なら 2 人が同時に書ける」 — 並列エージェント開発の天井を、ファイル単位の所有から行域単位へ引き上げました。
1 ファイルに 64 体をぶつけた実測
tools/coedit-bench.sh --agents 64 --lines 2000(2000 行のファイル 1 個に 64 体が同時に書き込む):
| 守り方 | 書けた担当 | 断られた | 衝突した枝 | 衝突行 | 人の手 |
|---|---|---|---|---|---|
| 守らない(素の git) | 64 | 0 | 48 | 960 | 48 |
| ファイル単位で持つ(〜v0.13) | 1 | 63 | 0 | 0 | 0 |
| 行の単位で持つ | 11 | 53 | 0 | 0 | 0 |
| 行の単位 + 交渉(v0.14) | 64 | 0 | 0 | 0 | 0 |
誇張せずに言うと: 衝突ゼロ自体は v0.13 でも達成できていました。v0.14 が買うのは並列度です(64 体中 1 体しか書けなかったのが、全員書けるようになりました)。素の git は詰めた条件でも 64 体全部が書けますが、48 枝が衝突して 960 行・48 回の手作業を要します。
どのリポジトリでも 1 コマンド
$ zai czero init # 台帳・git フック・マージドライバ・.gitattributes を一度に入れて自己診断
$ zai czero verify # 使い捨ての一時リポジトリで実際に競合を起こし、本当に止まるか実演する
$ zai czero uninstall # 入れたものだけを綺麗に戻すverify は設定を読むだけではありません。実際に競合を起こして止まることを実演します(対象リポジトリは 1 バイトも汚しません)。「入れたのに効いていない」が構造的に起こらないようにするためです。
変更点
- 断られる代わりに、近くの空いている行へ自動でずらすようになりました(
zai lease claim --shift)。1 ファイルへ 64 体をぶつける検証で、断られた件数が 53 件 → 0 件、書けた担当が 11 → 64 になります。マージ衝突は 0 件・人の手も 0 回のままです。ずらされた場合は「要求 → 実際に取れた場所」を必ず表示します(黙って別の場所を渡しません) - 「ここに足す」だけの予約ができるようになりました(
src/a.rs#@120)。関数やuseを足す作業は既存の行を 1 行も必要としないので、幅 0 で予約します。300 行のファイルに 64 体が全員入ります - 同じファイルでも、違う行なら 2 人が同時に書けるようになりました。これまでは「誰かが持っているファイルには書けない」でした。1 ファイルへ 64 体をぶつける検証で、ファイル単位の所有だと書けたのは 64 体中 1 体(63 体は拒否)でしたが、行域なら64 体全部が書けてマージ衝突は 0 件・人の手も 0 回です。
zai lease claim 'src/app.rs#L1200-1260'のように行を指定して確保します - エージェント同士が裏で認識し合うようになりました。Erlang のプロセスと同じ仕組みで、それぞれが身元(再起動したら別物として扱われる ID)とメールボックスを持ち、互いを監視します。担当を持ったまま落ちたエージェントの担当は自動で解放されるので、人が掃除する必要がありません
- 断られる代わりに「ずらす」ようになりました。要求した行域が埋まっていても、近くの空いている行域を提案して振り替えます。ただし**「ずらしてよい」と言った要求だけ**です — 行域は行番号ではなく「そこにある内容」に紐づくので、黙ってずらすと別の場所を編集させることになります
- 「いま統合したら一撃で通るか」を証明できるようになりました。複数ブランチの変更行域が離れていれば、
git mergeは必ず衝突しません。実際の git で網羅的に確かめて見逃し 0 件です。証明が立てば N 本を人手ゼロで統合します。作業ツリーを一度も触らず、最後に参照を 1 回だけ動かすので、途中で失敗しても中途半端な状態が残りません - どのリポジトリでも、一覧への追記が衝突しなくなりました。
.gitignore・CHANGELOG.md・package.jsonの依存・import宣言のような「両方の行を残すだけ」の衝突を、中身を見て自動で判定して解決します。目印を書く必要はありません。マーカ無しの検証で人が読む衝突行が 80% 減り、誤って自動解決した件数は 0 です。一覧と判断できないファイルでは素の git と 1 バイトも変わりません - 誰がどのファイルの何行目を持っているかが 1 画面で分かるようになりました。同じファイルを複数人が持っている状態を横帯で見せ、近すぎる組だけを赤枠にして「あと何行空ければ一撃で通るか」を出します
- 64 体以上で確保が「混雑しています」と断られることがあるのを直しました。待ち時間の予算が固定だったため、体数が増えると必ず足りなくなっていました。台数に依存しない待ち方へ変えています
- 行域を指定すると保護が効かなくなる不具合を直しました。誰かがファイル全体を持っていても、行を指定した確保が通ってしまい、重なる 2 つの行域も両方通っていました
- 全文置換で他人の担当を黙って消せる不具合を直しました。200 行のファイルを 2 行に置き換えると「触れたのは 1〜2 行目」と判定され、他の行の持ち主を巻き込んでいました
- これから書く場所を予約すると、その予約が消えて別人に取られる不具合を直しました。まだ短いファイルへ「1〜10 行目」を確保しても、実際には 1 行目しか押さえられておらず、重なる「5〜15 行目」が通っていました
- エージェントが行を上に足すと、下にいる担当の位置がずれる問題を直しました。担当は行番号ではなく「そこにある内容」で覚えるようになったので、他の人が上に 10 行足しても同じ場所を指し続けます
- どのリポジトリでも 1 コマンドで導入できるようになりました。
zai czero initで台帳・git フック・マージドライバ・.gitattributesが一度に入り、入れた直後に自己診断まで走ります。zai czero doctorは段ごとに理由と直し方を出し、zai czero verifyは使い捨ての一時リポジトリで実際に競合を起こして、本当に止まるかを実演します。zai czero uninstallで入れたものだけを綺麗に戻します(他人が書いた.gitattributesの行や既存のフックは無傷です) - 離れた行を担当する 2 人が、どちらもコミットできなかったのを直しました。コミット前の点検が行番号を見ておらず、同じファイルというだけで両方止めていました。あわせて点検を 685 倍速くしています(400 ファイル × 200 担当で 5.04 秒 → 7.4 ミリ秒)
- 統合の順番決めが、24 体を超えると裏目に出ていたのを直しました。「手が止まるまでに自動で入る本数」が 2 → 1 に減っていました。24 体で 1 本 → 10 本、32 体で 1 本 → 11 本になります。ただし衝突の総数は変わりません — 減るのは手が止まる回数だけです
- 互いに干渉しないブランチなら、順番を決めずに一撃で統合できるようになりました。24 本が互いに素なら「順序は不要」と出して、そのまま人手 0 回で入ります
数字と線引き(効かない条件も含めて)は docs/conflict-zero.md にあります。
検証: 全テスト 4273 件緑(6 回連続)/ clippy 緑 / macOS・Linux・Windows の CI 8 ジョブ全通過。