Files
TheTree_mock/docs/plans/original-completion-2026-10-02/execution/p05-02/SPEC.md
T

17 KiB
Raw Blame History

P05-02 全費目と資金区分 仕様(登録版 r01)

  • 状態: RootがOpusの登録候補r02を採用し、登録資料としてmainに固定する。登録・下書き試験は実装受入ではない。原本の加算はwhole-unitのfinalの後だけ。出典は同フォルダのPROVENANCE.json。
  • 前提: P04 は正式完了(b1810ff4)、P05-01 は正式受入済み。ユーザーの発言(2026-10-23)「開発作業止めないで。」「動作速度の試験と軽量化の作業は後ろ回しにして。理由はUIやアセット含めて入れ替える予定なので、現状のモック版を計画目標に置いてないので。」「まずゲームとしての機能実装完了を優先して」により、機能の実装を性能(P28)より先にする(feature-priority-r01/PLAN.md。会話の位置と原文は同じフォルダの PROVENANCE.json)。

1. 原本の条件(変えない)

  • work: 表金・裏金、維持費未払い、仕入れ、人件費、元本、利息、税を帳簿へ接続する。
  • acceptance: 3営業日で資金増減と台帳が一致し、借入元本を売上に含めない。
  • 原子要件(atomic_requirements.json、P05): 表金と裏金を分けて保持する(AR.economy.front_gold_account・back_gold_account)、表のサービスで表資金・裏のサービスで裏資金を得る(front_gold・back_gold)、飲食・宿泊は表の収益(income_food・income_lodging)、成人施設・カジノ・脅迫金・ユニット売却は裏の収益(income_adult・income_casino・income_blackmail・income_trade)、仕入れ・人件費・維持費・借金返済・世界樹ランク税を経費に記帳(expense_*)、日次決算で表裏の売上から全対象経費を引く(settlement_calculation)、00:00 の決算レポート(midnight_report)、維持費の A01・A02(upkeep.*)。
  • P28 の横断条件6件と同じ形の横断条件(原本条件と UI 操作の一致 / Runtime の実利用・会計・行動へ接続 / 途中保存・再起動で再現 / 異常・境界・中断 / 関連回帰 PASS / 要件別ログとソースハッシュ)を、この単位の範囲で適用する。

2. 決定(捏造しない)

  • 既存: A01(維持費は保有時間で日額按分、00:00 精算、不足は翌日へ繰越)、A02(維持費の初期試験値)。
  • 今回のユーザーの決定(2026-10-23、feature-priority-r01/DECISIONS_P05_02.json):
    • A09: 維持費・仕入れ・人件費・借入返済・利息・税は表金から払い、足りない分を裏金で補う。Rootが直接確認した回答は「Front, hidden fills gap (Recommended)」。この回答だけから、両資金が不足した場合の全費目の繰越までをユーザー決定とはしない。§3.3 の日次滞納と操作時拒否の区別は、既存挙動とOpusの仕様案に由来する。
    • A10: 世界樹ランク税は、その日の売上(表+裏)の10%を00:00に経費として計上する(初期試験値)。
    • A11: 闇銀行の利息は、借入残高の日利1%を毎日00:00に計上する(整数・切り捨て、初期試験値)。元本は売上に含めない。
    • A12: 表裏に分ける前の旧セーブは、所持金の全額を表金にし、裏金は0から始める。帳簿の履歴はそのまま。
  • 出典区分: Rootが直接確認したのは4質問と選択回答のラベル。A10の「10% of daily sales (Recommended)」、A11の「1% per day on balance (Recommended)」、A12の「All to front funds (Recommended)」。選択肢の説明文は、質問をした Opus の道具の呼出しから写して PROVENANCE.json に置く(Root は未確認)。説明文は、ラベルと選択肢の中心(A09 表金から先・不足を裏金で補う、A10 その日の売上の10%を00:00、A11 借入残高の日利1%、A12 所持金の全額を表金)を超える新しい人間の承認としない。精算時点・整数切り捨て・帳簿履歴保持などの詳細はOpusの登録仕様案および原要件に由来し、未確認の人間発言として追加しない。根拠は Root の p05-02-owner-registration-draft-r01/SOURCE_RECONCILIATION.json と、このフォルダの PROVENANCE.json。
  • まだ決めていないもの(この単位では作らない): ランクごとの税の差、借入の上限・期限・滞納から脅威(P05-03)、カジノ・脅迫金の発生源(後の単位)、D05 のうち下の §3.6 以外の同時発生。

