対象読者: Butler を利用するユーザー / Brain
関連 Issue: #80, #81
Track Ledger(トラック台帳)は、探索、試作、検証、方針転換、やり直しを Gitea Issue 上で追跡するための Butler の機能である。
採用した結論だけでなく、試した案、捨てた理由、確定した前提、次の出発点を残し、別のユーザーや Brain が後から判断を復元できる状態を作る。
次のように、複数の判断経路が生じる作業で使う。
小さな修正、単なるコマンド実行、判断を伴わない途中経過には使わない。通常の作業事実は work_record に残す。
#80 では、Gitea 1.25.5 に Project 操作用 REST API がないことが確認された。Butler の project_capability_check() は利用可否を判定できるが、API がない環境で Project ボードを自動操作することはできない。
Track Ledger は Project ボードの再実装ではない。必要だった「複数の探索や方針転換があっても、現在地と判断理由を失わないこと」を、Issue、label、comment、docs、work_record、handover の組み合わせで実現する。
| 要素 | 役割 |
|---|---|
| 親 Issue | 作業全体の目的、現在の本線、track 一覧、Issue 間 relation を示す台帳 |
| 子 Issue(track) | ひとつの探索、試作、検証、方針転換、やり直し |
| Issue 間 relation | Issue 同士の由来、継続、置き換えなどの関係 |
| docs | 長い設計、比較表、調査詳細、利用手順 |
work_record |
実際に行った変更と検証の記録 |
| handover | 次の Brain が再開するための短い引き継ぎ |
親 Issue は「今どこにいるか」、子 Issue は「なぜそう判断したか」、docs は長い説明、work_record は作業事実を受け持つ。
最初に対象プロジェクトで Butler セッションを開始する。
work_session_start(project_root="/path/to/project")
parent_issue_id を毎回省略したい場合は、親 Issue を default issue にする。
work_start(issue_id=81)
Track Ledger 用 label は track_ensure_labels() が不足分だけを作成する。この処理は冪等であり、再実行してよい。
track_ensure_labels()
既存の普通の Issue を Track Ledger の親 Issue にするには、まず preview で更新案を確認し、次に sync で反映する。
track_update_parent(parent_issue_id=81, mode="preview", current_mainline="現在採用している方針")
track_update_parent(parent_issue_id=81, mode="sync", current_mainline="現在採用している方針")
preview は Issue を書き換えず、preview_body に更新案を返す。sync は親 Issue 本文を実際に更新する。未初期化の Issue に sync を実行すると、Track Ledger metadata と次の見出しが追加され、data.initialized=true が返る。
既存本文は保持される。追加された見出しの 未定 や なし は、必要に応じて通常の Issue 編集で具体化する。
独立して判断を残す価値がある作業は track_start() で子 Issue にする。
track_start(
parent_issue_id=81,
title="保存方式を比較する",
kind="comparison",
purpose="Issue comment と専用 metadata の保守性を比較する",
success_criteria="採用方式と判断理由が決まる",
docs_refs=["docs/比較資料.md"]
)
利用できる kind は次のとおり。
| kind | 用途 |
|---|---|
exploration |
仕様、制約、選択肢の探索 |
experiment |
仮説の検証 |
prototype |
試作品の作成 |
pivot |
方針転換 |
restart |
作り直し |
comparison |
複数案の比較 |
baseline-check |
後続判断の前提となる事実の確認 |
作成された track は status=in_progress となり、親 Issue の Track 一覧にも追加される。label は補助情報であり、作成・付与の成否は track Issue の作成成否とは独立して扱われる。label の作成や付与に失敗しても、Issue metadata を正本として track Issue は作成されるため、返値の warnings で label の状態を確認する。
判断材料、レビュー結果、リスク、成果物など、track の文脈に属する記録は track_record() で子 Issue のコメントに保存する。
track_record(
track_issue_id=123,
summary="比較の結果、metadata 方式は機械的な整合性確認が可能だった",
record_type="decision",
decision="metadata 方式を採用候補とする",
artifacts=["docs/比較資料.md"]
)
record_type は progress、review、decision、risk、artifact、question のいずれかを指定する。省略時は progress になる。
promote_to_parent=true は親 Issue を自動更新しない。必要な track_update_parent() を next_actions で案内するだけなので、内容を確認してから反映する。
コード変更、変更ファイル、テスト結果などの作業事実は、同じ内容を track に重複させず work_record() に残す。
結論が出たら track_finish() を使う。
track_finish(
track_issue_id=123,
outcome="adopted",
decision="metadata 方式を採用する",
reason="Issue 本文から状態を復元でき、整合性チェックも可能なため",
artifacts=["docs/比較資料.md"]
)
利用できる outcome は次のとおり。
| outcome | 意味 |
|---|---|
adopted |
親 Issue の本線に採用した |
discarded |
明示的に採用しなかった |
superseded |
後続 track に置き換えられた |
inconclusive |
判断に足る結果が出なかった |
baseline |
後続判断の前提となる事実を確定した |
needs-review |
人間などの追加確認が必要 |
完了すると status=finished になり、既定では親 Issue の Track 一覧も更新される。reason を省略すると保存は行われるが missing_reason warning が返るため、原則として判断理由を指定する。
adopted の場合は、返された next_actions に従い、親 Issue の「現在の本線」も更新する。
track_update_parent(parent_issue_id=81, mode="preview", current_mainline="metadata 方式を採用する")
track_update_parent(parent_issue_id=81, mode="sync", current_mainline="metadata 方式を採用する")
superseded の場合は、置き換え先が自動では決まらない。後続 track を作成し、必要な relation を明示する。
作り直しでは track_start(kind="restart") より track_restart() を優先する。
track_restart(
parent_issue_id=81,
reason="現在の方式では競合更新を安全に扱えない",
preserve_artifacts=["調査結果", "既存テスト"],
discard_artifacts=["競合を考慮しない更新処理"],
next_starting_point="preview と sync を分けた方式から再設計する",
title="親Issue更新方式を作り直す"
)
reason と next_starting_point は必須である。preserve_artifacts または discard_artifacts が空でも開始できるが warning が返る。空にする場合も、本当に残すもの・捨てるものがないか確認する。
Issue 全体の由来や置き換えは track_relation_add() で記録する。
track_relation_add(
source_issue_id=81,
target_issue_id=80,
relation="derives_from",
reason="#80 で確定した Project API 非対応を前提に設計する"
)
引数は「source_issue_id relation target_issue_id」の順に読む。利用できる relation は次のとおり。
| relation | 読み方 |
|---|---|
derives_from |
source は target の結果や前提から派生した |
continues_as |
source の目的は target として形を変えて続く |
supersedes |
source は target を置き換える |
split_from |
source は target から切り出された |
references |
source は target を判断材料として参照する |
blocks |
source が target をブロックしている |
relation は必ず source 側に記録される。target も初期化済みの Track Ledger 親 Issue なら両側に記録される。普通の Issue を relation のためだけに自動初期化することはない。
Track の結果と Issue 間 relation は分けて考える。たとえば #80 の調査結果を baseline として扱うことと、#81 derives_from #80 を記録することは別の情報である。
現在地の確認には track_summarize() を使う。
track_summarize(parent_issue_id=81)
返値には現在の本線、状態別の track、relation、次の操作候補が含まれる。
不整合の確認には track_check() を使う。
track_check(parent_issue_id=81)
未初期化、現在の本線の未設定、親子 metadata の不一致、完了状態と outcome の矛盾、restart 必須項目の欠落、label のずれなどが warnings に返る。各 warning の action を確認する。
親の一覧が古い場合は、いきなり書き換えず次の順で直す。
track_update_parent(parent_issue_id=81, mode="preview")
track_update_parent(parent_issue_id=81, mode="sync")
track_check(parent_issue_id=81)
track_check() と track_update_parent() は、すべての不整合を自動修復するものではない。track metadata 自体の欠落や label のずれは、warning の案内に従って個別に確認する。
track_capture() は文章の保存先候補を分類する読み取り専用ツールである。
track_capture(parent_issue_id=81, content="比較結果と採用理由を記録したい")
issue_comment、docs、track、track_record、handover、unknown のいずれかと、次の操作候補を返す。進行中 track が1件なら suggested_track_issue_id、複数なら track_candidates が返る場合があるが、いずれも推定結果なので対象を確認してから保存する。
promote=true による自動保存は未実装である。指定しても保存されず、not_implemented warning が返る。
ユーザーは、目的、優先順位、採用判断、人間の確認が必要な事項を決める。台帳の機械的な整理までユーザーに負わせない。
Brain は次を行う。
work_observe() と必要に応じて track_summarize() を確認するwork_record、判断文脈を track、長文を docs に振り分けるtrack_check() で不整合を確認するwarnings、required_action、next_actions を確認するBrain は、ユーザーの判断を推測して adopted や discarded を確定しない。判断が必要なら needs-review として残すか、ユーザーに確認する。
# 初回だけ
work_session_start(project_root="/path/to/project")
track_update_parent(parent_issue_id=81, mode="preview", current_mainline="現在の方針")
track_update_parent(parent_issue_id=81, mode="sync", current_mainline="現在の方針")
# 探索を開始
track_start(parent_issue_id=81, title="案Aを検証", kind="experiment", purpose="案Aが制約を満たすか確認")
# 作業中
track_record(track_issue_id=123, summary="制約Xを満たさないことが判明", record_type="decision")
work_record(message="案Aの検証とテストを実施", issue_ids=[81, 123])
# 完了
track_finish(track_issue_id=123, outcome="discarded", decision="案Aは採用しない", reason="制約Xを満たさないため")
# 整合性確認
track_summarize(parent_issue_id=81)
track_check(parent_issue_id=81)
track_capture(promote=true) は自動保存しないtrack_record(promote_to_parent=true) は親 Issue を自動更新せず、更新手順を案内するtrack_check() は診断と修復案内が中心で、metadata や label の全自動修復は行わないこれらの制約があるため、書き込み操作の返値を確認し、親 Issue の更新では preview を先に使う。
Brain の通常運用では、このマニュアルを毎セッション読み直すことを前提にしない。Butler は MCP 接続時の Instructions に基本ライフサイクル、outcome の短い意味、記録先の分担、非自動化範囲を含める。
また、work_observe() は active issue が Track Ledger 親 Issue の場合、既に読み取った親 metadata から次を返す。
current_mainlinein_progress_count / in_progress_trackshas_warnings / warning_codesavailable_nextBrain はまず work_observe() の返値と各 tool の warnings / next_actions に従う。このマニュアルは、人間が運用全体を確認するとき、既存 Issue 群の移行、特殊な restart / supersede、通常の action で解消できない不整合など、詳細説明が必要な場合の正本として使う。