若くない何かの悩み

何かをdisっているときは、たいていツンデレですので大目に見てやってください。

マスタースケジュールの理論とコインチェックにおける実践

この記事はコインチェック株式会社(以下、コインチェック)のアドベントカレンダー4日目の記事です。


こんにちは。Kuniwak です。 最近は Software Engineer in Test の殻を破り(?)、PMO 的な役割でプロジェクトのプロセスを設計し、マスタースケジュールを計算しています。

みなさんはプロジェクトのスケジュールをどのように決めていますか? この記事ではスケジュール策定の背後にある理論とマスタースケジュールの作成方法を説明します。 また紹介するスケジュールの理論に基づいたツールである pfd-tools を紹介します。

TL;DR

  • PFD と要素表を書けばマスタースケジュールを機械的に計算できる(pfd-tools の pfdplan & planmaster コマンド)
  • スケジュールの理論を使うと改善すべき箇所がピンポイントでわかる(pfd-tools の criticalpath コマンド)
  • 現実のプロジェクトに適用でき、実際にマスタースケジュール策定に使える

説明の準備

マスタースケジュールとは

本記事ではマスタースケジュールをプロジェクトの定めた各工程の開始・完了時刻を定めたものとして定義しています(下図は適当に作った例です)。

マスタースケジュールの例

なおマスタースケジュールに正式に合意された定義はありません。さまざまな定義が存在します(ここでは他の定義は取り上げません)。

プロセスとは

プロセスとは成果物を入力し、成果物を出力する活動です1

プロジェクトの全体を小さなプロセスに分解し、それらを大局的な工程にマッピングするとマスタースケジュールを計算できます。 たとえば、機能Aを構成する機能A1と機能A2がありこれらが完成しないと機能Aが完成しないとします。 A1とA2のいずれも設計、実装、システムテストをされるとすると、機能Aの大局的な工程は設計(A1設計、A2設計)、実装(A1実装、A2実装)、システムテスト(A1システムテスト、A2システムテスト)のように局所的なプロセスにマッピングできます:

局所的なプロセス 大局的な工程
要求分析 要求分析
仕様記述 仕様記述
機能A1設計 設計
機能A2設計 設計
機能A1実装 実装
機能A2実装 実装
機能A1システムテスト システムテスト
機能A2システムテスト システムテスト
システム統合テスト システム統合テスト
ユーザー受け入れテスト ユーザー受け入れテスト
リリース リリース

大局的な工程の開始時刻はマッピングされたプロセスのうち最早のものの開始時刻で、工程の終了時刻は最早の次工程の開始時刻とマッピングされたプロセスのうち最遅のものの終了時刻の早い方です。

Process Flow Diagram(PFD) とは

Process Flow Diagram(PFD)とはプロセスを成果物変換の連なりであらわすプロセスの表現形式の1つです。清水吉男氏により提案されました。

PFD では成果物を矩形2、プロセスを楕円形であらわし、プロセスへの成果物の入出力を矢線であらわします。

PFD の例

この矢線によって PFD 上でプロセスの依存関係が明示されます。 たとえばあるプロセスを1つ選び矢線を逆方向にたどると、選んだプロセスを開始するためにあらかじめ完了しているべきプロセスがわかります3

矢線には、手戻りを意味する特別な矢線であるフィードバック線があります4。 フィードバック線の先のプロセスは、矢線の元の成果物の更新により手戻りして再実行しなければならないことを意味します。 代表的なフィードバック線はレビューコメントやバグチケットから実装への矢線です。

フィードバックのあるPFDの例

厳密にいうと、成果物からプロセスへ向かう実線の矢線は、矢線の元の成果物が完成していなければ矢線の先のプロセスを実行できないという意味を持ちます。 これに対し、破線の矢線であるフィードバック線は矢線の元の成果物が完成していなくとも矢線の先のプロセスを実行できるという違いがあります。 バグチケットがなくても実装は開始できますが、バグチケットが出たら修正(実装の再実行)が必要になるということです。

PFD に書ききれない情報(詳細な説明等)は要素表に書き出します。 要素表は成果物に関する要素表である成果物表とプロセスに関するプロセス表があります。

表1. 成果物表の例

成果物ID 説明
D1 コンパイルすれば動作するプログラムのコード。
D2 コードレビューによって付けられた D1 へのコメント。
D3 D1 が D4 を満たしていない入力を記載したバグチケット。
D4 D1 の満たすべき仕様。

表2. プロセス表の例

