Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
19 KiB
STATE.md スキーマリファレンス
STATE.md は MSD Core のプロジェクト記憶ファイルです — プロジェクトの現在地、直近の作業内容、次に実行すべきコマンドを記録する単一の Markdown ドキュメントです。このページではそのスキーマを説明します。ドキュメントインデックス も参照してください。
概要
MSD Core で管理するプロジェクトはすべて .planning/STATE.md に STATE.md を1つ保持します。このファイルはすべてのワークフロー開始時に読み込まれ、重要なアクションのたびに書き込まれます。ファイルは以下を組み合わせた構成です:
- YAML フロントマター — ステータスラインフック(
parseStateMd)およびmsd-tools stateコマンドが読み取る機械可読フィールド。 - Markdown 本文 — 現在の進捗、蓄積されたコンテキスト、セッション継続性、パフォーマンス指標を記述する人間可読なセクション。
ファイルは意図的にコンパクトに保たれています(目標: 100行以内)。プロジェクト状態のダイジェストであり、アーカイブではありません。
YAML フロントマター
フロントマターはファイルの先頭にある --- デリミタの間に記述します。msd_state_version と status 以外のフィールドはすべてオプションで、データが未取得の場合は省略できます。
注釈付きサンプル
---
msd_state_version: '1.0'
milestone: v2.0
milestone_name: Code Quality
status: executing
# フェーズライフサイクルフィールド — すべてオプション (v1.40.0, issue #2833 で追加)
active_phase: "4.5"
next_action: execute-phase
next_phases: ["4.5"]
progress:
total_phases: 17
completed_phases: 10
total_plans: 84
completed_plans: 47
percent: 59
# syncStateFrontmatter が書き込む追加フィールド
current_phase: "4"
current_phase_name: Observability
current_plan: "3"
last_updated: "2026-06-01T12:34:56.789Z"
state_head: 4f3c2b1a9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b
last_activity: "2026-06-01"
stopped_at: "Phase 4 P3 execution complete"
paused_at: null
---
フィールドリファレンス
| フィールド | 型 | 設定タイミング | 用途 |
|---|---|---|---|
msd_state_version |
string ('1.0') |
常時 | スキーマバージョン。syncStateFrontmatter が最初の state.* 呼び出し時に書き込む。 |
milestone |
string (例: v2.0) |
マイルストーン設定時 | 現在のマイルストーンバージョン。プロジェクト設定から読み取る。 |
milestone_name |
string | マイルストーン設定時 | 人間可読なマイルストーンラベル (例: Code Quality)。 |
status |
string | 常時 | 現在のライフサイクルステージ。normalizeStateStatus() によって正規化される — ステータス値 参照。 |
active_phase |
string (例: "4.5") |
このフェーズでオーケストレーターコマンドが実行中の場合 | 現在処理中のフェーズ番号。フェーズ間は null に設定。 |
next_action |
string | アイドル中で推奨コマンドがある場合 | 次に実行するスラッシュコマンド: discuss-phase、plan-phase、execute-phase、verify-phase。オーケストレーターが実行中または推奨なしの場合は null に設定。 |
next_phases |
YAML フロー配列 (例: ["4.5"]) |
next_action と対応して |
next_action が適用されるフェーズ ID(通常1〜2件)。next_action と同条件で null に設定。 |
progress.total_phases |
integer | フェーズデータ取得済みの場合 | 現在のマイルストーンにおける総フェーズ数。ROADMAP.md とフェーズディレクトリから算出。 |
progress.completed_phases |
integer | フェーズデータ取得済みの場合 | すべてのプランサマリーがディスク上に存在するフェーズ数(すなわちすべてのプランが完了したもの)。 |
progress.total_plans |
integer | プランファイルが存在する場合 | 現在のマイルストーンの全フェーズにわたるプランファイルの合計数。 |
progress.completed_plans |
integer | サマリーファイルが存在する場合 | 完了したプランサマリーの合計数(実行済みプランごとに1つの SUMMARY.md)。 |
progress.percent |
integer 0–100 | 進捗データ取得済みの場合 | フェーズ次元 でのマイルストーン進捗(min(completed_plans/total_plans, completed_phases/total_phases))。このフィールドが存在するときのみステータスラインの進捗バーが描画されます — 不在の場合はバーが非表示になります。 |
current_phase |
string | フェーズ実行中 | 本文の Current Phase: フィールドから抽出したフェーズ番号。 |
current_phase_name |
string | フェーズに名前がある場合 | 本文の Current Phase Name: フィールドから抽出したフェーズ名。 |
current_plan |
string | プランが進行中の場合 | 本文の Current Plan: フィールドから抽出したプラン番号。 |
last_updated |
ISO-8601 タイムスタンプ | 書き込み時に常時 | 最後の syncStateFrontmatter 呼び出しのタイムスタンプ。realClock.nowIso() によって書き込まれる。 |
state_head |
string (40-char sha) | On write, when the project's own git repo resolves | Full commit sha STATE.md was written against (#2573). Omitted entirely outside a git repo, or when the resolved repo is not the project's own — an unverifiable stamp degrades to absent rather than asserting provenance the file does not have. Recomputed on every write and never carried forward. |
last_activity |
string | 本文に設定されている場合 | 本文の Last Activity: フィールドから抽出した最終活動日。 |
last_activity_desc |
string | 本文に設定されている場合 | 本文の Last Activity Description: フィールドから抽出した最終活動の説明。 |
stopped_at |
string | 停止ポイントが記録された場合 | 最後に完了したアクションの説明。アーカイブの文章とのマッチを避けるため ## Session 本文セクションにスコープを限定。 |
paused_at |
string | プロジェクトが一時停止中の場合 | 一時停止ポイントの自由形式の説明。一時停止していない場合は省略または null。 |
フィールドの多重度
| フィールド | 多重度 |
|---|---|
msd_state_version |
one |
milestone |
optional |
milestone_name |
optional |
current_phase |
optional |
current_phase_name |
optional |
current_plan |
optional |
status |
one |
stopped_at |
optional |
paused_at |
optional |
last_updated |
one |
last_activity |
optional |
last_activity_desc |
optional |
state_head |
optional |
progress.total_phases |
optional |
progress.completed_phases |
optional |
progress.total_plans |
optional |
progress.completed_plans |
optional |
progress.percent |
optional |
ステータス値
msd-core/bin/lib/state-document.cjs の normalizeStateStatus() が本文の生テキストを以下の正規値にマッピングします:
| 正規値 | マッチするテキスト(大文字小文字不問) |
|---|---|
discussing |
discussing を含む |
planning |
planning または ready to plan を含む |
executing |
executing、in progress、または ready to execute を含む |
verifying |
verif を含む |
completed |
complete または done を含む |
paused |
paused または stopped を含む、または paused_at が存在する |
unknown |
上記のいずれにも該当しない |
オーケストレーターコマンドが実行中の場合、慣例(issue #2833)として status にライフサイクルステージを直接書き込みます:
| コマンド | 実行中の status |
|---|---|
/msd-discuss-phase |
discussing |
/msd-plan-phase |
planning |
/msd-execute-phase |
executing |
/msd-verify-work |
verifying |
ステータスライフサイクル (ADR-2207)
The Status field follows a strict lifecycle across phase and milestone boundaries:
| 値 | 書き込み元 | 意味 |
|---|---|---|
Ready to plan |
completePhaseCore (non-last phase) |
Next phase is ready for planning |
All phases complete |
completePhaseCore (last phase) |
All phases done; milestone awaiting formal close |
<version> milestone complete |
milestoneCompleteCore |
Milestone formally closed and archived |
Awaiting next milestone |
milestoneCompleteCore |
Terminal/archived state |
Phase-completion verbs never write Milestone complete (the overloaded bare value was removed in #2204 per ADR-2207 to decouple phase-level writes from milestone termination).
ステータスライン描画シーン
hooks/msd-statusline.js の formatMsdState() がパース済みフロントマターを読み取り、最初にマッチしたシーン を出力します。新しいライフサイクルフィールドが適用されない場合は、v1.38.x から一切変更なくオリジナルのフォーマットにフォールスルーします。
| シーン | トリガー | 表示例 |
|---|---|---|
| 1. フェーズアクティブ | active_phase が設定されている |
v2.0 [██░░░░░░░░] 20% · Phase 4.5 executing |
| 2. アイドル・次のアクション推奨 | active_phase が null かつ next_action と next_phases の両方が設定されている |
v2.0 [██░░░░░░░░] 20% · next execute-phase 4.5 |
| 3. マイルストーン完了 | percent が 100 または completed_phases == total_phases |
v2.0 [██████████] 100% · milestone complete |
| 4. デフォルトフォールバック | 上記のいずれにも該当しない | v1.9 Code Quality · executing · ph 1/5(既存フォーマット) |
シーン優先度: active_phase と next_action が両方設定されている場合、シーン1が優先されます — オーケストレーターが実行中であるため「次の推奨」は誤解を招くためです。この優先度は formatMsdState() のチェック順序によって強制され、tests/msd-statusline.test.cjs の "scene priority" スイートでカバーされています。
進捗バー([██░░░░░░░░] 20%)はフロントマターに progress.percent が存在する場合のみマイルストーンセグメントに追加されます。不在の場合はバーは表示されません。
フロントマターパースの制約
ステータスラインフックは正規表現ベースのパース(完全な YAML ライブラリを使用しない)を使用するため、以下の制約が適用されます。これらは tests/msd-statusline.test.cjs でテストされています。
-
フロントマターはファイルの先頭文字から始まる必要があります。 コメントを含む何かが開始
---の前にあると、マッチが無効になります。開始---行は末尾のスペースなしで正確にそれだけである必要があります。 -
ネストされたブロック内のコメントはサポートされていません。
progress:ブロックパーサーは次の行が[ \t]+\w+:であることを要求します。progress:と最初のキーの間に# commentを挿入するとマッチが壊れてバーが消えます。ドキュメントはフロントマターブロック内ではなくSTATE.md本文に記載してください。 -
next_phasesの主形式は単一行フローです。 パーサーは最初にnext_phases: ["4.5", "4.6"]を試みます。ブロックシーケンス(- 4.5\n- 4.6)もパースされますが、ステータスライン描画の信頼性は低下します。正規表現ベースのパーサーを予測可能に保つため、next_phasesには単一行フローを使用してください。多数の候補フェーズをドキュメント目的で記録する必要がある場合はSTATE.md本文に格納してください。
将来的に正規表現パーサーを完全な YAML ライブラリに置き換えた場合は、これらの制約を緩和しテストを更新できます。
Markdown 本文セクション
本文(末尾の --- 以降のすべて)は msd-core/templates/state.md のテンプレートに従います。標準セクションは以下の通りです:
Project Reference
.planning/PROJECT.md へのポインタです。以下を含みます:
- Core value —
PROJECT.mdの Core Value セクションの一行説明。 - Current focus — アクティブなフェーズ。
Current Position
プロジェクトの現在の状況:
| フィールド | フォーマット |
|---|---|
Phase: |
X of Y (Phase name) |
Plan: |
A of B in current phase |
Status: |
自由テキスト。例: Ready to execute、Executing Phase 4、Phase complete — ready for verification |
Last activity: |
ハンドラー書き込み時は ISO 日付(YYYY-MM-DD); エグゼキューター作成時はナラティブ文章 |
Progress: |
ビジュアルバー。例: [████░░░░░░] 40% |
このセクションのすべてのフィールドは単一値であり、このセクションは追記されるのではなく上書きされます。 2つ目の Phase: 行は2つ目の位置ではなく、履歴でもありません — それは不正な入力です。リーダーは重複を文書内の出現順序では解決しません。フォームによって解決します。判定順序は各フォームが ## Current Position セクション内のどこに現れるかに関係なく、このセクション内のどこにあっても太字の **Phase:** value、次に行頭の平文 Phase: value、最後にパイプテーブルの | Phase | value | 行の順です — そして勝者となったフォーム内でのみ、最初の出現が勝ちます。このセクションの外にある太字または平文の行 — 以前の ## Archive エントリや YAML フロントマター内の太字行 — は一切参照されません。実装は常にまず ## Current Position セクションへスコープを絞ってから(#2956)フォームの優先順位を適用します。実務上の帰結は2つあります。上位のフォームで書かれた重複は、セクション内で後に現れていても勝ちます。つまり「強調のために」追記された太字行は、無視されるのではなく、先行する平文行を黙って上書きします。また、インデントされた Phase: 行は平文フォーム(行頭を基準とする)からは見えず、次に一致するフォームへとフォールスルーします。「上位フォームが勝つ」というルールには2つの鋭い落とし穴が伴います。値が末尾の空白だけの太字行は、下にある有効な平文行にフォールスルーせず、空文字列として解決されます。また、ラベルのセル自体が太字になっているパイプテーブル行(| **Phase:** | value |)は太字パターンに先に捕捉され、パイプを含むセルの文字列がそのまま返されます。このセクションを書き込む際は、行を追加するのではなく、置き換えてください。
進捗の履歴はここには属しません。それは、増えていくように設計されたセクションである以下の ### Performance Metrics に蓄積されます。
このセクションの Status: および Last activity: フィールドは、既存の値が既知のテンプレートデフォルト値の場合に MSD ハンドラーによって更新されます(クヌース不変式: エグゼキューター作成値は保存されます)。既知のハンドラーデフォルト値の完全なリストは msd-core/bin/lib/state-document.cjs の KNOWN_TEMPLATE_DEFAULTS に記載されています。
Performance Metrics
実行速度の追跡:
- 完了した総プラン数、プランあたりの平均所要時間。
- フェーズごとの内訳テーブル(
Phase | Plans | Total | Avg/Plan)。 - 最近のトレンド: Improving / Stable / Degrading。
各プラン完了後に更新されます。
Accumulated Context
Decisions — 現在の作業に影響する最近の意思決定のサマリー(完全なログは PROJECT.md に保存)。msd-tools state add-decision で追加。
Pending Todos — 件数と .planning/todos/pending/ への参照。/msd-capture で取得。
Blockers/Concerns — 今後の作業に影響する課題。起点フェーズのプレフィックス付き。msd-tools state add-blocker で追加し、msd-tools state resolve-blocker で解決。
Session Continuity
即座のセッション再開を可能にします:
Last session:— 最後のセッションの ISO-8601 タイムスタンプ。Stopped at:— 最後に完了したアクションの説明。Resume file:—.continue-here*.mdファイルが存在する場合はそのパス、存在しない場合はNone。
後方互換性
フェーズライフサイクルフィールド(active_phase、next_action、next_phases、バー用の progress.percent)は 追加式でプロジェクトごとにオプトイン です:
- ライフサイクルフィールドが一切設定されていない
STATE.mdは v1.38.x 以前と バイト単位で同一 に描画されます。 - ライフサイクルフィールドの追加はオプトインです — フィールドが不在の場合レンダラーはグレースフルに縮退します。
- 進捗バーは
progressブロックが存在する場合でもオプトインです: バーをトリガーするのはprogress.percentのみで、total_phasesとcompleted_phasesだけではトリガーされません。
tests/msd-statusline.test.cjs の formatMsdState #2833 backward compatibility テストスイートがこの保証を固定しています。レガシー STATE.md 描画を壊す変更があればスイートが失敗します。