docs: freeze approved weather and severance specifications

This commit is contained in:
Codex
2026-10-24 03:36:52 +09:00
parent 48d3b0023b
commit 4654789b01
7 changed files with 308 additions and 5 deletions
@@ -100,6 +100,30 @@
"reference": "execution/p05-02/SPEC.md", "reference": "execution/p05-02/SPEC.md",
"provenance_reference": "execution/p05-02/PROVENANCE.json", "provenance_reference": "execution/p05-02/PROVENANCE.json",
"implementation_note": "帳簿履歴を保持。口座欠如による移行判定と5空口座追加はOpusの実装仕様。F8は他の帳簿フィールドbyte不変を必須とする。SPEC §3.8。" "implementation_note": "帳簿履歴を保持。口座欠如による移行判定と5空口座追加はOpusの実装仕様。F8は他の帳簿フィールドbyte不変を必須とする。SPEC §3.8。"
},
{
"id": "A13",
"title": "天候の初期仕様",
"decision": "毎朝6時に晴れ60%・雨25%・マナ霧10%・嵐5%で抽選し、雨6時間・霧4時間・嵐2時間の後は晴れ(開始は6〜20時の30分刻み)。雨の間は新規来客を半分にし、帰宅予定の客は雨が止むまで滞在を延長(最大4時間)。マナ霧の魔法効率上昇は世界樹・マナ炉の産出1.2倍、興奮度上昇は成人確認済みの客の性欲の増加1.5倍。",
"origin": "user_answer_recorded_by_root_in_codex_conversation",
"approved_at_jst": null,
"answer_verbatim": "この初期仕様で進める",
"reference": "execution/p07-01/SPEC.md",
"provenance_reference": "execution/p07-01/PROVENANCE.json",
"implementation_note": "切り捨て・抽選の手順・保存される系列 weather・延長の記録・旧セーブの移行・拒否の規則は実装担当の選択で、人の新しい承認としない。SPEC §2・§4・§5。",
"recorded_at_utc": "2026-10-23T18:07:36Z (Root record time; the answer time is not recorded)"
},
{
"id": "A14",
"title": "一般従業員の解雇の退職金",
"decision": "退職金はその職員の日給の3日分。表金から払い、不足分を裏金で補い、合計でも足りなければ解雇しない。未払い給与は退職金と分けて保持し次の午前0時に精算する。退職金は帳簿で区別し、日次決算では運営費に計上する。",
"origin": "user_answer_recorded_by_root_in_codex_conversation",
"approved_at_jst": null,
"answer_verbatim": "この初期仕様で進める",
"reference": "execution/p16-01-dismiss/SPEC.md",
"provenance_reference": "execution/p16-01-dismiss/PROVENANCE.json",
"implementation_note": "日給×3の整数、補填と退職金の1つの取引、区分 STAFF_SEVERANCE と口座、旧セーブへの空の口座の追加、命令ごとに1回の記帳は実装担当の選択。進行中の襲撃の防衛者の扱い(R9)は Root の一時の境界で人の承認ではない。SPEC §3.5・§3.6・§6.3。",
"recorded_at_utc": "2026-10-23T18:07:36Z (Root record time; the answer time is not recorded)"
} }
], ],
"pending": [ "pending": [
@@ -130,7 +154,7 @@
{ {
"id": "D04", "id": "D04",
"title": "未指定の経済と行動係数", "title": "未指定の経済と行動係数",
"details": "税・利息・マナ・天候・環境・役割・成長等の必須値のうち未確定部分。A01〜A12の決定範囲はconfirmedと各仕様を参照。A10・A11は初期試験値であり、その他の未確定値を補完しない。", "details": "税・利息・マナ・天候・環境・役割・成長等の必須値のうち未確定部分。A01〜A14の決定範囲はconfirmedと各仕様を参照。A10・A11は初期試験値であり、その他の未確定値を補完しない。",
"needed_at": "各機能の本番値固定", "needed_at": "各機能の本番値固定",
"independent_work": "原本明示値、契約、候補比較を先行する。", "independent_work": "原本明示値、契約、候補比較を先行する。",
"kind": "required_per_feature" "kind": "required_per_feature"
@@ -0,0 +1,32 @@
{
"by": "Claude Opus 5.5 Desktop (local_a7f85421-3eed-4482-8030-c0dca669573a), the commander that wrote the proposal; the question was asked by Root (Codex)",
"decision_record": {
"path": "artifacts/original-completion-2026-10-02/USER_DECISIONS_WEATHER_SEVERANCE_R01.json",
"sha256": "c4a08ad4369ceec1738543540611a8c8921bd263d9fbe6b3e2621698f2957390"
},
"human_decision": {
"id": "A13",
"questionItemId": "[\"request_user_input_async\",\"call_d8c3f7424f574a0abd751ed8050687f0\",0]",
"question_verbatim": "天候機能は原本に効果量の指定がないため、次の初期仕様を採用して進めてよいですか。\n\n1. 毎朝6時に晴れ60%・雨25%・マナ霧10%・嵐5%で抽選。雨6時間・霧4時間・嵐2時間で、その後は晴れ。開始は6〜20時の30分刻み。\n2. 雨の間は新規来客を半分にし、帰宅予定の客は雨が止むまで滞在を延長(最大4時間)。\n3. マナ霧の「魔法効率上昇」は世界樹・マナ炉の産出1.2倍、「興奮度上昇」は成人確認済みの客の性欲の増加1.5倍として実装。\n\nこの数値と対応づけは実装担当の提案で、まだ確定していません。詳細は[天候機能の実装案](/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p07-01-registration-proposal-r01/PROPOSAL.md)です。資金管理の確認は回答を待つ間も継続します。",
"answer_verbatim": "この初期仕様で進める",
"source": "Actual user send_user_message_question_reply in this Codex conversation; recorded time is not the original answer time.",
"recorded_at_utc": "2026-10-23T18:07:36Z",
"proposal": {
"path": "artifacts/original-completion-2026-10-02/p07-01-registration-proposal-r01/PROPOSAL.md",
"sha256": "0772743ac11c466e4e9e283f5df2a8e652255c6db2964e83aab81d95f480a532",
"sha256_now": "0772743ac11c466e4e9e283f5df2a8e652255c6db2964e83aab81d95f480a532"
}
},
"interpretation_boundary": [
"Human-approved: the three items of the question and the linked proposal as presented.",
"Implementer choices (not a new human approval): floor rounding as written in the proposal, the draw procedure (integer 0-99 and the 29 start slots), the saved weather stream, the once-per-guest extension record, the furnace acceptance rule at the fog yield, the effect on the positive intimacy increment only, the old-save migration and the rejection rules (SPEC sections 4 and 5).",
"Not approved here: P07-02 environment, P07-03 news, other D04 values, P05-03 answers (still pending)."
],
"limits": [
"These answers supersede the stale heartbeat statements that weather and severance are awaiting user answers.",
"P05-03 questions remain unanswered.",
"No approval of additional combat dismissal rules, acceptance waivers, deletion of models/runtime/personal data, or exact future integration candidates is asserted.",
"This record is a decision record, not evidence of implementation or acceptance. Original completion remains 24/88 and 4/30 packages."
],
"original_completed": 24
}
@@ -0,0 +1,94 @@
# P07-01 雨と霧と自然天候 仕様(登録版 r01)
- 状態: 登録の前の仕様。Root が main の `docs/plans/original-completion-2026-10-02/execution/p07-01/SPEC.md` に固定し、その commit を `base_commit` にして通常の登録をする。登録・下書きは実装の受入ではない。原本への加算は whole-unit の final の後だけ。出典は同じフォルダの `PROVENANCE.json`。
- 前提: P04 は正式完了。ユーザーの指示(2026-10-23)「まずゲームとしての機能実装完了を優先して」「…統合試験の動作速度のチューニングを、今やるよりも機能実装の完了を優先して」により、機能の単位を先にする。P07-01 は P05-03 の人への問い(未回答)とは独立している。
## 1. 原本の条件(変えない)
- 原本 `docs/traceability/original/BASELINE.txt` 74 行(原文): `* **天候:** 雨(客足減・滞在延長)、嵐(新規客ゼロ)、マナの霧(魔法効率UP・興奮度UP)。` 214 行(原文): `* **上部:** 資金・マナ・資材リソース、時間・天候、世界樹ランク。`
- P07-01 の work: 雨の来客減・滞在延長、マナ霧、自然変化を実営業へ接続する。acceptance: 天候切替直前後、途中保存、自然来客の差を同条件で説明できる。
- P07 の acceptance のうちこの単位に当たる部分: 嵐で新規入館0、雨で来客減/滞在延長。天候変化の瞬間と保存再開が一致。
- 原子要件(P07): `AR.weather.rain_arrivals`(雨で客足が減る)、`AR.weather.rain_stay`(雨で滞在が延長する)、`AR.weather.fog_magic`(マナの霧で魔法効率が上がる)、`AR.weather.fog_excitation`(マナの霧で興奮度が上がる)、`AR.weather.storm_no_arrivals`(嵐で新規客がゼロになる)、`AR.ui.hud_weather`(上部に天候を表示する)。
- 横断条件(P07): 原本条件とUI操作が一致、Runtimeの実利用・会計・行動へ接続、途中保存・再起動で再現、異常/境界/中断を検証、関連回帰PASS、要件別ログとソースハッシュを保存、既存代表負荷の性能回帰を計測。
## 2. 決定(捏造しない)
- **A13(ユーザーの決定。回答の時刻は記録に無く、Root の記録は 2026-10-23T18:07:36Z)**: 天候の初期仕様。問い(原文は `PROVENANCE.json`)の3項目に、ユーザーが「この初期仕様で進める」と答えた。
1. 毎朝 6 時に、晴れ 60%・雨 25%・マナ霧 10%・嵐 5% で抽選する。雨は 6 時間、霧は 4 時間、嵐は 2 時間続き、その後は晴れ。開始は 6〜20 時の 30 分刻み。
2. 雨の間は新規来客を半分にする。帰宅予定の客は、雨が止むまで滞在を延長する(最大 4 時間)。
3. マナ霧の「魔法効率上昇」は、世界樹とマナ炉の産出を 1.2 倍にする。「興奮度上昇」は、成人確認済みの客の性欲の増加を 1.5 倍にする。
- 出典の区分: 人が承認したのは、上の問いの3項目と、問いが詳細として示した実装案 `p07-01-registration-proposal-r01/PROPOSAL.md`(SHA-256 `0772743a…a532`)。実装案にある「切り捨て」と、下の §4 の抽選の手順・保存・移行・同時の扱いの詳細は、実装担当(Opus)の仕様の選択で、人の新しい承認として扱わない。
- 既存の決定のまま: 嵐の新規入館 0(原本の明示。今の実装を保つ)。A06(マナの貯蔵の上限 300 と 10 分の境界)は変えない。
- この単位で作らないもの: P07-02 の環境(採光・遮音・隠蔽・景観・清潔・騒音)、P07-03 の流行ニュース、天候の魔法以外への効果、D04 の他の値。
## 3. 今の実装(main `48d3b00`)
- `scripts/environment/weather_timeline.gd`: 種類 `clear`・`rain`・`storm`・`mana_fog`、予定の切り替え(`schedule`、`MAX_PENDING` 4096)、時刻の前進、保存と復元(VERSION 1)。確率と効果は持たない。
- `autoload/simulation_runtime.gd`: 時刻の境界の最初(`simulation_runtime.0_weather` → `_advance_weather`)で天候を進める。来客の計画の受付(`_operations_arrival_boundary`)は、嵐の間 `capacity_remaining` を 0 にする。新しい客の帰りの予定は一律 `planned_exit_at = 今 + 720`(3109 行と `guest_service.gd` 131 行)、帰りの判定は 9038 行。保存される乱数の系列は `RNG_STREAM_IDS`(78 行〜。`world`・`guest_spawn` など9本)で、旧 save に `defense` の系列が無い時は `world_seed` から作る前例がある(1322〜1324 行)。`get_weather_report` は今の種類と分だけを返す。
- `scripts/mana/mana_reserve_cycle.gd`: 10 分ごとの境界で、世界樹の産出 `WORLD_TREE_GENERATION` 20、マナ炉の産出 `FURNACE_YIELD` 100、上限 300(A06)。
- `scripts/guest/guest_service.gd` 330〜367 行: 性欲(`intimacy`)の増減の計算。成人確認は `guest_definition.gd` の `adult_verified`。
- `scenes/main/main.gd`: 上部の天候の表示(晴れ・雨・嵐・マナの霧)。予報は無い。
- ゲームの中で天候を予定する経路(自然天候)は無く、試験だけが `schedule` を呼ぶ。雨・霧の効果は無い。
## 4. 挙動
- 4.1 自然天候(A13-1):
- 毎日 06:00 の時刻の境界で1回だけ抽選する。新しいゲームでは、開始の日の 06:00 にも抽選する。
- 保存される乱数の系列 `weather` を `RNG_STREAM_IDS` に足して使う。
- 種類: 0〜99 の整数を1つ引き、0〜59 晴れ、60〜84 雨、85〜94 マナの霧、95〜99 嵐。
- 晴れ以外では、開始の時刻を 06:00〜20:00 の 30 分刻みの 29 個から1つ引く。開始の時刻に切り替え、続く時間(雨 360 分・霧 240 分・嵐 120 分)の後に晴れへ切り替える。予定は `weather_timeline.schedule` で行い、保存される。
- 最も遅い終わり(20:00 開始の雨で翌 02:00)は、次の 06:00 の抽選より前なので、日をまたいで予定が重ならない。開始が 06:00 の時は、同じ境界で切り替える。
- 抽選の結果(日、種類、開始、終わり)を出来事 `WEATHER_FORECAST_DRAWN` として記録する。
- 4.2 雨の来客(A13-2): 雨の間の来客の計画の境界では、計画の新規の人数を半分(切り捨て)にする。嵐の 0 と、マナや定員の今の上限は先に効く。晴れと霧では変えない。
- 4.3 雨の滞在(A13-2):
- 雨の間に帰りの時刻(`planned_exit_at`)になった客は、帰りを、その雨の終わりの時刻か、元の帰りの予定 + 240 分の早い方まで延ばす。
- 延長は客ごとに1回だけで、元の予定と延長の後の予定を保存する。延長の後の時刻には、天候に関わらず今の規則で帰る。
- 嵐と霧では延ばさない。
- 4.4 マナの霧(A13-3):
- 魔法効率: 霧の間のマナの 10 分の境界では、世界樹の産出を floor(20 × 1.2) = 24、マナ炉の産出を floor(100 × 1.2) = 120 にする。炉の受け入れの判定(空きが産出以上)も、その境界の産出の量で行う。上限 300 は変えない。
- 興奮度: 霧の間、`adult_verified` の客の性欲の増加(その計算の正の増分)を floor(増分 × 1.5) にする。減少と、成人確認の無い客は変えない。
- 霧の外では元に戻る。
- 4.5 嵐(原本): 今の新規入館 0 を保つ。自然天候の嵐でも同じ。
- 4.6 上部の表示と予報(`AR.ui.hud_weather`):
- 今の天候に加えて、その日の次の切り替え(種類と時刻)を出す(`get_weather_report` に足す)。
- 雨・嵐・霧の時は効果を短く案内する(雨: 来客が半分・帰りを最大 4 時間延ばす、嵐: 新規来客なし、霧: マナの産出と成人客の性欲が増える)。
- UI は今の部品のままにし、完成の見た目は求めない。
- 4.7 同時の扱い(D05 の範囲の実装の契約):
- 天候は今どおり時刻の境界の最初に進めるので、同じ分の来客の計画・帰りの判定・マナの境界・締めより先に効く。
- 予定の重複・過去の時刻・上限を超えた予定は、今の `weather_timeline` の規則で拒む。
## 5. 保存と移行
- 5.1 自然天候の状態(最後に抽選した日と、その日の予定)、系列 `weather`、客の延長の記録を保存する。同じ process の保存の往復と別の process の再開で同じ状態になり、抽選・延長・霧の効果を二重に行わない。
- 5.2 旧 save(自然天候の状態と系列 `weather` が無い):
- 今の天候と予定をそのまま保つ。
- 系列 `weather` は `world_seed` から作る(`defense` の系列の既存の移行と同じ形)。
- 読み込みの後の最初の 06:00 から抽選を始める。過去の日の抽選はさかのぼらない。客の延長の記録は無しとして読む。
- 5.3 不正な天候の状態(知らない種類、範囲の外の時刻、重なる予定、延長の上限を超えた記録)は拒否し、読込の前の状態を保つ。
## 6. 受入条件(acceptance_baseline の本文と同じ)
- P07-01-F1 自然天候: 毎日 06:00 に1回だけ、§4.1 の確率・開始の時刻・続く時間で天候が自然に予定され、同じ world_seed と同じ操作で同じ天候の列になる。新しいゲームの開始の日も抽選され、旧 save は §5.2 のとおり移行する。
- P07-01-F2 雨の来客: 雨の間の来客の計画の新規の人数が、同じ条件の晴れの半分(切り捨て)になり、嵐の 0 と定員・マナの上限を壊さない。
- P07-01-F3 雨の滞在: 雨の間に帰りの時刻になった客が、雨の終わりか元の予定 + 240 分の早い方まで1回だけ残り、その後は今の規則で帰る。嵐と霧では延びない。
- P07-01-F4 嵐: 自然の嵐を含め、嵐の間の新規入館が 0。
- P07-01-F5 マナの霧: 霧の間のマナの境界で世界樹 24・マナ炉 120(上限 300 のまま)、成人確認済みの客の性欲の増加が floor(×1.5) になり、霧の外と成人確認の無い客は変わらない。
- P07-01-F6 表示と予報: ゲームの本物の Runtime と Main の上部の表示で、今の天候・次の切り替え(種類と時刻)・効果の案内が Runtime の値と一致する。
- P07-01-F7 保存と再開: 天候の切り替えの直前・直後・途中の保存を、同じ process と別の process で読み、天候・予定・系列・来客・滞在の延長・霧の効果が同じになり、二重に効かない。旧 save は §5.2 で読め、不正な状態は §5.3 で拒否して状態を保つ。
- P07-01-F8 回帰: 関連の回帰(狭い roster と再開の2段)と最終の S の全 roster(既存の代表負荷の性能の suite を含む)が PASS。既存の試験の期待値の変更は `EXPECTATION_CHANGES.json` に変更前後と根拠を一覧にする。元の失敗を保存し、未解決の試験を除いて PASS にしない。
## 7. 開示
- 実装案の「切り捨て」と §4・§5 の詳細は、実装担当の選択(§2)。
- 興奮度は性欲(`intimacy`)の増加に当てた。今の客の種類の多くは性欲の増加が 0 なので、霧の効果は増加が正の成人確認済みの客にだけ表れる。
- 予報はその日の予定だけを出し、翌日以降は出さない(翌日の抽選は翌朝 06:00)。UI は今の部品のまま。Windows の実機は後。
- 性能の調整はしない(横断条件の性能回帰の計測は、全 roster の既存の性能の suite の結果で見る)。
## 8. 検証
- validation `p07-weather`: `tools/run_p07_weather_tests.py --output {build_dir}/p07-weather-evidence`。P05-02 の `tools/run_p05_funds_tests.py` と同じ guarded の段の手順を、この作業の中で作る。
- 狭い roster:
- 新しい suite `tests/environment/test_p07_weather_runtime.gd`(F1〜F7)。
- 既存の `tests/environment/test_runtime_weather.gd`・`test_weather_timeline.gd`・`test_weather_recovery.gd`・`tests/mvp/test_runtime_operations_integration.gd`・`tests/s2/test_runtime_operations_cycle.gd`・`tests/s2/test_runtime_mana_reserve.gd`・`tests/s2/test_mana_reserve_cycle.gd`・`tests/s3/test_guest_service.gd`・`tests/s6/test_runtime_save_lifecycle.gd`・`tests/s6/test_runtime_snapshot_serialization.gd`・`tests/ui/test_main_dashboard.gd`。
- 再開の2段: `tests/environment/test_p07_weather_restart_1_write.gd`(天候の途中で保存。生成ファイルは handoff だけ)と `..._2_read.gd`(別の process で読む)。
- その後: 正式の validation → 最終の S の全 roster を1回 → fresh な独立レビュー(whole-unit)。速度の調整の作業と、微小な変更ごとの全回帰はしない。
@@ -0,0 +1,36 @@
{
"by": "Claude Opus 5.5 Desktop (local_a7f85421-3eed-4482-8030-c0dca669573a), the commander that wrote the proposal; the question was asked by Root (Codex)",
"decision_record": {
"path": "artifacts/original-completion-2026-10-02/USER_DECISIONS_WEATHER_SEVERANCE_R01.json",
"sha256": "c4a08ad4369ceec1738543540611a8c8921bd263d9fbe6b3e2621698f2957390"
},
"human_decision": {
"id": "A14",
"questionItemId": "[\"request_user_input_async\",\"call_6696d05036264581b24f6416e62e673a\",0]",
"question_verbatim": "原本には「解雇(退職金)」とありますが、金額と支払方法が未指定です。一般従業員の解雇は、次の初期仕様で進めてよいですか。\n\n・退職金は、その職員の日給の3日分。\n・表金から払い、不足分を裏金で補う。合計でも足りなければ解雇しない。\n・未払い給与は退職金と分けて保持し、次の午前0時に精算する。\n・退職金は帳簿で区別し、日次決算では運営費に計上する。\n\n数値と支払方法は実装担当の提案で、まだ確定していません。[具体案](/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p16-01-dismiss-registration-r02/SEVERANCE_DECISION_PROPOSAL.md)",
"answer_verbatim": "この初期仕様で進める",
"source": "Actual user send_user_message_question_reply in this Codex conversation; recorded time is not the original answer time.",
"recorded_at_utc": "2026-10-23T18:07:36Z",
"proposal": {
"path": "artifacts/original-completion-2026-10-02/p16-01-dismiss-registration-r02/SEVERANCE_DECISION_PROPOSAL.md",
"sha256": "02039fa25c50b43732dfa34e17eb7ba72de8eafaba0e19a151f9d08960de3842"
}
},
"root_boundary_not_human": {
"id": "R9 DEFENSE_LOCKED",
"record": "artifacts/original-completion-2026-10-02/p16-01-dismiss-registration-r03/ROOT_DECISION_R9_AND_COMMAND_BOUNDARY_R01.md",
"sha256": "58918a1a652673d3e7fb589414a34faaa45bde3a80b841319ee4a69590b97e31"
},
"interpretation_boundary": [
"Human-approved: the four items of the question and the linked proposal as presented.",
"Implementer choices (not a new human approval): integer wage x3, the single transaction with the top-up, the STAFF_SEVERANCE category and its account, the empty-account addition for old saves, once-per-command recording (SPEC 3.6).",
"Not approved: any combat or raid dismissal rule, acceptance waivers, P05-03 answers (pending)."
],
"limits": [
"These answers supersede the stale heartbeat statements that weather and severance are awaiting user answers.",
"P05-03 questions remain unanswered.",
"No approval of additional combat dismissal rules, acceptance waivers, deletion of models/runtime/personal data, or exact future integration candidates is asserted.",
"This record is a decision record, not evidence of implementation or acceptance. Original completion remains 24/88 and 4/30 packages."
],
"original_completed": 24
}
@@ -0,0 +1,117 @@
# P16-01-DISMISS 一般従業員の通常操作での解雇(退職金を含む) 仕様(登録版 r04。P16-01 の補助の作業)
- 状態: 登録の前の仕様(実 Opus の commander、2026-10-24)。§3.5 の退職金はユーザーの決定(A14、Root の記録 2026-10-23T18:07:36Z)で決まり、凍結できる。§6.3 R9 は Root が既存の範囲の権限で採った、この補助の作業の一時の境界(2026-10-23、`../p16-01-dismiss-registration-r03/ROOT_DECISION_R9_AND_COMMAND_BOUNDARY_R01.md`)で、人の承認ではない。Root が main に `docs/plans/original-completion-2026-10-02/execution/p16-01-dismiss/SPEC.md` として固定し、その commit(P07-01 の統合の後の main の上)を `base_commit` に通常の登録をする。製品は登録まで変えない。出典は同じフォルダの `PROVENANCE.json`。
- 履歴: r01・r02(誤りを含む)と r03(退職金の決定の前の版)は書き換えずに残す。r03 からの違いは `CHANGES_FROM_R03.md`。
- 原本への加算: 0。原単位 P16-01・P16-03、原子要件 `AR.staff.dismissal_severance` の package P05 の原 work・原 AC は、この作業では閉じない(§8)。
## 1. 原本の条件(原文。変えない)
- `docs/traceability/original/BASELINE.txt`:
- 98 行 `* **一般従業員:** ギルド雇用。日給発生。ストレスが溜まりやすく解雇自由。`
- 99 行 `* **奴隷:** 市場購入や借金客拘束で獲得。食費のみ。ストレス耐性が高く「人身売買」で売却可能。`
- 113 行 `* **処分:** 解雇(退職金)、人身売買(ステータスにより価格変動。他の従業員の忠誠度低下リスクあり)。`
- 116 行 `* **特性:** 代替不可能、雇用コスト・維持費無料、成長上限が高い、解雇・売却不可。固有スキルを所持。`(ユニークの節)
- 原子要件: `AR.staff.general_dismissal`(P16)「一般従業員を通常操作で解雇できる。」、`AR.staff.dismissal_severance`(P05、D04 待ち)「解雇で退職金を支払う。」、`AR.unique.no_dismissal`(P17)「ユニーク人物を解雇できない。」
- 原単位の文: P16-01 の AC「求人から配置・精算・退職まで通常操作でき、ユニーク禁止操作を維持する。」。P16-03 の work「勤務、休息、給与、気絶、救護、退職時参照除去を横断検証する。」
- ユーザーの言葉(原文): 「まずゲームとしての機能実装完了を優先して」(2026-10-23、P05-02 の `PROVENANCE.json` と同じ出典)。「開発作業を進めて。またがわわは後で変えるので、、統合試験の動作速度のチューニングを、今やるよりも機能実装の完了を優先して」(2026-10-23、Root が共有した原文)。以下の要約は要約と記す。
- 要件 ID: `P16-01-DISMISS`、`AR.staff.general_dismissal`、`AR.staff.dismissal_severance`、`AR.unique.no_dismissal`。
## 2. 解雇できる職員の区分(今の製品の区分)
- 一般従業員 = `StaffRuntime.EmploymentKind.FREE_HIRE` の職員。根拠: ギルドの候補の雇用(`hire_staff_candidate`)は、`scripts/data/mvp_content_catalog.gd` 329 行で `heroine_anri` を `UNIQUE`、それ以外の全ての候補を `FREE_HIRE` にする。`FREE_HIRE` は日給を持つ(`StaffRuntime.get_effective_daily_wage`、`UNIQUE` だけ 0)。原本 98 行の「ギルド雇用。日給発生。」に当たる。
- 解雇の命令の対象にしない区分(この作業の外。他の処分の流れには触れない):
- `UNIQUE`: 原本 116 行と `AR.unique.no_dismissal`。今の `StaffService.remove_staff` も拒む。
- `ADULT_CONTRACT`: `scripts/staff/staff_runtime.gd` 31 行に定義があるが、今のゲームにこの区分を作る経路は無く、原本 98 行の一般従業員と同じとは確かめられない。命令は拒む(理由 `NOT_GENERAL_EMPLOYEE`)。これは対象の区分の範囲で、新しいゲームの規則ではない。
- 奴隷(原本 99 行)と人身売買(113 行): 今のゲームに区分も流れも無く、この作業で作らない。
## 3. 退職金(原本の要件と A14 の決定)
- 3.1 原本 113 行「解雇(退職金)」と `AR.staff.dismissal_severance` により、通常の解雇は退職金の支払と切り離せない。
- 3.2 原本に額・式・払う元は無い(D04)。A09 の元の質問の対象(維持費・仕入れ・人件費・返済・利息・税)に退職金は入っていない。
- 3.3 退職金 0 を前提にしない(A14 で額が決まった)。
- 3.4 既存の規則(変えない): 解雇の前に貯まった未払いの給与は、退職金とは別に `_departed_payroll` に保持し、次の 00:00 の締めで払う(A09 の順)。
- 3.5 **A14(ユーザーの決定。回答の時刻は記録に無く、Root の記録は 2026-10-23T18:07:36Z)**: 問い(原文は `PROVENANCE.json`)の4項目に、ユーザーが「この初期仕様で進める」と答えた。
- 退職金は、その職員の日給の3日分。
- 表金から払い、不足分を裏金で補う。合計でも足りなければ解雇しない。
- 未払い給与は退職金と分けて保持し、次の午前0時に精算する。
- 退職金は帳簿で区別し、日次決算では運営費に計上する。
- 3.6 実装の詳細(問いが示した案 `../p16-01-dismiss-registration-r02/SEVERANCE_DECISION_PROPOSAL.md` §3、SHA-256 `02039fa2…3842` のとおり。案の詳細は実装担当の選択で、人の新しい承認として扱わない):
- 額 = `StaffRuntime.get_effective_daily_wage` × 3(整数)。日給 0 の職員は 0。
- 支払は解雇の命令の時に行う。表金で足りない分を裏金から表金へ補填し(`BACK_FUND_TOP_UP`、P05-02 と同じ)、補填と退職金を1つの取引で記帳する。
- 表金と裏金の合計が足りなければ R8 で拒み、§5.c の比べ方で状態を変えない(滞納にしない)。
- 帳簿の新しい区分 `STAFF_SEVERANCE`: 表金から、給与(`WAGE`)の照合と混ざらない退職金の費用の口座へ記帳する。日次決算の照合では `cost_of_goods`(画面「運営費(仕入れ・契約金等)」。雇用の契約金 `STAFF_SIGNING_COST` と同じ)に入れる。
- 旧セーブに退職金の費用の口座が無ければ、空の口座として足す(残高・既存の口座・取引の履歴は変えない。P05-02 の A12 の口座の追加と同じ形)。
- 命令ごとに1回だけ記帳し、再送と保存再開で二度払わない。
## 4. 挙動
- 4.1 命令: `SimulationRuntime` に通常の command `dismiss_staff`(payload `staff_id`)を足す。判定の順: (a) 運営の終了なら受付の前に拒む(今の `submit_command` の規則)。(b) 同じ idempotency key なら受付で拒む(今の `CommandQueue.enqueue` の規則)。(c) executor で、職員が存在するか、区分が `FREE_HIRE` か、§6 の拒否の行に当たらないか、§3.5 の退職金を払えるかを、状態を変える前に全て確かめる。(d) 全て通れば、退職金の支払(§3.5)、`StaffService.remove_staff(staff_id, &"DISMISSED", true, 分)`、§6.2 の後始末を1つの操作として行い、途中で失敗すれば前の状態に戻す。
- 4.2 成功の結果: `staff_id`、払った退職金(§3.5)、保持した未払いの給与、消した勤務の ID、開き直した作業の ID。`STAFF_REMOVED`(reason `DISMISSED`)の出来事。
- 4.3 通常の画面: 職員の管理の画面(`StaffManagementPanel`)で、選んだ職員が §6 の許可の行に当たる時だけ「解雇」の操作を出し、通常の入力(Main の画面の操作)で 4.1 の命令を送る。拒否の行に当たる時は操作を出さないか無効にし、理由(`UNIQUE` は今の「ユニーク:雇用・維持費無料 / 解雇・売却不可」、それ以外は §6 の理由)を出す。退職金の額(§3.5)と、作業を持つ職員なら開き直る作業を、押す前に出す。結果(成功、拒否の理由、払った退職金、保持した未払い)を出し、名簿と選択を更新する。UI は今の部品のままで、完成の見た目は求めない。
## 5. 拒否の時に変わってよいもの(原子性の比べ方)
- 5.a 画面で操作を出さない・無効の時、画面の中の判定で送らない時: 命令を送らないので、Runtime の snapshot(`create_snapshot`)の全体が bytes で同じ。
- 5.b 運営の終了の後(4.1 a)、同じ key の再送(4.1 b): 受付の前・受付で止まり command の ID を使わないので、snapshot の全体が bytes で同じ。同じ key の再送の結果は `DUPLICATE_IDEMPOTENCY_KEY` で、details に最初の結果がつく。
- 5.c executor の拒否(4.1 c): 命令は受け付けて処理されるので、次の4つの区画だけが、決まった形で変わってよい。`systems.runtime.next_command_id`(ちょうど 1 増える)、`systems.runtime.command_queue`(その command の処理済みの失敗の結果・受付の記録、key を付けた時はその key と command の ID の対応だけが増える)、`systems.runtime.id_generator`(出来事の番号が 1 進む)、`systems.runtime.domain_events`(その command の ID の `COMMAND_FAILED` の出来事がちょうど1つ増え、他の出来事は変わらない)。他の全ての区画(`staff`・`economy`・`facilities`・`path`・`elevators`・`guests`・`operations`・`defense`・`events` など)は bytes で同じ。
- 5.d 試験は、5.c の4つの区画から上の決まった増分だけを取り除いた写しの全体を bytes で比べ、増分そのもの(command の ID、失敗の結果の理由、出来事の種類)も確かめる。局所の確認で他の区画が変わると分かったら、それは直す不具合で、比べる範囲を後から広げない。
## 6. 許可と拒否の表(実際の削除と所有の契約から)
- 6.0 使う契約: 解雇は既存の削除の契約 `StaffService.remove_staff`(main `48d3b00` でも 888〜935 行。`staff_service.gd` は P05-02 で変わっていない)に従う。この契約は、`UNIQUE`(897 行)、外部が持つ作業(`is_externally_driven_task`、899 行)、作業の予約を解けない時(905 行)だけを拒み、取り消せる今の作業は予約を解いて開き直す(902〜909 行)。配置の変更の規則 `_staff_assignment_block_reason`(Runtime 6964〜6973 行)は配置の変更のための規則なので、解雇には使わない。作業の有無や状態だけで一律に解雇を止めない。
- 6.1 許可(`FREE_HIRE`、§3.5 の支払ができる時。どの行も §6.2 の後始末を確かめる):
- A1 非番(作業なし)。
- A2 通勤中(昇降機を待つ・乗っている時を含む)。`_on_staff_removed` が昇降機の予約を取り消し、経路の actor を消す。
- A3 勤務中で手が空いている(施設に配置)。
- A4 施設でサービスの途中(`ServiceInstance.staff_ids` に入っている)。施設の人員の投影から外れ、人数が `staff_min` を欠けると、今の施設の規則でサービスが職員を待ち(`STAFF_REPLACEMENT_GRACE_MINUTES` 5 分)、代わりが来なければ失敗になる(`scripts/facility/facility_service.gd` 21 行と 875〜891 行)。
- A5 取り消せる作業を持つ(清掃など。予約つきを含む)。`remove_staff` が予約を解き、作業を開き直す(進み具合は作業の方針のまま)。清掃の派遣は生きた職員と作業から毎回導く判定(`scripts/environment/facility_cleaning_bridge.gd` 12〜15 行)で、保存された参照は残らない。
- A6 救護の運搬者(`rescue_pickup`・`rescue_transport`。外部が持つ作業ではない)。作業は開き直り、次の時刻の救護の確認(`_advance_staff_rescue`、Runtime 13475〜13494 行)が、運搬者の居ない運搬を `RESCUE_INTERRUPTED` で取り消し(13492 行。運搬者が居ないので 13490 行の「乗っている間は保つ」は当たらず、患者の昇降機の予約も取り消す、13493 行)、倒れた職員の救護を今の規則でやり直す。次の時刻の確認だけに頼らず、命令の境目でも整合を保つ(§6.2.1)。
- A7 倒れている(INCAPACITATED。救護の対象)。`remove_staff` は状態を見ない。次の時刻の救護の確認が、患者の居ない救護の作業を取り消し、運搬者の昇降機の予約も取り消す。運搬の完了は患者が居なければ何もしない(Runtime 12460〜12467 行)。命令の境目の整合は §6.2.1。救護の確認は、運搬者が昇降機に乗っている時だけ着くまで保つ(13490〜13491 行)。
- A8 出来事の拘束中(`event_service` の `_actor_locks`)。出来事の側の既存の契約 `_handle_missing_actors`(`scripts/events/event_service.gd` 1056 行〜。`missing_actor_policy` の続ける・役で置き換える・失敗の分岐が 1069〜1098 行)が、次の評価で欠けた職員を扱い、拘束を外す。欠けの判定は `_missing_actor_ids`(1226 行)と `_actor_is_available`(1234〜1235 行)。命令の境目の整合は §6.2.1。
- A9 同じ職員を対象にした別の命令が待ち行列にある時。その命令は解雇の後に `NOT_FOUND` などで拒まれ、何も変えない。
- A10 未払いの給与がある時(§3.4 で保持)。
- 6.2 後始末(許可の全ての行。決めた範囲のファイルの中で行う): 勤務・予定・配置(`remove_staff`)、経路の actor と昇降機の予約(`_on_staff_removed`)、施設の人員の投影(解雇の命令の中で `_sync_facility_staffing`(Runtime 9565 行)をすぐ行い、保存の時の施設の人員の照合(1241〜1255 行)と食い違わない)、画面の選択(`StaffManagementPanel`)、`audit_orphan_tasks` で孤立 0、`STAFF_REMOVED`(reason `DISMISSED`)が1つ。関係の系(P18)はユニークだけを参照し(Runtime 7051〜7067 行)、一般従業員の参照は無い。局所の確認で他の参照が残ると分かったら、それを §6.2 の後始末として決めた範囲の中で直し、拒否に変えない。
- 6.2.1 命令の境目の整合(A6・A7・A8。Root 2026-10-23、`ROOT_DECISION_R9_AND_COMMAND_BOUNDARY_R01.md`): 次の時刻の後始末(`_advance_staff_rescue`、出来事の評価)だけに頼らない。解雇の命令の中で(同じ時刻、次の進行の前に)、欠けた職員を患者か運搬者に持つ救護の作業を今の規則(`RESCUE_INTERRUPTED` の取り消しと昇降機の予約の取り消し)で片づけ、出来事は公開の `event_service.audit_actor_availability`(`scripts/events/event_service.gd` 556〜571 行。Runtime の進行も 8909 行で使う)で欠けた職員を今の `missing_actor_policy` で扱う。命令の直後に保存し、同じ process と別の process で読み込んでも、欠けた職員への参照(救護の作業の患者と運搬者、昇降機の予約、出来事の actor と拘束)が残らず、保存の照合が通る。運搬者と患者が一緒に昇降機に乗っている時は、着くまで保つ今の規則(13490〜13491 行)と命令の直後の保存の照合の両方が成り立つ形を、決めた範囲(Runtime と `StaffService`)の中で実装で決めて記録する。退却や戦闘のような新しい規則は作らず、許可の行を全面の拒否に置き換えない。
- 6.3 拒否(業務の状態を変えない。5.b か 5.c の比べ方):
- 既存の規則による拒否:
- R1 `UNIQUE`(アンリなど)→ 今の `remove_staff` の拒否の文(`Unique Staff cannot be dismissed, sold or permanently removed.`)。5.c。
- R2 外部が持つ作業(仕入れの物流の受け取り・配達・返送。`supply_logistics_bridge.owns_task`)→ 今の `remove_staff` の拒否の文(`Finish the employee external operation before removal.`)。取り消すと物流の要求と荷物が孤立するので、外部の操作の終わりを待つ。5.c。
- R3 作業の予約を解けない → 今の `remove_staff` の拒否の文(`Staff removal could not release Task Reservations.`)。5.c。
- R4 存在しない職員 → `NOT_FOUND`。5.c。
- R5 運営の終了の後 → 今の `submit_command` の拒否(reason `BANKRUPT`)。5.b。
- R6 同じ key の再送 → `DUPLICATE_IDEMPOTENCY_KEY`。5.b。
- 対象の区分の範囲による拒否: R7 `ADULT_CONTRACT` → `NOT_GENERAL_EMPLOYEE`(§2)。5.c。
- §3.5 の決定による拒否: R8 表金と裏金の合計が退職金に足りない時 → `INSUFFICIENT_FUNDS`(A14「合計でも足りなければ解雇しない」)。5.c。
- **Root が採った一時の境界(既存の解雇の契約に無い。根拠つき)**: R9 進行中(終わっていない)の襲撃の防衛者(`_defense_lock_owner(staff_id, &"DEFENDER")` が空でない)→ `DEFENSE_LOCKED`。5.c。
- 根拠: 終わっていない襲撃の防衛側の職員について、Runtime の防衛の照合は、職員が存在し、状態が `UNAVAILABLE` で、作業を持たないことを求める(`simulation_runtime.gd` 10919〜10924 行。準備中は体力・疲労の一致も 10925〜10929 行。終わった襲撃は履歴なので照合しない、10915〜10920 行)。襲撃の結果の当てはめも `staff_service.has_staff` を求める(10194〜10195 行)。そのため、進行中の襲撃の防衛者を消すと、保存の照合と襲撃の結果の当てはめが失敗する。
- 後始末で避けられない理由: 襲撃の名簿から防衛者を外すには `scripts/defense/**`(決めた範囲の外)を変える必要があり、防衛者が途中で抜けた時の戦闘の扱い(退却、戦力の減り方)は原本にも決定にも無い。
- Root が 2026-10-23 に、既存の範囲の権限で、この補助の作業の一時の境界として採った(`ROOT_DECISION_R9_AND_COMMAND_BOUNDARY_R01.md`)。人への追加の問いは要らない。進行中の襲撃の防衛者の解雇は原本の要件として未達のまま開示し(§8)、退却や戦闘の規則を作らず、自由な解雇の完了として扱わない。
## 7. 受入条件(acceptance_baseline の本文と同じ)
- P16-01-DISMISS-F1 通常の命令: §6.1 の許可の行の `FREE_HIRE` の職員を §4.1 の command で解雇でき、名簿から消え、`STAFF_REMOVED`(reason `DISMISSED`)が1つ記録される。
- P16-01-DISMISS-F2 区分の拒否: `UNIQUE` と `ADULT_CONTRACT` は命令でも画面でも解雇できず、§5 の比べ方で業務の状態が変わらない。
- P16-01-DISMISS-F3 退職金: §3.5 で決めた額と払う元で、解雇ごとに1回だけ払われ、日次決算と帳簿の照合が一致する。§3.5 で決めた支払ができない時は解雇されず、§5.c の比べ方で業務の状態が変わらない。
- P16-01-DISMISS-F4 未払いの給与: 解雇の前の未払いが退職金とは別に保持され、次の 00:00 の締めで1回だけ払われ(A09 の補填を含む)、解雇の後に日給が生じない。
- P16-01-DISMISS-F5 再送: 同じ key の再送が `DUPLICATE_IDEMPOTENCY_KEY` で、details に最初の結果がつき、§5.b の比べ方で snapshot の全体が同じ。退職金を二度払わない。
- P16-01-DISMISS-F6 拒否の境界: §6.3 の拒否の全ての行(R1〜R9)で拒み、§5 の該当の比べ方で業務の状態が変わらない。
- P16-01-DISMISS-F7 許可の境界と後始末: §6.1 の許可の全ての行(A1〜A10)で解雇でき、§6.2 の後始末が全て成り立つ。開き直した作業、サービスの待ちと失敗、救護のやり直し、出来事の欠けた職員の扱いは、それぞれ既存の規則どおりになる。A6・A7・A8 は §6.2.1 のとおり、命令の直後に保存して同じ process と別の process で読み込んでも参照が残らず、保存の照合が通る。
- P16-01-DISMISS-F8 保存と再開: 解雇の前後(命令の直後、次の進行の前を含む)・締めの前後の保存を同じ process と別の process で読み、同じ状態で、退職金と未払いの給与の支払が二重にならない。
- P16-01-DISMISS-F9 通常の画面: ゲームの本物の Runtime と Main の職員の管理の画面で、通常の入力で許可の行の一般従業員を解雇でき(退職金の額と開き直る作業を押す前に見られる)、拒否の行では操作が出ないか無効で理由が出る。fixture の直接の呼び出し(`staff_service.remove_staff`)だけで通常の入口の完了を主張しない。
- P16-01-DISMISS-F10 回帰: 関連の回帰(狭い roster と再開の2段)と最終の S の全 roster が PASS。既存の試験の期待値の変更は `EXPECTATION_CHANGES.json` に変更前後と根拠を一覧にする。
## 8. 原単位との差(開示)
- P16-01 の残り: 求人募集の通常の操作(`AR.staff.recruitment`)、奴隷市場・破産客からの獲得(`AR.staff.market_acquisition`・`debt_acquisition`、D04)、雇用の区分ごとの費用の整理。P16-03 の残り: 勤務・休息・気絶・救護の横断(D04)、解雇の経路の外の退職時の参照の除去。人身売買(`AR.staff.sale_*`、D04)。どれも未達のまま。`AR.staff.dismissal_severance` は §3.5 の決定とこの作業の受入で接続するが、package P05 の原単位の完了には数えない。§6.3 R9 により、進行中の襲撃の防衛者の解雇は原本の要件として未達のまま開示する(自由な解雇の完了ではない)。
## 9. 検証
- validation `p16-dismiss`(`tools/run_p16_dismiss_tests.py --output {build_dir}/p16-dismiss-evidence`。P05-02 の `tools/run_p05_funds_tests.py` と同じ guarded の段の手順を、この作業の中で作る)。
- 狭い roster: 新しい suite `tests/staff/test_general_dismissal.gd`(F1〜F9。§6 の全ての行。退職金の額・補填・不足の拒否・決算の区分を含む)、既存の `tests/ui/test_staff_management.gd`・`tests/ui/test_selection_departure.gd`・`tests/s3/test_runtime_staff_assignment.gd`・`tests/s3/test_staff_service.gd`・`tests/ui/test_anri_recruitment.gd`・`tests/ui/test_approved_free_unique_arrears_ui.gd`・`tests/s6/test_runtime_save_lifecycle.gd`・`tests/s6/test_runtime_snapshot_serialization.gd`・`tests/mvp/test_runtime_operations_integration.gd`。再開の2段 `tests/staff/test_general_dismissal_restart_1_write.gd`(解雇の後・締めの前に保存。唯一の生成ファイルは handoff)と `..._2_read.gd`(別の process で読み、締めまで進めて1回だけの支払を確かめる)。実 12 段。
- その後: 正式の validation → 最終の S の全 roster を1回 → fresh な独立レビュー(この補助の作業の範囲。原単位の whole-unit の受入ではない)。速度の調整の作業と、微小な変更ごとの全回帰はしない。
## 10. 開示
- UI は今の部品のまま(完成の見た目ではない)。Windows 実機は後。解雇の日の日給は今の給与の契約(締めの時に雇用中の職員に日給)のまま新しい規則を作らない。解雇した候補の再雇用は今の `hire_staff_candidate` の規則(同じ候補を二度雇えない)を変えない。解雇した職員が歩いて出る描写は作らない(非描写の状態として命令の時点で取り除く)。
- 行番号は main `48d3b00` のもの(P05-02 で `simulation_runtime.gd` の行が動いたので r03 から直した)。登録の時の main で読み直す。
@@ -84,7 +84,7 @@
"passed": true "passed": true
}, },
{ {
"name": "all12_confirmed_decisions", "name": "all14_confirmed_decisions",
"passed": true "passed": true
}, },
{ {
@@ -238,7 +238,7 @@
"build_atomic_requirements.py": "6d6ea9e4216372dbd0f9fed3f885a4481b21a3f539a26f64cf98a6830af984c5", "build_atomic_requirements.py": "6d6ea9e4216372dbd0f9fed3f885a4481b21a3f539a26f64cf98a6830af984c5",
"build_facility_value_contracts.py": "35027b23ce75ce9e4e0cdfc5132fd2eb771ba9f598d97750d7ecf9ecb257f769", "build_facility_value_contracts.py": "35027b23ce75ce9e4e0cdfc5132fd2eb771ba9f598d97750d7ecf9ecb257f769",
"current_evidence_links.json": "db1837bcc8497201134297e312f4b266a297102285307ec3075d4e23632e26c2", "current_evidence_links.json": "db1837bcc8497201134297e312f4b266a297102285307ec3075d4e23632e26c2",
"decisions.json": "6566a460e310d8fd51c807c31d1e26f442ecb68f39a92db9ae4011fe3910e706", "decisions.json": "f1ccd5909eac20431d578d92e51bef7f018345a2b1ce044c671ef92de0a693a5",
"facility_value_contracts.json": "447388ba03a29bfac25f2bcd068665aedbb07ba7641ce86f2db93d44f4c9f326", "facility_value_contracts.json": "447388ba03a29bfac25f2bcd068665aedbb07ba7641ce86f2db93d44f4c9f326",
"facility_value_contracts_validation.json": "bf490a9ca585c48fc318e76c4a069ef244827d828d46e6415399f7710590dd16", "facility_value_contracts_validation.json": "bf490a9ca585c48fc318e76c4a069ef244827d828d46e6415399f7710590dd16",
"performance_audit.json": "0b630b15a392c3e0366f1362bfe4ddacb968f915f54549f82e4d6fa315384762", "performance_audit.json": "0b630b15a392c3e0366f1362bfe4ddacb968f915f54549f82e4d6fa315384762",
@@ -251,7 +251,7 @@
"source_atomic_coverage.json": "2ab7b9e6a2536ef248d4f7ccd695bf75a082b47018aca7a5a1b6b706fe1907bc", "source_atomic_coverage.json": "2ab7b9e6a2536ef248d4f7ccd695bf75a082b47018aca7a5a1b6b706fe1907bc",
"validate_atomic_requirements.py": "5b2d0b7d72cb124830fbb0a12d1434e6db698148cc5263d33fd5bd7c2953a1e0", "validate_atomic_requirements.py": "5b2d0b7d72cb124830fbb0a12d1434e6db698148cc5263d33fd5bd7c2953a1e0",
"validate_facility_value_contracts.py": "91640e2a76cd6cc9186f7b85c0bf379b24b6cac0d48962815235ee628e7ae43e", "validate_facility_value_contracts.py": "91640e2a76cd6cc9186f7b85c0bf379b24b6cac0d48962815235ee628e7ae43e",
"validate_plan.py": "dc65987db520df75a9b90037eae82819ba4c8863354340681092703454cdfb31", "validate_plan.py": "2f698fbf38d3b16713835f99aaa391df9ebc30f44547f272644de19efb91f50a",
"validator_update_checks.json": "f997d0f3de2cea29550840b1d5cb23647d64f81329de46758551e2b6c8fecc27", "validator_update_checks.json": "f997d0f3de2cea29550840b1d5cb23647d64f81329de46758551e2b6c8fecc27",
"work_packages.json": "f543f39842764076b4522cc818c476d18bdc8e09ac9d83e02dd84ccadc966496" "work_packages.json": "f543f39842764076b4522cc818c476d18bdc8e09ac9d83e02dd84ccadc966496"
} }
@@ -172,7 +172,7 @@ def main():
pending = {d["id"] for d in decisions["pending"]} pending = {d["id"] for d in decisions["pending"]}
check("all10_pending_decision_groups", pending == {f"D{i:02d}" for i in range(1, 11)}) check("all10_pending_decision_groups", pending == {f"D{i:02d}" for i in range(1, 11)})
check("known_decision_references", all(set(p["decisions"]) <= pending for p in packages)) check("known_decision_references", all(set(p["decisions"]) <= pending for p in packages))
check("all12_confirmed_decisions", {d["id"] for d in decisions["confirmed"]} == {f"A{i:02d}" for i in range(1, 13)}) check("all14_confirmed_decisions", {d["id"] for d in decisions["confirmed"]} == {f"A{i:02d}" for i in range(1, 15)})
check("confirmed_decision_references_exist", all((PLAN / d["reference"]).is_file() for d in decisions["confirmed"] if "reference" in d)) check("confirmed_decision_references_exist", all((PLAN / d["reference"]).is_file() for d in decisions["confirmed"] if "reference" in d))
state_counts = dict(collections.Counter(p["state"] for p in packages)) state_counts = dict(collections.Counter(p["state"] for p in packages))
check("valid_package_states", all(p["state"] in states for p in packages)) check("valid_package_states", all(p["state"] in states for p in packages))