プロセスID 説明
P1 仕様にもとづきコードを書く。レビューコメントおよびバグチケットが出なくなるまで修正を繰り返す。
P2 実装していない者がコードをレビューする。
P3 仕様に照らして欠陥を発見する。

重要な概念として 初期成果物最終成果物 があります:

  • 初期成果物 は、どんなプロセスからも出力されない、すなわち所与の成果物です
  • 最終成果物 は、どんなプロセスの入力にもならない、すなわちプロジェクトの目当ての成果物です。プロジェクトは 最終成果物 を出力することを目的としています

スケジュールの理論

スケジュールの理論とは、プロセスの依存関係および各プロセスの所要時間を与えるととりえるプロセスの実行順序とその所要時間を定める体系です。 スケジュールの理論を使うと、プロセスの実行順序がプロセスの依存関係に沿っているかどうかの判定やその実行順序を採用した場合のトータルの所要時間を計算できます。

スケジュールの理論として PERT 図を与える Program Evaluation and Review Technique(PERT)や資源制約付きスケジューリング問題(Resource-Constrained Project Scheduling Problem; RCPSP)の各種モデルが知られています。 今回は PFD を元にした3つのモデルを紹介します:

  1. 無限資源・フィードバック線なし
  2. 有限資源・フィードバック線なし
  3. 有限資源・フィードバック線あり(pfd-tools で fsm と呼んでいるものです)

今回紹介するモデルの中では、資源無制限・フィードバック線なしのモデルが最も簡単です。 そのため、まず資源無制限・フィードバック線なしのものを説明します。 次に資源の制限を考慮したモデル、次にさらにフィードバック線も考慮したモデルへとステップアップしていきます。

モデルの紹介

無限資源・フィードバック線なし

このモデルは、あるプロセスの入力成果物がすべて揃い、かつそのプロセスが一度も実行されたことがなければそのプロセスを 実行可能 としたものです。 フィードバック線がないので手戻りはなく、どんなプロセスも1回より多く実行されることはありません。 PERT はこのモデルに相当します。

このモデルは資源が無制限であるため単純ですが非現実的な前提をもっています。 ふつう、プロセスの実行には実行者という資源が必要で、現実的には実行者は同時に複数のことをできません(できたとしても能率が落ちます)。 そのためこの方法で計算したスケジュールは現実的なそれより所要時間を短くしがちです。 もしより現実的な所要時間を計算したい場合は後に説明する資源の制限を考慮したモデルを使う必要があります。

例として手戻りのないソフトウェア開発プロセスの実行が進展していく様子を示します。

無限資源・フィードバック線なしのモデルの実行が進展していく様子の例

全体の所要時間は次のように計算されます。 プロセスが複数あればそれは並列化直列のいずれかで接続されています。 並列プロセスの所要時間は並列に実行されるプロセスの所要時間のうち最大のものです。 直列なプロセスの所要時間は実行されるプロセスの実行時間の総和です。 これを再帰的に計算すると所要時間が一意に定まります。

有限資源・フィードバック線なし

このモデルは、あるプロセスの入力成果物がすべて揃い、かつそのプロセスが一度も実行されたことがなく、かつ必要な資源を占有できれば、そのプロセスを 実行可能 としたものです。 フィードバック線がないので手戻りがないことは変わりません。 前のモデルに加えて、資源の占有という条件が加わっています。 すなわち、同時に実行される複数のプロセスはある資源を同時に使用することができないということです。 前のモデルでは条件をすべて満たしたものをすべて実行することにできましたが、このモデルでは資源に被りのないように実行するプロセスを選ばないといけません。

このモデルではプロセスの依存関係に加え、プロセスごとに必要資源とそのときの消費作業量の関係を与えなければなりません。 たとえばAさんのみが担当できるプロセスでは、必要資源はAさん1人で消費作業量は1人分(=1人日)を与えるとよいです。 他にも複数人で手分けできる場合、消費作業量は必要資源の数に応じて大きくなるようにします。

例として手戻りのないソフトウェア開発プロセスの実行が進展していく様子を示します。

有限資源・フィードバック線なしのモデルの実行が進展していく様子の例

時刻2で同時に実行されるプロセス(時刻1→2の P2, P3)の必要資源に被りがあったためP2またはP3のどちらか一方しか実行できなくなっています。この図では P2 を先に実行し、P2 が終わったら P3 を実行する実行計画を選んでいます。