3. 範囲

3.1 口座

  • 表金は既存の PLAYER_CASH(意味を変えない。gold の資源は今までどおり表金を映す)。裏金は新しい口座 BACK_CASH(負を許さない)。
  • 税と利息は、維持費と同じく「計上(経費 → 未払金)」と「支払(未払金 → 資金)」の2つの記帳にする。未払金の口座に残った額が滞納。

3.2 収入の振り分け

  • 施設の売上は今までどおり施設の売上の口座に入り、その後の移し替え(SERVICE_CASH_SWEEP)の行き先を、施設の定義の札で決める: restricted_service か adult_only があれば BACK_CASH、それ以外は PLAYER_CASH。今の定義では adult_private_room・black_market(trade)・vip_private_salon が裏。
  • カジノと脅迫金は今のゲームに発生源が無い。同じ札の規則で裏に入ることを試験で固定し、発生源は後の単位で作る(開示)。

3.3 支払の規則(A09)

  • 00:00 の精算の支払(維持費、人件費、税、利息): その日に払う額の合計(滞納を含む)のうち表金で足りない分だけを、精算の前に裏金から表金へ補填する(区分 BACK_FUND_TOP_UP、売上でも経費でもない記帳)。その後の支払は今までどおり表金から行う。両方で足りない分は、それぞれの滞納として翌日へ繰り越す(維持費と人件費は既存の滞納の仕組み、税と利息は未払金の口座)。締めが 06:00 の旧暦の 00:00 の維持費の精算にも同じ補填を行う。
  • 操作の時の支払(仕入れの手動と自動、借入の返済): 表金+裏金が足りれば、表金で足りない分を裏金から補填して表金から払う。返済は補填と支払を1つの取引にする。仕入れは、記帳が1つの領収の形を保つため、補填を直前の別の取引にし、仕入れが失敗した場合は両方を取り消す。足りなければ今までどおり拒否し、Gold と在庫を変えない。見積の「払える額」は表金+裏金。
  • それ以外の支払(建設、罰金、event、雇用の契約金、防衛の技能、event の預り金)は今までどおり表金だけ(A09 の対象外。開示)。
  • 出どころの区分: 「表金から先に払い、足りない分を裏金で補う」はユーザーの回答(A09 のラベル)。両方で足りない場合に、00:00 の義務は滞納として繰り越し、操作の時の支払は拒否する、という区別は、ユーザーの決定ではなく、既存のコード(base dda3eed の返済と仕入れは払えない額を拒否する。人件費と維持費は払える分を払い残りを滞納にする)と、それに合わせた Opus の解釈(拒否した操作には繰り越すものが無い)による。

3.4 世界樹ランク税(A10)

  • 第 d 日の 00:00 の精算で、税 = floor(売上_d × 10 / 100)。売上_d は日次決算の売上(表+裏、既存の返金の相殺の後)。0 なら記帳しない。
  • 区分は RANK_TAX、決算の taxes_and_interest に入れる。第 d 日の決算に入り、第 d+1 日に二重に数えない。

3.5 闇銀行の利息(A11)

  • 毎日 00:00 に、利息 = floor(借入残高 × 1 / 100)。借入残高は、その時点の全ての借入の元本の合計(LOAN_PRINCIPAL_BORROWED − LOAN_PRINCIPAL_REPAID)。0 なら記帳しない。
  • 区分は LOAN_INTEREST、決算の taxes_and_interest。元本の出入り(financing_principal_*)は今までどおり売上と経費に入れない。

3.6 00:00 の順序

  • 00:00 の日次の締めの中で、補填 → 人件費 → 維持費(既存の順序)→ 税 → 利息。税と利息は、それぞれの未払金の口座に古い滞納が残っていれば、新しい額より先にそれを払う。
  • 途中保存・再開・同じ分の再試行で、税と利息を二重に計上・支払しない(日ごとの冪等の key)。

