markharness guiは起動だけを担うAccepted(2026-10-02決定)。実装は未着手。0022(コアへのUI同梱の廃止)と0032(CLIのJSONを外部契約とするseam)の方針を変えず、その上でGUIを作る形を決める。
markharnessのテスト知識は、Requirement・Feature・Behavior・Scenario・TestCaseの関係を持つ。人がYAMLを直接編集するときは、変更対象だけでなく、その関連先や変更による影響を把握し、UIDやファイル配置を意識しながら整合性を保つ必要がある。この負担が大きいと、大きな修正だけでなく小さな追加さえためらわれ、テスト知識を更新し続けるうえで障害になる。
CLIはこれらの関係、Change Impact、Release CoverageをJSONで出力する。GUIの目的は、関係をたどって変更対象を選び、その文脈のままテスト知識を編集し、変更後の関係を確認できるようにすることである。ターミナルを使わない人(非開発者を含む)にも、その作業を画面から行えるようにする。閲覧だけの段階は開発の途中として許すが、閲覧後にYAML編集へ戻る負担が残るため、markharnessの配布物への同梱は編集ができるようになってから行う。本ADRは、このGUIをどのような形で提供するかを決める。
0022は、コアに同梱していたdashboardを「MVPの命題に寄与しないUIの保守コストを恒常的に負う」として廃止した。0032は、traceability・impact・coverageのJSONを外部向けの契約とし、表示は別ツールに委ねる方針を採った。
先例はgit guiである。Git公式マニュアルによれば、git-guiは独立プロジェクトとして保守され、安定版がGit本体の配布物に同梱される。起動はgit guiというサブコマンドで、gitが別の実行ファイルgit-guiを探して実行する。git-guiはgitの機能をgitのCLIを子プロセスとして呼ぶことで使い、実装言語もgit本体とは独立している。
GUIは別リポジトリ(markharness-gui)で、別の実行ファイル(markharness-gui)として作る。実装技術・画面設計・内部の構成は、GUIのリポジトリが決める。コアはそれを前提にしない。コアにHTTPサーバー・フロントエンドのアセット・ブラウザ起動の処理は置かない。
GUIはmarkharnessをGUIの外から子プロセスとして呼び、そのJSON出力だけを読む。.markharness/配下の内部ファイルは直接読まない。コアのRustライブラリを直接呼ぶこともしない。
閲覧だけの途中段階が使うのは、既存の読み取り出力だけである: traceability(--atを省略した作業ツリー)、binding list、coverage、impact。軸・説明・手順などの詳細項目は既存の出力に無い。編集に必要なこれらの項目を画面に出すときは、先にCLIに読み取り出力を追加し、GUIはその出力を読む(決定10)。axes listは、この途中段階では使わない。軸の定義(idとlabel)の一覧だけを返し、traceabilityは要素ごとの軸を返さないため、一覧を結びつける対象が画面に無い。また、出力がrecord_kindもschema_versionも持たない裸の配列で、決定5の種別の確認を適用できない。
markharness guiは起動だけを担うmarkharness gui [--dir <path>]
project_root::resolveで対象プロジェクトのルートを決める。未初期化ならmarkharness initを促すエラーにする。markharness-guiを、markharness自身と同じディレクトリ、見つからなければPATHの順に探して実行する。見つからなければ、GUIが同梱されていない旨と導入方法を示すエラーで終了する。--dir <ルートの絶対パス>を渡し、環境変数MARKHARNESS_BINに、起動したmarkharness自身の絶対パスを設定する。GUIはこのパスのmarkharnessを呼ぶ。GUIを単独で起動した場合に限り、PATH上のmarkharnessを使う。同じ配布物のmarkharnessだけを呼ばせて、版の食い違いを避けるためである。Ctrl-Cで終了できるようにするためである。GUI自身が常駐や別プロセス化をするかどうかは、GUIが決める。markharness <name>)にはしない。必要になるまでguiだけを持つ。CIやAIだけがCLIを使う場合に、GUIの分だけ配布物が大きくなるのを避けるため、現行のCLIのみのアーカイブはそのまま残す。GUI入りのアーカイブを別に作り、markharnessとmarkharness-guiを同じディレクトリに入れる。GUIの成果物は、GUIリポジトリが公開した安定版を、markharnessのリリース時に固定して取り込む。取り込む安定版は、決定10のとおり、テスト知識の編集ができるものに限る。CLIのみの配布物でmarkharness guiを実行したときは、決定3の未同梱エラーになる。
schema_versionで判断する。0.xの間はschema_versionが変わらないため、同梱された組み合わせを信頼するGUIは、受け取ったJSONのrecord_kindが期待する種別であること、schema_versionが自身の対応する版であることを確認し、そうでなければ表示を止める。対応する版と受け取った版を示して更新を案内し、部分的な表示はしない。誤った関係を表示するより、止めるほうが害が小さいためである。GUIは、schema_versionが上がることを、読み方を変える必要がある変化の信号として扱う。どの変化で上げるかは、0039のとおり、コア側が決める。
GUIは、必要な項目だけを読み、既存のオブジェクトに追加された未知のキーや、未知の新しい配列は無視する。これらは、GUIが表示する範囲の関係を誤らせない追加だからである。一方、GUIが意味を解釈する値の集合(関係のkind、Requirementのsource、bindingのmodeなど)に、GUIが知らない値が現れたときは、その要素を黙って除外せず、対応しない版として表示を止める。必要な項目が欠けているときも、同じく止める。schema_versionが同じでも、追加された項目が古いmarkharnessに無い場合や、新しい値を出す新しいmarkharnessを使った場合を、これで検出できる。止めるときに部分的な表示をしない、というのは、この止まる場合の動作である。
ただし、0026決定7と0039により、0.xの間は公開JSONのschema_versionが1に固定され、出力の形が変わっても上がらない。この間、schema_versionの確認は互換の変化を検出できない(検出できるのは、必要な項目の欠落だけである)。そこで0.xの間は、GUIが同じ配布物のmarkharnessだけを呼ぶこと(決定3)と、GUIの安定版をmarkharnessのリリースに固定して同梱すること(決定4)により、同梱された組み合わせを信頼する。この結果、GUIを単独で起動して別の版のmarkharnessを使った場合には、出力の形の違いを検出できない。
schema_versionを上げる基準は、0039のとおり1.0の基準を満たす時点で決まる。schema_versionが実際に上がるようになれば、GUIの確認は、GUIを変更しなくても互換の判断として働く。
GUIは、終了コードが0以外であれば失敗とみなし、標準エラー出力の文面をそのまま表示する。コマンドによってエラーがJSONのことと平文のことがあるが、GUIが機械的に分岐したい具体的な場面がまだ無いため、統一しない。
strictdoc exportを実行して得るsource: externalのRequirementについて、traceabilityが返すのはsource_keyまでで、要求の見出しや階層は含まれない。これらを画面に出すために、GUIがstrictdoc export --formats=jsonを実行し、そのJSONを読む。これは、コアが外部の内容を保持・複製しない方針(0023)と、コアはstrictdocを実行しない決定(0036決定2)を保つための、GUIだけの例外である。StrictDocは任意の連携のままで、無い環境ではmarkharnessのデータだけを表示する。
エクスポートには時間がかかる(後述の計測)。GUIは、エクスポートのJSONを基準として保存し、StrictDocのドキュメントと設定ファイルの更新時刻がそのJSONより新しいときだけ、裏で再エクスポートする。この間も、markharness側のデータは先に表示する。コアが課す制約は1つだけである: 古い内容を見せ続けない。利用者が、古い表示から必ず抜け出せる手段(キャッシュを使わない再エクスポート)を持つ。 保存場所・判定の細部・更新中の表示は、GUIのリポジトリが決める。
GUIはファイルを監視しない。利用者が更新操作をしたときに、JSONを再取得する。GUI自身が書き込み(編集)を行った後は、GUIが自動で再取得する。GUIの外で起きた変更は、更新操作で反映する。
GUIは、閲覧と編集を担う。閲覧だけの版は、GUIのリポジトリでの開発の途中段階として存在してよいが、GUI入りのアーカイブには同梱しない。同梱するのは、テスト知識の編集ができる安定版からである。
編集は、設計書cli-read-model-design.mdの§14.2のとおり、knowledge reconcileだけを通し、GUIがKnowledgeのファイルを直接書き換えることはしない。編集の画面に必要な詳細項目(軸・説明・手順など)は、決定2のとおり、先にCLIに読み取り出力を追加し、GUIはその出力を読む。
src/cli.rs: Guiサブコマンドの追加。起動のためのファイル探索と引数・環境変数の組み立ては、テストできる単位に分ける。実装は別タスクで、TDDで行う。.github/workflows/release.yml: GUI入りアーカイブの追加。GUIリポジトリに最初の安定版ができてから、取り込み方法を決める。docs/ja/cli-manual.md・docs/en/cli-manual.md: markharness guiの説明を、実装と同時に追加する。CONTEXT.md: 用語「GUI」(追加済み)。docs/ja/design/cli-read-model-design.md・docs/en/design/cli-read-model-design.mdの§14.1・§14.3: 本ADRと食い違っていた2点を更新する。(1)§14.1は、viewが使う読み取りコマンドを3つ(traceability・impact・coverage)に限っていたが、GUIは検証手段のためにbinding listも使う。binding listは§3.3の初期リードモデルではなくoutcome系統の出力なので、GUIが読むことは本ADRの範囲で決め、リードモデルへ加えるかどうかは別に決める。(2)§14.3は「markharness viewを追加しない」と書いていたが、本ADRのmarkharness guiは別ツールを起動するだけで、ビューアの実装を本体に持たない点を明記した。record_kindとschema_versionごとのfixtureを取り込んで契約テストに使う方針を述べている。これは、schema_versionで互換を判断する決定5と整合するが、GUIが契約テストで何を取り込むかは決めていない。また、設計書には別名のビューアを前提にした記述が他にも残る。これらは、本ADRの合意後に別ブランチで整理する。PATHの探索だけで起動する: 非開発者に別のインストールと版の食い違いを負わせる。--strictdoc-exportオプションを入れる: CIが生成したファイルを渡す用途は、版の識別情報が無いと、古いエクスポートと新しいKnowledgeを組み合わせた誤った図を正常な画面として表示しうる。必要な場面は決定9の「レビュー用スナップショット」で、単独のオプションとして足す理由が今は無い。strictdocを呼ぶ必要がなくなるが、0023が意図的に定めた「コアは外部の内容を保持・複製しない」境界を曲げる。traceabilityは既定で作業ツリーを読むため、再取得すれば最新が得られる。strictdoc export --formats=jsonの所要時間2026-10-02に、strictdoc 0.30.1・Windowsで計測した。1環境・実プロジェクト1件のみの計測であり、Linux・macOSでは測っていない。
| 対象 | 要求数 | 既定 | --no-parallelization |
|---|---|---|---|
合成データ(単純な要求、.sdoc8個) |
400 | 4.1秒 | 2.0秒 |
StrictDoc自身のリポジトリ全体(strictdoc export .) |
358 | 20.6秒 | 18.6秒 |
同じdocs/とspec/だけを切り出したコピー |
358 | 6.3秒 | 3.9秒 |
include_source_pathsで指定されたソースコード側のトレーサビリティの走査である。この走査は、GUIが必要とする要求の見出しと階層には不要である。--no-parallelizationは、小規模では所要時間を約半分にし、全体では約1割短くした。JSONの内容は、確認した2つのデータで両方式が同一だった。このオプションはStrictDoc自身のヘルプで「デバッグに有用」と説明されたものである。strictdoc export --configで設定を上書きするなど)ことは、未検証の可能性である。StrictDocの設定はPythonのコードで、プロジェクトの設定を部分的に変えるのは難しい可能性がある。