「できません」ではなく「何を外しますか」
目標
範囲の内外を判定するルールを、順序のあるファイルに固めて、判定ツールを作ります。前提ごとに、壊れたときの結果と確認方法と有効期間を書いた元帳を置き、期限が切れた確認を見つけ出します。範囲外の要望には、断る文章ではなくトレードオフ表で答えます。
なぜ重要なのか
着手の最初の週に決めた範囲は、2週目から漏れ出します。合意書は引き出しの中にあり、読んでみても、この要望がその文に当たるのかがあいまいです。ルールを順序のあるファイルに書いて判定ツールを動かせば、「なぜこれはできないのですか」にルールを1つ見せればよく、ルールが間違っていればルールを直せば済みます。人を説得する代わりにファイルを直す会話になります。 どのルールにも当たらなかった要望は、範囲外ではなく判断保留です。当たらなかったものを自動的に範囲外へ押しやると、ルールの抜けが永遠に見えません。保留の一覧がそのまま次の会議の議題です。 前提も同じです。会議で聞いた話を前提に計画を立て、3週間後にそれが間違っていたとわかりますが、そのときにはすでにその上にスケジュールが載っています。前提ごとに、壊れたら何が崩れるかと確認方法と有効期間と持ち主を書いておけば、期間が過ぎた前提が一覧に浮かび上がります。 採点ツールは、提出された数字を信じません。毎回違うルールと要望で、作成した判定ツールを実際に動かして、判定と根拠のルールを照合し、前提元帳には境界の日付を入れて、期限切れの判定を確かめます。
ステップ
- /root/scope/gen_engagement.pyを作成して実行し、requests.json(25件)・baseline.json(10件、予算30日)・sow.mdを作成してください。
- 合意書を読み、/root/scope/scope_rules.jsonにルールを順番に書いてください。ルールごとにid・effect・match・reasonを入れ、狭いルールを上に置きます。
- /root/scope/judge.pyを作成し、要望ごとに最初に当てはまるルールで範囲内・範囲外・保留に分け、verdicts.jsonを書かせてください。
- matchにactionとtagを追加し、条件がすべて当てはまるときだけルールが当たるようにしてください。判定には、どのルールが決めたかも書きます。
- /root/scope/assumptions.jsonに前提を5つ以上書いてください。前提ごとにstatement・if_broken・verify_how・verified_on・valid_days・ownerを入れます。
- /root/scope/assumptions.pyを作成し、
--as-ofの基準で期限が切れた前提を見つけて、expired.jsonを書かせてください。 - 新しく入ってきた範囲外の要望RQ-021-NEWについて、トレードオフ表を書いてください(保存先: /root/scope/tradeoff.json)。
- /root/scope/scope_report.mdに4つの節で報告してください。
参考
- 要望の項目:
{"id", "title", "system", "action", "tags": [...], "est_days", "from"}。systemはwms・crm・billing・bi、actionはread・fix・change・build・trainです。 - ルールファイル:
{"rules": [{"id": …, "effect": "in"|"out", "match": {"system"?: …, "action"?: …, "tag"?: …}, "reason": …}]}。matchの条件がすべて当てはまって初めて、そのルールが要望に当たります。tagは、要望のtagsにその値が入っていれば当てはまります。一覧の順序が優先順位で、最初に当てはまったルールが勝ちます。 - 判定の実行契約:
python3 /root/scope/judge.py --rules <규칙> --requests <요청> --out <판정 JSON>(プレースホルダーはルール、要望、判定JSONのパスです)は、1行の要約を標準出力に出して、終了コード0で終わります。入力を読み込めない場合は3です。 - 判定JSON:
{"counts": {"in", "out", "undecided"}, "verdicts": [{"id", "verdict", "rule"}]}。verdictsは要望idの昇順で、ruleは決めたルールのidで、保留ならnullです。 - 前提元帳:
{"assumptions": [{"id", "owner", "statement", "if_broken", "verify_how", "verified_on": "YYYY-MM-DD", "valid_days": 정수}]}(プレースホルダーは整数です)。 - 期限切れの実行契約:
python3 /root/scope/assumptions.py --ledger <원장> --as-of <YYYY-MM-DD> --out <결과 JSON>(プレースホルダーは元帳と結果JSONのパスです)。期限日は확인일 + valid_days(韓国語の式は「確認日 + valid_days」という意味です)で、基準日が期限日を過ぎて初めて期限切れです(期限日の当日はまだ有効です)。 - 期限切れJSON:
{"as_of", "items": [{"id", "expires_on", "expired"}], "expired": [id...], "valid": [id...]}。itemsはidの昇順です。 - トレードオフ表:
{"request_id", "added_days", "dropped_days", "drop": [{"id", "est_days", "reason"}], "question"}。外そうと提案する作業の合計が新しい要望のコスト以上で、その束からどれか1つを外すと足りなくなる必要があります。priorityがmustの作業は交換の対象ではありません。questionは、外す作業のidをすべて含む1文で、疑問符(?)で終わります。 - よくあるミス: 当たらなかった要望を範囲外へ押しやること、広いルールを上に置いて狭いルールが永遠に当たらなくなること、期限の境界を1日ずらして計算すること、トレードオフ表にmustの作業を入れること。
- 前提の基準日2026-09-17、有効期間を日単位で数える方式、トレードオフ表の最小性の条件は、このラボの前提です。標準が決めるものではなく、チームが合意してファイルに書いておく値です。
- 参考ドキュメント: RFC 2119とRFC 8174は規則文の強さを語で固定する方法を、RFC 3339は日付の表記を、Python datetimeドキュメントは日付の計算を説明しています。
着手資料一式を広げる
/root/scope/gen_engagement.pyを作成して実行し、/root/scope/requests.json(25件)、/root/scope/baseline.json(作業10件・予算30日)、/root/scope/sow.mdを作成してください。
着手のときに手にするのは、要望の一覧と、合意済みの作業の一覧と、合意書です。広げたら、まずsow.mdの6行を読んでください。次のステップのルールは、すべてそこから出てきます。
合意書をルールに移す
/root/scope/scope_rules.jsonにルールを順番に書いてください。ルールごとにid(一意)・effect(inまたはout)・match(system・action・tagのうち1つ以上)・reason(10文字以上)を入れます。ルールは5つ以上必要で、要望25件に当てはめたとき、範囲内・範囲外・保留がすべて1件以上出る必要があります。
狭いルールを上に置きます。個人情報に触れる作業はどのシステムでも範囲外なので一番上に来て、システム単位のルールはその下です。すべての要望を覆おうとしないでください。当たらなかったものは範囲外ではなく保留で、保留の一覧がルールの抜けを示します。
範囲内・範囲外・保留に分ける
/root/scope/judge.pyを作成し、要望ごとに最初に当てはまるルールで判定して、/root/scope/verdicts.jsonを書かせてください。どのルールにも当てはまらなければ、verdictはundecidedで、ruleはnullです。
要望をルールの一覧の上から順に当てはめ、最初に当てはまったルールで止めます。最後まで当たらなければ保留です。範囲外へ押しやらないでください。verdictsは要望idの昇順に並べ、countsに3種類をそれぞれ数えます。
条件がすべて当てはまるときだけ当てる
matchにactionとtagを追加し、条件がすべて当てはまるときだけルールが要望に当たるようにしてください。tagは、要望のtagsにその値が入っていれば当てはまります。判定には、決めたルールのidをそのまま書きます。
条件をORで扱うと、狭いルールが広いルールのように振る舞って、優先順位が崩れます。ルールに書かれた条件だけを見て、書かれていない条件にはどんな値でも通してください。採点ツールは、狭いルールと広いルールの順序を入れ替えながら、優先順位が守られているかを確かめます。
前提元帳を作る
/root/scope/assumptions.jsonに前提を5つ以上書いてください。前提ごとにid・owner・statement(15文字以上)・if_broken(15文字以上)・verify_how(10文字以上)・verified_on(YYYY-MM-DD)・valid_days(1以上365以下)を入れます。基準日2026-09-17に照らしたとき、すでに期限が切れた前提と、まだ有効な前提がそれぞれ1つ以上ある必要があります。
壊れたら何が崩れるかを書いてみると、ある前提は間違っていても何も起きず、ある前提はその上に計画全体が載っているとわかります。持ち主のいない前提は、期間が過ぎても誰も確認しないので、ownerを必ず書いてください。確認日と有効期間は、前提ごとに違う値にします。
確認の期限が切れた前提を見つける
/root/scope/assumptions.pyを作成し、--ledger --as-of --outで期限切れかどうかを判定して、基準日2026-09-17で実行し、/root/scope/expired.jsonを作成してください。期限日は確認日にvalid_daysを足した日で、基準日が期限日を過ぎて初めて期限切れです。
期限の境界を1日ずらして計算する間違いがよくあります。期限日の当日はまだ有効で、その翌日から期限切れです。結果には、前提ごとに計算した期限日も一緒に書いてください。そうすれば、顧客がいつまで有効なのかを見られます。
何を外しますか
新しく入ってきた範囲外の要望RQ-021-NEWについて、トレードオフ表を書いてください(保存先: /root/scope/tradeoff.json)。dropはbaselineの作業のうちpriorityがmustでないものであり、合計がadded_days以上で、そのうちどれか1つを外すと足りなくなる必要があります。questionは、外す作業のidをすべて含む1文で、疑問符(?)で終わります。
余裕を持たせて多く外そうと言うと、顧客は私たちが仕事を減らしたがっていると感じます。大きい作業から入れていき、合計がコストを超えたら止めて、その束から外してもよいものがないかをもう一度見直してください。必ずやるべき作業は交換の対象ではありません。
範囲と前提を報告する
/root/scope/scope_report.mdに、## 합의한 범위와 판정 결과、## 판단이 보류된 요청、## 전제와 만료된 확인、## 무엇을 빼겠습니까の4つの節で書いてください(韓国語の見出しは順に「合意した範囲と判定結果」「判断が保留された要望」「前提と期限が切れた確認」「何を外しますか」という意味です)。判定3種類の件数、保留された要望のid、期限が切れた前提のidとそれが壊れたら何が崩れるか、トレードオフ表の数字が、すべて出ている必要があります。
レポートは手で書かず、verdicts・expired・tradeoffの3つのファイルから生成してください。保留の一覧を隠さないでください。保留が5件なら、ルールに抜けが5つあるという意味で、そのまま報告すれば顧客が一緒に埋めてくれます。