全体の所要時間の計算方法は状態遷移モデルで定義されます。 状態には時刻と各プロセスの残作業量が記録されています。

  • 初期状態 では時刻0、残り作業量はあらかじめ見積もっておいた所要作業量と同じです
  • 次状態の決め方は次のとおりです。現在の状態で 割当可能 なプロセスを得ます。 割当可能 とは、あるプロセスの入力成果物がすべて揃い、かつその残り時間が0でない(1度も実行が完了していないことと同値)ことです。定義より、割当可能 ならば必要資源を割り当てるとかならず 実行可能 です。この 割当可能 なプロセスの部分集合のうち、集合内のプロセスのすべての組み合わせにおいて必要資源集合に共通部分のないものが 有効な割当集合 です。現在の状態から 有効な割当集合 の要素を1つ選ぶと消費作業量がわかるので現在の残作業量から消費作業量を差し引きいずれかのプロセスの残作業量が 0 になる最短の経過時間を計算し、これを次の状態の時刻とします。現在時刻と次の状態の時刻の差を計算し、その 時間経過 * 消費作業量 を差し引いて次の残作業量を定めます。こうして 有効な割当集合 ごとに次の状態を定めます(つまり割当を状態遷移ラベルとした状態遷移モデルになっています)
  • ある状態のすべてのプロセスの残作業量が0であれば(=すべてのプロセスが1度は実行されたら)、その状態を完了状態と呼びます。どんなプロセスかつどんな遷移経路でも 完了状態 にいつか到達します5

ここで 初期状態 から 完了状態 に至るまでの割当の列(=遷移経路)を 実行計画 といいます。 任意の 実行計画 からガントチャートを計算できるため 実行計画 は重要な概念です。 各 実行計画 の所要時間は 完了状態 の時刻です。 ふつう、 実行計画 は複数ありえます。 そのため所要時間が最短となる 実行計画 を探索するとよいです。 最短の保証が必要であればダイクストラ法、最短ではないがそこそこのものが欲しければビームサーチ、とにかく短い処理時間で結果を出したければ貪欲法を利用できます。

有限資源・フィードバック線あり

このモデルは、あるプロセスのフィードバックされた入力成果物をのぞいたすべての入力成果物が揃い、かつフィードバックされる入力成果物を含めたいずれかの成果物の版が更新されてから一度も実行されておらず、かつ必要な資源を占有できれば 実行可能 としたものです。 このモデルが pfd-tools に搭載されています。

このモデルではすべてのプロセスは2回以上実行されえます。 前のモデルに加えて、版の更新を処理したか否かという条件が加わっており、成果物の版という概念をもちます。 前のモデルでは成果物はただ1回のみ作成されるので版という概念はありませんでした。

フィードバック成果物にはこれ以上変更がおきない最終版を定めておきます。 最終版に到達した成果物はそれ以降版に変更がないとみなします。 そうしないと版の更新がなくならないので永遠にプロセスを実行し続けられてしまうからです。 プロセスは複数回実行されうるので、2回目以降の所要作業量の計算方法を用意しておく必要があります。 ふつう現実では手戻りするごとに所要作業量は減っていきます。 今回の方法では繰り返すごとに所要作業量は前回の x% になる、のようにモデリングしています。

例として小規模ソフトウェアの開発プロセスの実行が進展していく様子を示します(進展の様子は pfd-tools の pfdrun コマンドや pfdrungraph コマンドから確認できます)。

有限資源・フィードバック線ありのモデルの実行が進展していく様子の例

全体の所要時間の計算方法は前のモデルの状態遷移モデルと似ています。 状態には時刻と各プロセスの残作業量、プロセスごとに版が更新されてからまだ利用されていない成果物の集合、成果物ごとに版数が記録されています。

  1. 初期状態 では時刻0、残り作業量は所要作業量と同じ、初期成果物 を入力とするプロセスについて 初期成果物 は版が更新されてから利用されていないとします
  2. 割当可能性 は前のモデルと少しだけ定義が異なります。あるプロセスが 割当可能 とは、そのプロセスにフィードバックされた入力成果物をのぞいたすべての入力成果物が揃い、入力成果物の版が更新されてからまだ利用していないものがあることです。割当可能 なら必要資源を割り当てられればかならず 実行可能 です。この 割当可能 なプロセスの部分集合のうち、集合内のプロセスのすべての組み合わせにおいて資源集合に共通部分のないものが 有効な割当集合 です。現在の状態から 有効な割当集合 から要素を1つ選ぶと消費作業量がわかるので現在の残作業量から消費作業量を差し引きいずれかのプロセスの残作業量が 0 になる最短の経過時間を計算し、これを次の状態の時刻とします。現在時刻と次の状態の時刻の差を計算し、その時間経過x消費作業量を差し引き次の残作業量のベースを定めます。このベースから残作業量が0のプロセスについて再実行する場合の所要時間分だけ回復(今回の事例ではプロセスごとに再実行所要時間割合xを定めておき、所要時間 * x^実行回数 で計算しました。プロセスの実行回数はそのプロセスの出力成果物の版と一致します)して次の残作業量を定めます。またベースから完了したプロセスがわかるので完了したプロセス P の入力成果物の未利用フラグを降ろし、P の出力成果物を入力とするプロセス P' ごとに未利用のフラグを立てます。こうして有効な割り当てごと次の状態が定まります。これも前のモデルと同じく割当を状態遷移ラベルとした状態遷移モデルになっています
  3. ある状態ですべてのプロセスが 割当不能 であればその状態を 完了状態 と呼びます。どんなプロセスかつどんな遷移経路でもいつか完了状態に到達できるかはまだ証明しきれていませんが経験的には真です

