Accepted
外部プロジェクト(todo2。アプリ本体をリポジトリ直下、markharnessのknowledge/等をdocs/配下にmarkharness init --dir docsで初期化)でmarkharness execution recordを実行した際、markharnessのプロジェクトディレクトリ(--dir)がgitリポジトリのルートと一致しない(リポジトリ内のサブディレクトリに置かれる)配置で失敗する不具合が見つかった。実運用でこの配置を試みる利用者が実在することを示す一次事例であり、修正に先立って「そもそもこの配置を正式にサポートすべきか」という設計判断が必要だった。
選択肢2を採用する。プロジェクトディレクトリ(knowledge/等の親、--dir/cwdで指定するroot)は、gitリポジトリのルートと一致している必要はない。
理由:
todo2の一次事例が既にこの配置を実運用で要求している。changes computeはマイルストーン間でknowledge/配下の部分木のtree SHAだけを比較する設計であり、milestone自体(git tag)はリポジトリ全体に対するグローバルな概念である。プロダクト本体のリリースタグをそのままmilestoneとして流用し、markharness側は関心のある部分木だけを見る、という分担は自然であり、サブディレクトリ配置と整合的である。knowledge//generated/等を同居させることになり、どちらもリポジトリ構成として不自然になる。この不利益に対応する、サブディレクトリ配置側の構造的な不利益は見当たらない。src/git.rsのtree_sha/show_blobが使っていたGitの<rev>:<path>構文は、./または../で始めない限り常にリポジトリルートからの相対パスとして解釈される(git -C <root>でカレントディレクトリを変えてもこの解釈規則には影響しない)。一方、呼び出し元のid_cache::resolve_feature_versionsはgit ls-treeのpathspec構文(-C root相対で正しく解決される)で得たパスを、そのまま<rev>:<path>に渡していたため、rootがリポジトリのサブディレクトリの場合にパスがずれて失敗していた。tree_shaをgit rev-parse --verify <rev>:<path>からgit ls-treeベース(-C root相対のpathspec)に書き換えた。パスベースのshow_blobは削除し、ls_tree_recursiveが既に返している content-addressed SHA を直接渡すshow_blob_by_sha(git cat-file -p)に置き換えた。SHAはパス解釈を経ないため、rootがリポジトリのどこにあっても影響を受けない。docs/cli-manual.mdの--dirの説明を、「対象プロジェクトディレクトリ(gitリポジトリのルート)」から「gitリポジトリ内の任意のディレクトリ(リポジトリ自体のルートである必要はない)」という趣旨に修正した(1.11/1.12/1.13/1.14節)。todo2相当のサブディレクトリ配置に対してexecution record・changes computeが実際に成功することを確認した。docs/nested-project-dir-git-path-fix-spec.mdにまとめていたが、対応完了に伴い本決定記録に要点を転記した上で削除した。--dirを一切指定せずカレントディレクトリから自動的にgitリポジトリルートを検出する(git rev-parse --show-toplevel相当)機能の追加は、本決定を運用面で完成させる自然な次の課題だが、引き続き別課題として残す。