3.7 決算とレポート

  • 日次決算に、売上の内訳(表・裏)、税・利息、税と利息の滞納を足す。利益の式(売上 − 全対象経費)と、3回連続の赤字で終了の規則は変えない。

3.8 保存(A12)

  • 資金の口座(BACK_CASH、税と利息の経費と未払金)は帳簿の snapshot の中にあるので、Runtime の snapshot の版は上げない(版 15 はミミの購入の履歴と一致させて検査しているため、版の組を増やさない)。旧セーブは BACK_CASH が無いことで判定し、他の資金の口座も無いことを確かめてから、それらを 0 で作る(A12。PLAYER_CASH と帳簿の履歴はそのまま)。一部だけがある、または性質の違う口座は拒否し、読込の前の状態を保つ。
  • 日次の決算の精算の報告(settlement)に、帳簿だけから求める資金の報告 funds(表裏の売上、補填、税・利息とその支払、税・利息の滞納)を足す。決算の区分(category_totals)の形は変えず、税と利息は既存の taxes_and_interest に入れる。読込の時は funds を帳簿から求め直して一致を確かめ、滞納の合計(arrears_total)は人件費・維持費・税・利息の滞納の和と照合する。分ける前に確定した日は funds を持たない(その日に資金の記帳が無いことを確かめる)。

3.9 表示

  • 帳簿の画面と日次のレポートに、表金・裏金の残高、表裏の売上、税、利息、滞納を出す。今の UI は後で入れ替えるので、見た目は今の部品のまま、通常の操作で読めることだけを求める。

4. 受入条件(全て必須。部分点なし)

ID 内容
P05-02-F1 表金と裏金が別の口座で、裏の札の施設の売上だけが裏金に入る(表・裏の施設を各1つ以上で確かめる)
P05-02-F2 A09 の支払の規則(00:00 の精算、操作の時、対象外の支払が今までどおり)。境界: 表金だけで足りる、裏金で補う、両方で足りず滞納、滞納の翌日の支払
P05-02-F3 A10 の税の値・切り捨て・時点・決算の区分・滞納
P05-02-F4 A11 の利息の値・時点・借入の後と返済の後の残高・元本が売上に入らない
P05-02-F5 3営業日の照合: 表金・裏金それぞれの日ごとの増減が帳簿の合計と一致し、決算の全ての区分が帳簿と一致し、元本が売上に入らない
P05-02-F6 途中保存・00:00 の前後の保存・別の process での再開で、税・利息・振り分けが二重にならず同じ結果。旧 snapshot の移行(A12)と不正値の拒否
P05-02-F7 帳簿の画面と日次のレポートで、表金・裏金・表裏の売上・税・利息・滞納が読める(通常の操作で開く)
P05-02-F8 関連の回帰と最終Sの全 roster が PASS。既存試験の期待値変更はA09・A10・A11の承認済み差、または§3.8のA12旧セーブ移行の差だけに限定し、全件を EXPECTATION_CHANGES.json に変更前後の値・計算または構造差・根拠つきで一覧化する。A12は旧セーブへの5口座(BACK_CASH、LOAN_INTEREST_EXPENSE、LOAN_INTEREST_PAYABLE、RANK_TAX_EXPENSE、RANK_TAX_PAYABLE)の追加だけとし、残高・既存口座・取引履歴・その他の帳簿フィールドの不変をbyte比較で確認する。元の失敗を保存し、未解決の試験を除外してPASSにしない