前のモデルと同様に、初期状態 から 完了状態 に至るまでの割当の列(=遷移経路)を 実行計画 といいます。 任意の 実行計画からガントチャートを計算できるため 実行計画 は重要な概念です。 各実行計画の所要時間は、完了状態の時刻です。 前のモデルと同様、ふつう実行計画は複数ありうるので所要時間が最短となる実行計画を探索するとよいです。 最短の保証が必要であればダイクストラ法、最短ではないがそこそこのものが欲しければビームサーチ、とにかく短い処理時間で結果を出したければ貪欲法を利用するとよいでしょう。

紹介しなかった重要な要素

紙幅の都合で紹介できませんでしたが実際のマスタースケジュールを計算するために必要な2つの概念があるので紹介しておきます。

時刻つき初期成果物

初期成果物が利用可能となる時刻を与えられるようにする拡張です。 プロジェクト外のプロセスによって未来に作成され納期が約束されている成果物をこれで表現します。

トリガー

プロセスの割当可能性に追加条件を与える拡張です。 テストは直前のテストレベルのテストが完了していないと普通開始しません。 この制約を前のテストレベルのフィードバックループが完了していないと開始できないというトリガーで表現できます。

マスタースケジュール

前述の通りプロセスと工程をマッピングするとその開始時刻と終了時刻からマスタースケジュールを計算できます。 開始時刻と終了時刻はすべて実行計画に含まれているので、実行計画とプロセスから大局的な工程へのマッピングさえあればマスタースケジュールを計算可能です(pfd-tools では planmaster がこれを担当します)。

クリティカルパス

クリティカルパス とは、所要時間または所要作業量を増やすと全体の所要時間が増えるプロセスからなる集合のことです。 たとえば並列のプロセスA、B があり、それぞれの所要時間を 5、 10 とします。

プロセスAとBのガントチャート

プロセスBの所要時間を増やせば全体の所要時間は増えますがプロセスAの所要時間を増やしても全体の所要時間は増えません。

プロセスAとBの所要時間が伸びた場合の比較

つまりBは クリティカルパス に含まれており、Aは含まれていません。

クリティカルパス 上のプロセスの所要時間が予定よりも伸びると全体の所要時間が伸びます。 そのため クリティカルパス 上のプロセスは要注意なプロセスです。

また クリティカルパス ではないプロセスの所要時間または所要作業量を増やしても全体の所要時間は増えません。 この増やしても全体の所要時間を変えない最大の幅のことを 全余裕 (Total Float)と呼びます。 クリティカルパスに含まれるすべてのプロセスの全余裕は0です。

プロセスAとBの全余裕

まだ所要時間または所要作業量を見積もれていないプロセスがあるとき、その 全余裕 を計算し、直列な部分の所要時間の総和が全余裕を超えるかどうかをインタビューすると迅速に全体の所要時間が伸びそうかどうかを判断できます。 全余裕 を超える場合、そのプロセスは クリティカルパス になるので要注意です。

工期短縮においても クリティカルパス が重要です。 工期短縮をするには、次のサイクルを何度も繰り返す必要があります:

  1. クリティカルパス を特定する
  2. その クリティカルパス 上のすべてのプロセスを改善する
  3. 1 に戻る

繰り返す必要があるのは、ある クリティカルパス 上のプロセスの所要時間または所要作業量を減らしていくと、あるところから全体の所要時間が減らなくなることがあるからです。 たとえば並列のプロセスA、Bの例では、プロセスBの時間を5より短くしても、全体の所要時間は5より短くはなりません。

