wiki sync drift targeted mirror - Liplus-Project/liplus-language GitHub Wiki
wiki sync のミラーは wipe-and-copy でなく drift set 限定で行う
Question
docs/ → wiki のミラーを、Wiki 作業ツリーを一括で消してから全コピーする(wipe-and-copy)方式で行うか、差分ファイルだけを操作する(diff-targeted)方式で行うか。
Current resolution
diff-targeted。docs/ と wiki 作業ツリーの内容が異なる docs/ 所有ファイルだけを to_copy / to_delete に列挙し、その集合にのみ per-file 操作を適用する。内容比較は CR 除去後に行い、行末差だけでは drift としない。drift 計算自体が失敗した場合は STOP してエスカレートし、wipe パターンへフォールバックしない。
Edges
- supersedes: wipe-and-copy による selective wipe(
rm [A-Z]*.md [0-9]*.md Home.md _Footer.md相当)。同じミラー不変条件を、破壊的プリミティブなしで満たす - depends on: wiki sync 時の _Sidebar.md 整合性 assertion — 所有境界(docs/ 所有 ↔ Wiki 専属)を前提とする点で共通の基盤に乗る
背景
所有境界の由来
判断記録の実体エントリを wiki 専属に移した 2026-04-26(#1172)に、docs/ 所有(大文字 + 数字 prefix + Home.md + _Footer.md)と Wiki 専属(小文字エントリ + _Sidebar.md)の境界が確定した。2026-05-21 の命名 refactor(#1324)で Wiki 専属側の pattern が [a-z].-*.md から kebab-case [a-z]*.md に変わり、順序は filesystem ではなく index と _Sidebar.md で明示する形になった。「docs/ に無い = wiki から消す」と読む手順は Wiki 専属側を全滅させるため、境界は同期手順の入力そのものである。
wipe から drift-targeted へ
PR #1330(Decision-Log → Decision-Structure リネーム)後の wiki sync 実行中、subagent の bulk wipe が auto-mode classifier に block された。回避として docs/ と wiki の差分を取り、drift set(当時 7 files、いずれも docs/ 所有)だけに操作を限定したところ、結果は wipe-and-copy と完全に一致した。この実測を仕様側に昇格したのが #1331 / PR #1332。
classifier の拒否は一過性の設定不備ではなく、rules/model/subtractive-structural-beauty.md の Artifact deletion calibration が持つ blast radius 軸に対応する構造的なものである。したがって「classifier が煩いので別経路で通す」は誤った読みで、drift-targeted が構造に合っている側。
行末正規化
Windows ホストでは既定 clone に autocrlf=true が効き、blob が LF でも作業ツリーが CRLF になる。素の cmp 比較では docs/ 所有ファイルが軒並み drift 判定になり、純粋な行末 churn を wiki に push する。#1474 / PR #1480 で二重に閉じた: clone 側を git -c core.autocrlf=false にして作業ツリーを blob と byte 一致させ、比較側も CR 除去後に行うようにした。非 Windows ホストでは CR が無いため no-op。
制約
- ミラー不変条件(同期後、docs/ 所有ファイルは byte 単位で一致)は変えない。
to_copyが全ての差分を覆いto_deleteが docs/ 側で消えたものを覆う限り、終状態は wipe-and-copy と同一 - 参照実装は process substitution を使うため bash 系シェルを前提とする(wiki sync 手順は元から bash 系を前提としている)
- STOP 条件(sidebar / cross-reference / Wiki 専属保全)の挙動は本判断で変更していない
結論
採用 = diff-targeted + 行末正規化 + 失敗時 STOP。
却下 = wipe-and-copy の維持(blast radius が Wiki 全体で、classifier 拒否の構造的理由にも反する)。却下 = drift 計算失敗時の wipe フォールバック(失敗時にだけ最も危険な経路へ落ちる設計になる)。