5. 変更してよいパス(候補)

  • autoload/simulation_runtime.gd
  • scripts/economy/facility_upkeep_settlement.gd(払う額の見込みの純粋な関数)、scripts/economy/finance_policy.gd(新規、口座・税率・利率・裏の札)と .uid
  • scripts/supply/supply_management_service.gd(見積の払える額と、仕入れの前の補填)
  • scripts/ui/operating_ledger_panel.gd
  • tests/economy/test_p05_funds_runtime.gd(新規)と .uid
  • tests/** のうち既存の試験の期待値の更新(§4 F8 の規則の範囲だけ。一覧 execution/p05-02/EXPECTATION_CHANGES.json が必須)
  • tools/run_p05_funds_tests.py(新規、既存の guarded runner の protocol を使う)、tools/regression/suite-policy.json
  • docs/plans/original-completion-2026-10-02/execution/p05-02/**、docs/plans/original-completion-2026-10-02/execution/completion_marker_contracts.json

6. 検証

  • 登録の validation p05-funds: tools/run_p05_funds_tests.py --output {build_dir}/p05-funds-evidence(検証だけ。収集は Root の役割の native で --collect)。roster は8本: 新しい tests/economy/test_p05_funds_runtime.gd と、関連の tests/mvp/test_original_midnight_settlement.gd、tests/mvp/test_runtime_operations_integration.gd、tests/s2/test_runtime_operations_cycle.gd、tests/s6/test_runtime_save_lifecycle.gd、tests/s6/test_runtime_snapshot_serialization.gd、tests/supply/test_supply_management_service.gd、tests/ui/test_upkeep_closed_ui.gd。runner は P18 の guarded runner と同じ protocol(roster・名前・数を roster から求める点だけが違う)。
  • tests/mvp/test_runtime_upkeep.gd は source の中に報告のファイルを生成する suite(suite-policy.json の fixed_generated_report_routes)で、狭い roster の規則(生成物なし)に合わないので入れない。維持費を裏金で補う場面は新しい suite に入れ、test_runtime_upkeep.gd は最終の全 roster で確かめる。tests/ui/test_business_management.gd は古い有界の音声の後始末(old_bounded_teardown)の suite で、その証明は置き直した証拠では照合できない(証明が元の絶対パスを持つ)ので、狭い roster に入れず最終の全 roster で確かめる。帳簿の画面の新しい表示(F7)は、新しい suite が実際の OperatingLedgerPanel に4日分の帳簿を読ませて確かめる。
  • F6 の別の process での再開: 下書きの新しい suite は、同じ process での snapshot の保存と読み直し、セーブファイルへの書き出しと読み直し(save_to_path・load_from_path)までを確かめている。別の process での再開(書き手の process が書いたセーブファイルを、別の process の読み手が読んで同じ結果になること)は、まだ実装していない。登録の後に tools/run_p05_funds_tests.py と tests/** の範囲で、書き手と読み手の2つの段として足す。実装できない場合は F6 を満たさないものとして扱い、範囲を狭めない。
  • final の前に、最終の S で全 roster を1回(重複の全回帰はしない)。
  • 独立レビュー: 実装担当とは別の新しい Opus が、原 work・原 acceptance・横断条件・U1/U2 を whole-unit で判定する。

7. 開示(U1)

  • カジノと脅迫金の発生源は無い(規則だけを固定)。ランクごとの税の差は作らない(A10 は一律10%の試験値)。借入の上限・期限・滞納から脅威、金庫の上限は P05-03。建設・罰金などは表金だけで払う(A09 の対象外)。UI は今の部品のままで、完成の見た目ではない。Windows 実機は後。

8. 登録の前の下書き(正式の証拠ではない)

  • 下書きの作業ツリーと状態: p05-02-registration-proposal-r01/DRAFT_STATUS.md、全試験の直接の実行の診断 p05-02-registration-proposal-r01/DIAGNOSTIC_SWEEP_R01.json(今回の変更で期待値が変わったのは tests/business/test_required_kitchen.gd の A12 だけ。他の 0 以外は base dda3eed でも同じ)。
  • 下書きでの guarded の収集(local-collection-failures/): r01 は import の段で停止(新しい suite の .uid が無かった)。r02 と r03 は 10 本の収集は成功したが、runner の自己検証が失敗した(r02 は P18 の数 7 が残っていた、r03 は報告を生成する suite が roster にあった)。いずれも正式の合格ではなく、失敗の出力を保持する。
  • 登録の後は、下書きの成果を SHA の一致で W に引き継ぎ、W で局所の確認と通常の owner submit を行う。下書きでの実行は数えない。