プロセスBの最小弾性値

これは クリティカルパス がBを含むものからAを含むものに切り替わったため起きています。

このように クリティカルパス 上のプロセスにはその所要時間または所要作業量を減らすと全体の所要時間を減らせる最小の所要時間または所要作業量があるときがあります。 これを 最小弾性値 と呼びます6最小弾性値 のあるプロセスは、そのプロセスを改善すれば全体の所要時間を短縮できるため注目すべきです。

クリティカルパスを特定するには、実行計画を固定し、調べたいプロセスの所要作業量を伸ばし全体の所要作業量が伸びることを確認していくとよいです。 消費作業量は1と仮定し、調べたいプロセスの所用作業量を伸ばす幅を x とし、全体の所要時間が y だけ増えたとします。x - y全余裕 です。 全余裕 が 0 であるプロセスは クリティカルパス に含まれています。 こうしてクリティカルパスの特定ができます(criticalpath コマンドで同じことをしています)。

また同様に消費作業量が1であると仮定し、クリティカルパス 上の調べたいプロセスの所用作業量を 0 にし、全体の所要時間が z だけ減ったとします。所用作業量 - z最小弾性値 です。 こうして 最小弾性値 を計算できます(criticalpath コマンドで同じことをしています)。

全体の所要時間の短縮

クリティカルパス を特定し、その クリティカルパス 上のすべてのプロセスを改善すると全体の所要時間を短縮できます。 プロセスの改善には次のような方法があります。

効率化

直列なプロセスを並列にする

直列部分を並列にするグラフ操作に相当します。 所要時間が総和からmax関数に変わるので所要時間を短縮できます。 ただ本来予定されていた成果物を利用せず前段階の成果物を利用するように変更するため投機的になることが多いです。

手分け可能にする

プロセス表の資源割当と消費作業量の組の列操作に相当します。 空いている資源があれば、これを活用して消費作業量を増やせるので所要時間を短縮できます。 たとえば成果物を分解し依存のない構成部分を手分けして作成できるようにすると実現できます。

Cost から Delivery への転換

ありものを使う

ある成果物から逆向きに到達可能な要素を除去し、初期成果物 に置き換えるグラフ操作に相当します。 除去されたプロセスが クリティカルパス に含まれるとそれらの所要時間を0にできるので大幅な所要時間を短縮できます。 ただしありものの調達コストが増えます。

ツールによって自動化する

プロセス表の資源割当制限緩和操作と消費作業量の増加操作に相当します。 ツールの利用にコストがかかる場合はコストが増えます。

資源を追加する

資源表への行追加操作に相当します。 有効な資源割当集合が増えるため手分け可能なプロセスがあれば消費作業量を増やせて所要時間を減らせます。 遅れているプロジェクトへの増員はプロジェクトを余計に遅らせることは人月の神話で有名です。 ただし PFD と要素表が十分に記述できていれば学習コストと連絡コストはそこまでかからないと見込めるためブルックスほど筆者は悲観的ではありません。

Quality から Delivery への転換

スコープを縮小し、プロセスの所要時間または所要作業量を縮小する

プロセス表の所要時間または所要作業量を小さくする表操作に相当します。 到達可能なすべての成果物(最終成果物を含む)のスコープ縮小を伴うことに注意が必要です。

成果物の品質低下リスクを許容し、プロセスの所要時間を減らす

プロセス表の所要時間または所要作業量を小さくする表操作に相当します。 最終的な品質が酷いことになるリスクを負います。なるべく避けるべきです。

本事例のスケジュール策定方法

本事例では前述のスケジュールの理論の3つ目のモデル(資源制限・フィードバック線あり)を利用して、次のようにスケジュールを策定しました。実際にこの計画通りのスケジュール、品質で達成できるかどうかはこれから明らかになります。

$ # PFD を Google Drive 上の diagrams.net を使って関係者と共同で作成した。これを手元にダウンロードしておく:
$ cat ./pfd.drawio
<mxfile host="65bd71144e">
    <diagram id="ZC_KSqUXoirMDHc_9cWT" name="P0">
...

$ # pfdrenum で採番しておく:
$ pfdrenum -inplace ./pfd.drawio

$ # Google Drive 上の PFD へすぐ上書きしておく。

$ # 空の複合成果物表を作成しておく:
$ printf "ID\tDescription\tDeliverables\n" > ./cd.tsv

$ # PFD からプロセス表を作成する:
$ pfdtable -p ./pfd.drawio -cd cd.tsv -t ap > ./ap.tsv

$ # プロセス表に拡張カラムを追加しておく。
$ edit ./ap.tsv
$ head -1 ./ap.tsv
ID      Description     予想作業量      予想手戻り作業量割合    必要資源        開始条件        グループ        マイルストーン

$ # PFD から成果物表を作成する:
$ pfdtable -p ./pfd.drawio -cd cd.tsv -t ad > ./ad.tsv

$ # PFD から合成プロセス表を作成する:
$ pfdtable -p ./pfd.drawio -cd cd.tsv -t cp > ./cp.tsv

$ # PFD とプロセス表から資源表を作成する:
$ pfdtable -p ./pfd.drawio -cd cd.tsv -t r > ./r.tsv

$ # マスタースケジュール用のプロセスグループ表を作成する(pfdtable はまだ未対応):
$ edit ./g.tsv

$ # マスタースケジュール用のマイルストーン表を作成する(pfdtable はまだ未対応):
$ edit ./m.tsv

$ # PFD 上のすべてのプロセスを関係者と共同で2点見積り(楽観と悲観)した。過去データがなかったため当てずっぽうで繰り返し再実行所要時間割合と成果物の最終版数を決めた
$ # ./ap1.tsv に楽観の予想作業量を記載する:
$ cp ./ap{,1}.tsv
$ edit ./ap1.tsv

$ # ./ap2.tsv に悲観の予想作業量を記載する:
$ cp ./ap{,2}.tsv
$ edit ./ap2.tsv

$ # いちいちすべての要素表を指定するのは面倒なのでプロジェクトファイルを作成しておく:
$ echo '{"pfd":"pfd.drawio","atomic_process_table":"ap1.tsv","atomic_deliverable_table":"ad.tsv","resource_table":"r.tsv","composite_deliverable_table":"cd.tsv","milestone_table":"m.tsv","group_table":"g.tsv"}' > ./project1.json
$ echo '{"pfd":"pfd.drawio","atomic_process_table":"ap2.tsv","atomic_deliverable_table":"ad.tsv","resource_table":"r.tsv","composite_deliverable_table":"cd.tsv","milestone_table":"m.tsv","group_table":"g.tsv"}' > ./project2.json

$ # 整合性を確認する。pfdlint が正常終了したら問題なし。異常終了したら正常終了するようになるまで問題を修正する:
$ pfdlint -f ./project1.json
$ pfdlint -f ./project2.json

$ # 楽観側の実行計画を作成する:
$ pfdplan -f ./project1.json -poor -out-format plan-json | tee ./plan.json
{
  "initial_state": {
    "time": 0,
...

$ # 実行計画を Google Sheets の Timeline ビューで読める形に変換する:
$ pfdtimeline -f ./project1.json -start 2025-04-01 -not-biz-days <(holidays -locale ja) ./plan.json | tee ./timeline1.tsv
AtomicProcess   NumOfComplete   AllocatedResources      Description     StartTime       EndTime Start   End
P1      0       Biz     要求分析する    2025-04-08 10:00:00     2025-04-22 10:00:00     5       15
...

$ # Google Sheets に貼り付ける:
$ pbcopy < ./timeline1.tsv

$ # 悲観側の実行計画を作成する:
$ pfdplan -f ./project1.json -poor -out-format plan-json | tee ./plan.json
{
  "initial_state": {
    "time": 0,
...

$ # 実行計画を Google Sheets の Timeline ビューで読める形に変換する:
$ pfdtimeline -f ./project1.json -start 2025-04-01 -not-biz-days <(holidays -locale ja) ./plan.json | tee ./timeline2.tsv
AtomicProcess   NumOfComplete   AllocatedResources      Description     StartTime       EndTime Start   End
P1      0       Biz     要求分析する    2025-04-08 10:00:00     2025-04-22 10:00:00     5       15
...

$ # Google Sheets に貼り付ける:
$ pbcopy < ./timeline2.tsv

$ # Google の Timeline ビューで実行計画を確認し、意図していないプロセスの依存関係、トリガーがないか確認し、問題があれば原因究明に pfdquery 等を使いながら PFD やプロセス表を修正する。
$ pfdquery -f ./project.json P20
QUERY   SOURCE  RESULT
P20     PFD[desc]       IP制限状態でリリースする
...

$ # 楽観・悲観のリリース時刻の差を確認し、不確実性としてレポートしておく。
$ # 楽観xバッファ1.5倍でマスタースケジュールを作成する:
$ planmaster -ap ./ap1.tsv -g ./g.tsv -m ./m.tsv -p ./plan.json -b 1.5 -start 2025-04-01 -not-biz-days <(holidays -locale ja) | tee ./master.tsv
Group   GroupDescription        Milestone       MilestoneDescription    Start   End
Admin   管理者向け機能  M1      要求分析        2025-04-10 14:30:00     2025-05-02 14:30:00
...

$ # Google Sheets にマスタースケジュールを貼り付ける
$ pbcopy < ./master.tsv

$ # この時点で納期が間に合うかどうかを確認する。今回は間に合ってなかったのでプロセスの改善を開始した。
$ # クリティカルパス分析をする。全余裕(TOTAL_FLOAT)が 0 なプロセスがクリティカルパスに含まれている:
$ criticalpath -f ./project.json -poor | tee ./criticalpath.tsv
ATOMIC_PROCESS  TOTAL_FLOAT     MINIMUM_ELASTICITY
P1      0.00    10.00
P2      35.73   5.00
...

$ # クリティカルパス上の全プロセスについて、スコープアウト可能なオプションを担当者へヒアリングし、責任者の承認を得てスコープアウトする。スコープ縮小後の予想作業量に修正する。
$ edit ./ap1.tsv
$ edit ./ap2.tsv

$ # クリティカルパス分析を繰り返し、目標に達するまでスコープ縮小を続ける。目標に達したらそのスコープを確定し、マスタースケジュールを再計算する。
$ pfdplan -f ./project1.json -poor -out-format plan-json | tee ./plan.json
$ planmaster -ap ./ap1.tsv -g ./g.tsv -m ./m.tsv -p ./plan.json -b 1.5 -start 2025-04-01 -not-biz-days <(holidays -locale ja) | tee ./master.tsv
Group   GroupDescription        Milestone       MilestoneDescription    Start   End
Admin   管理者向け機能  M1      要求分析        2025-04-10 14:30:00     2025-05-02 14:30:00

$ # Google Sheets のマスタースケジュールを更新して作業完了。
$ pbcopy < ./master.tsv

途中で登場した成果物の内容(本記事用に適当に作成しています):

PFD(./pfd.drawio

マスタースケジュールを計算するために作成した PFD の例

プロセス表(./ap1.tsv

ID Description 予想作業量 予想手戻り作業量割合 必要資源 開始条件 グループ マイルストーン
P1 要求分析する 10 0.1 Biz:1 User,Admin M1
P2 画面遷移仕様を記述する 10 0.1 Front,Designer:2;Designer:1 User,Admin M2
P3 インフラ設計する 5 0.1 SRE:1 User,Admin M3a
P4 APIを設計する 8 0.1 App:1 User,Admin M3a
P5 テーブル設計する 10 0.1 App:1 User,Admin M3a
P6 サーバーを実装する 20 0.1 App:1 User M3b
P7 管理画面を実装する 5 0.1 App:1 Admin M3b
P8 仕様を妥当性検証する 10 0.1 SET:1 \complete(*) User,Admin M2
P9 正当性検証を設計する 10 0.1 TE:1 User M3c
P10 クライアントを実装する 15 0.1 Front:1 User M3b
P11 画面表示仕様を記述する 10 0.1 Front,Designer:2;Designer:1 User M2
P12 使用性をレビューする 7 0.1 Designer:1 User M2
P13 SRE によるコードレビュー 3 0.1 SRE:1 \complete(*) User M3b
P14 管理オペレーションを設計する 5 0.1 Ope:1 Admin M3a
P15 オペレータによる受入テスト 5 0.1 Ope:1 \complete(*) Admin M4
P16 サーバーとクライアントを結合する 0.2 0.1 App,Front:1 User M3b
P17 開発環境でシステムテストする 10 0.1 TE:1 \complete(*) User M4
P18 ステージング環境で外部サービスと結合する 0.2 0.1 App:1 User M3b
P19 システム統合テストする 5 0.1 TE:1 \complete(*) User M5
P20 IP制限状態でリリースする 0 0.1 SRE:1 \complete(*) User,Admin M6
P21 本番検証する 1 0.1 TE:1 \complete(*) User,Admin M6
P22 IP制限解除する 0 0.1 SRE:1 User,Admin M7

合成プロセス表(./cp.tsv

ID Description
(空) (空)

成果物表(./ad.tsv

ID Description 利用可能時刻 最大版
D1 リリースされユーザーが利用できる新機能システム。 - -
D4 使用性を改善する画面表示仕様の Figma 上のコメント。 - 2
D5 安全性・活性・到達可能性違反を引き起こす入力。 - 1
D7 GitHub 上の SRE によるコードレビューコメント。 - 2
D8 オペレータによる受入テストバグチケット。 - 2
D9 CS が受信したユーザーからサービスへの改善要望。 0 -
D10 経営戦略。どのようなユーザーを今後狙っていくかが指示されている。 5 -
D11 外部サービスX。 15 -
D12 機能要求。活性と到達可能性の形式で表現されている。 - -
D13 非機能要求。安全性と性能要件の形式で表現されている。 - -
D14 ユーザーのペルソナ。 0 -
D15 画面遷移仕様。画面を状態とし、イベント・ガード・事後条件の3つ組を遷移に付与した画面遷移図。 - -
D16 インフラ構成図。 - -
D17 シグネチャ、事前条件・事後条件の組で表現されたAPI仕様。 - -
D18 DDLで表現されたテーブルのテーブル定義書。 - -
D19 サーバー実装。 - -
D20 オペレータが操作する管理画面の Web サーバー実装。 - -
D21 ユーザー向け機能に関連するテストケース。 - -
D22 クライアント実装。 - -
D23 画面表示仕様。画面ごとに画面UIの代表的なレイアウトおよび画面UI間の相互作用が記述されている。 - -
D24 管理オペレーション手順書。想定される管理オペレーションが必要な状況ごとに対応する管理オペレーションの手順が書かれている。 - -
D25 開発した新機能システム。 - -
D26 外部サービスXと統合された新機能システム。 - -
D27 IP制限が社内向けに制限された外部サービスXと統合された新機能システム。まだユーザーはサービスを利用できない。 - -
D3.1 JIRA 上の本番検証由来のバグチケット。 - 1
D3.2 JIRA 上のシステム統合テスト由来のバグチケット。 - 2
D3.3 JIRA 上のシステムテスト由来のバグチケット。 - 3

複合成果物表(./cd.tsv

ID Description Deliverables
D3 BTS上のユーザー向け機能のバグチケット。 D3.1,D3.2,D3.3

プロセスグループ表(./g.tsv

ID Description
User ユーザー向け機能
Admin 管理者向け機能

マイルストーン表(./m.tsv

ID Description Groups Successors
M1 要求分析 User,Admin M2
M2 仕様記述 User,Admin M3a,M3b,M3c
M3a 設計 User,Admin M4
M3b 実装 User,Admin M4
M3c テスト設計 User,Admin M4
M4 システムテスト User,Admin M5
M5 システム統合テスト User,Admin M6
M6 本番検証 User,Admin M7
M7 リリース User,Admin

終わりに

この記事ではマスタースケジュールの理論とコインチェックにおける実践を紹介しました。 本記事の内容をまとめると次のようになります:

  • PFD と要素表を書けばマスタースケジュールを機械的に計算できる
  • スケジュールの理論を使うと改善すべき箇所がピンポイントでわかる
  • 現実のプロジェクトに適用でき、実際にスケジュール作成に使える

参考文献


  1. 「インプットをアウトプットに変換する,相互に関連する又は相互に作用する一連の活動」ISO25000:2017
  2. 清水氏の提唱したオリジナルでは成果物を書類記号であらわします。また書類記号に拘らず成果物に合わせてわかりやすい記号を使うとよいともしています。ここでは説明を単純に保つため矩形で統一しています。
  3. プロセスの依存関係をあらわす代表的な表現形式に PERT 図(またはアローダイアグラム)があります。成果物をイベント、プロセスを矢線とし、そのプロセスの所要時間を矢線に付属すると PFD を PERT 図に変換できます。つまり PFD は PERT 図で成果物を強調したスーパーセットとみなせます。等価ではなくスーパーセットであるのは後述するフィードバック線があるからです。フィードバック線は PERT 図には含まれません。
  4. 清水氏の提唱したオリジナルの定義には破線の矢線はありません。オリジナルの定義にある更新の方向を明らかにするためのアレンジです。
  5. PFD はフィードバック線を除けば有限な DAG であり、かつ消費作業量は 0 より大きいですから、どんな状態でも完了状態でなければ 割当可能 なプロセスが1つはあります。したがって遷移するたびに残作業量の総和が狭義単調減少します。そのためいつかかならず完了状態に到達します。
  6. これは筆者の命名です。ここでは 弾性 を局所のプロセスの所要時間または所要作業量を増減させると全体の所要時間を増減させることとしています。このように弾性を定義すると、 全余裕 に所要時間を足したものが 最大非弾性値 となります。最小弾性値 に対応する PERT の用語はないようです。