MAS-071: 稼働率連動型役員報酬シミュレーター(4 軸 × 4 アプローチ統合・MAS-057 cockpit 拡張)
概要
| 項目 | 内容 |
|---|---|
| 案件 ID | MAS-071 |
| 案件名 | 稼働率連動型役員報酬シミュレーター(4 軸 × 4 アプローチ統合・MAS-057 cockpit 拡張) |
| カテゴリ | シミュレーション・役員報酬戦略 / 税務・労務リスク防衛 |
| Phase | P2 |
| 優先度 | ★★★ |
| 実装ステータス | ✅ 完了 (PR #457・2026-05-01・commit 16fdffb → PR #459・commit 8f45430 で UX 細部改善反映)。spec を v0.1 Draft → v1.0 Implemented → v1.1 Implemented に整合追従。v1.0 で 8 領域(4 軸モデル拡張 / 労働強度係数 / 100% 稼働時月額単価入力 / Phase 5 シナリオ保存 / 稼働率独立入力 / UX 日本語化・千円表示 / 法人運転バッファ解釈明確化 / sys_params 7 → 8 キー)。v1.1 で 3 領域追加(UX 細部改善 8 項目 / シナリオ payload 拡張 approachByYear[6] + y0Months / 4 アプローチ平均 AVG 表示)。「実装が spec を先行 → spec を整合追従」のパターン累計 13 例目(v1.0 が 11 例目・v1.1 が 13 例目・MAS-057 v2.4 と同 PR)。 |
| 所要時間 | 約 3 週間(Phase 1 計算エンジン 1 週 + Phase 2 React Panel 1 週 + Phase 3 cockpit 統合 + Phase 4 テスト 1 週・週 10h 前提)+ Phase 5 シナリオ保存 0.5 週(v1.0 で追加) |
| 対象ファイル(新規) | 400_domain/454_compensation_strategy_engine.js(純粋関数・IIFE 名前空間 CompensationStrategyEngine・4 アプローチ A/B/C/D を対称関数化 + 4 軸モデル (V_d, V_s, V_i, V_m) × (R_d, R_s, R_i, R_m) × intensityFactor ・約 400 行)/ webapp_client/src/cockpit/CompensationStrategyPanel.tsx(React 独立パネル・cockpit 最上部配置(経営判断の起点・v1.0 で MAS-058 直下から変更)・約 700 行)/ 800_ops/821_migration_mas071_strategy_seed.js(MAS071_* 8 キー冪等シード) |
| 対象ファイル(変更) | 000_infra/002_constants.js(Constants.MAS071_DEFAULTS 新設・4 軸市場価値 default 等)/ 100_config/101_sys_config.js(40_mas071_scenarios タブ DDL 追加 + flagTabs 登録 + メニュー登録)/ 200_data/202_repository.js(MAS071ScenarioRepository 追加)/ 300_ui/302_spa_bridge.js(bootstrap に MAS071_* 8 キー + mas071Params 追加 + runCompensationStrategySimulation + 4 シナリオ API(listMAS071Scenarios / saveMAS071Scenario / loadMAS071Scenario / deleteMAS071Scenario)追加)/ webapp_client/scripts/sync-engines.mjs(454 を sync 対象に追加・failure_patterns #33 対策)/ webapp_client/src/cockpit-main.tsx(import './engines/454_compensation_strategy_engine.js' を副作用 import 追加・failure_patterns #33 対策) |
| 新規シート | 40_mas071_scenarios(v1.0 で追加):有効フラグ / シナリオID / シナリオ名 / 作成日時 / 更新日時 / payloadJSON / 備考。ID プレフィックス MAS071SC_xxxx(4 桁連番)。 |
新規 03_sys_params キー(v1.0 で 7 → 8 キー) | MAS071_VD_DELIVERY(default 10000000・デリバリー業務市場年収)/ MAS071_VS_SALES(default 10000000・営業マーケ業務市場年収・v1.0 で新設)/ MAS071_VI_INVESTMENT(default 12000000・投資業務市場年収)/ MAS071_VM_MANAGEMENT(default 8000000・管理業務市場年収)/ MAS071_LMIN_LIVING_COST(default 4800000・最低必要額面年収)/ MAS071_BUFFER_MONTHS(default 3・法人最低固定バッファ月商換算)/ MAS071_TARGET_PROFIT(default 6000000・融資対策用目標法人利益)/ MAS071_TC_SCAN_STEP(default 120000・アプローチ C スキャン刻み・月 1 万円)の計 8 キー。 |
| 前提案件 | MAS-057 Phase 1(✅ 完了 PR #356・SocialInsuranceTierEngine / PersonalTaxEngine 実装済)/ MAS-057 Phase 3(✅ 完了 PR #379・SPA 基盤・sync-engines.mjs 確立)/ MAS-057 Step 6.16 シート保存(✅ 完了・_f57Crud_ ファクトリパターン確立・本案件のシナリオ API 4 個もこのファクトリで実装)/ MAS-058 v2.0(✅ 完了 PR #400・RequiredRevenuePanel.tsx の panel 配置原則確立。v1.0 ではこの配置原則を再検討し cockpit 最上部に変更) |
| 後続案件 | MAS-067 マルチイヤー化 v2(5 軸モデルの A1 役員報酬軸に本案件のアプローチ A〜D 推奨レンジを統合 / F67_COMPENSATION_STRATEGY_ENABLED フラグで段階導入) |
| 吸収・再定義対象 | なし(MAS-057 給与系 + MAS-066 配当 + MAS-058 健全性 + MAS-071 「4 軸 × 4 アプローチ統合視点」のスコープ分離) |
目的
bizlp Solo-CEO(一人社長)が役員報酬を決定する際、単なる「節税」だけでなく「自身の稼働割合(時間の使い方)」と「4 つの財務的アプローチ(生活防衛・内部留保・税務最適化・融資対策)」を統合的に評価し、最適な報酬額をシステマティックに導き出すことを目的とする。
MAS-057 Phase 3 cockpit は「年収帯 + 月額/賞与配分」の最適化(社保・所得税・住民税の手取り最大化)を提供したが、「なぜその年収額に決めるのか」の上位判断軸(例: ライフプラン視点 / 法人成長視点 / 税務調査防衛視点 / 融資視点)を明示的にシミュレートする機能はまだない。MAS-071 はこの上位軸を 4 軸稼働率(R_d / R_s / R_i / R_m)× 市場価値(V_d / V_s / V_i / V_m)× 労働強度係数(intensityFactor)= 理論報酬額 TC という客観的根拠で表現し、その TC を 4 つの異なる視点(A/B/C/D)でクランプして「推奨レンジ」をビジュアル提示する。
v1.0 で 3 軸 → 4 軸に拡張:v0.1 Draft では「デリバリー / 投資 / 管理」の 3 軸モデルだったが、実装では Solo-CEO の実態に即して 「営業・マーケティング」軸を独立させた。リード獲得・商談・SNS 運用は「直接案件遂行(デリバリー)」とも「研究・プロダクト開発(投資)」とも性質が異なるため、4 軸目として default 稼働率 20% / 市場年収 1,000 万で配分する。default 配分は 40% / 20% / 30% / 10%(合計 100%)。
v1.0 で労働強度係数 intensityFactor を追加:V(市場年収)はフルタイム前提値(160h/月相当)のため、超過稼働分を線形で TC 増加させる係数を導入。レンジ 0.5 - 2.5(default 1.0)。例えば intensityFactor = 1.4 は「224 時間/月(≒ 月 224h・週 56h 相当)」を意味し、UI に
(140% ・ ≒ 224 時間/月)の補助表示を出す。
特に 税務調査での「不相当に高額な役員給与」(法人税法施行令 70 条 1 号)防衛論理 において、「同種同規模事業の 0.5〜2 倍範囲」の正当化根拠を ロールバリュー積算(V × R × intensityFactor)として書面化できる点が他社 SaaS にない差別化機能。Solo-CEO の役員報酬は「経営判断」だが、その判断を「説明可能(accountable)」にする。
業務 4 軸モデル(v1.0 確定)
| 業務 | 説明(sublabel) | default 市場年収 | default 稼働率 |
|---|---|---|---|
| デリバリー業務 | 案件遂行・顧客対応 | 1,000 万 | 40% |
| 営業・マーケティング 🆕 | リード獲得・商談・SNS 運用 | 1,000 万 | 20% |
| 投資業務 | 研究・プロダクト開発・事業開発 | 1,200 万 | 30% |
| 管理業務 | 経理・労務・法務・プロセス改善 | 800 万 | 10% |
理論報酬額の正式定義:
TC = ((V_d × R_d) + (V_s × R_s) + (V_i × R_i) + (V_m × R_m)) × intensityFactor
例: default 配分(V_d=1000 / V_s=1000 / V_i=1200 / V_m=800・R=40/20/30/10%・intensityFactor=1.0) = (1000×0.4 + 1000×0.2 + 1200×0.3 + 800×0.1) × 1.0 = (400 + 200 + 360 + 80) × 1.0 = 1,040 万
現在のコード
本案件は MAS-057 Phase 1 で確立した PersonalTaxEngine / SocialInsuranceTierEngine を順呼び出しして、4 アプローチ(A/B/C/D)の推奨報酬額を算出するアグリゲータ。新規ロジックは 稼働率 × 市場価値の理論報酬額 TC 算出 + 4 アプローチクランプ計算 + アプローチ C の税務最適スキャン(C_opt)のみ。
MAS-057 Phase 1(✅ 完了)の利用関数
| 関数 | 定義ファイル | 用途 |
|---|---|---|
SocialInsuranceTierEngine.findTier(monthly, tierMap) | 400_domain/442_social_insurance_tier_engine.js:85 | 月額報酬から標準報酬月額等級検索 |
SocialInsuranceTierEngine.calcPremiums(tierInfo, opts) | 同:110 | 月額側社保料計算(健保 + 厚年 + 介護 + 子育て) |
PersonalTaxEngine.calcIncomeTax(taxableIncome) | 同:280 | 個人所得税(累進・1000/100 円端数処理) |
PersonalTaxEngine.calcResidentTax(taxableIncome) | 同:306 | 住民税 10% |
Constants.INCOME_TAX_BRACKETS.brackets | 000_infra/002_constants.js | 個人所得税ブラケット(5-45%) |
Constants.TAX_RATES.brackets | 000_infra/002_constants.js:22 | 法人税累進(軽減 15% / 標準 23.2%) |
Constants.getParam(key, default) | 000_infra/002_constants.js:167 | MAS071_* パラメータ取得 |
裏取り原則(failure_patterns #18-#20): 上記の関数シグネチャ・行番号は MAS-057 spec / MAS-058 spec から転記しており、実装着手前に Read で再確認すること(MAS-057 のリファクタにより行番号がずれる可能性がある)。
MAS-057 Phase 3 SPA 基盤の流用(failure_patterns #33 対策)
webapp_client/scripts/sync-engines.mjs(PR #379 で確立)が 400_domain/{442,443,444,445,449,450,451,452,453}_*.js を webapp_client/src/engines/ にコピー + window 露出する仕組み。本案件で 454 を sync 対象に追加 + webapp_client/src/cockpit-main.tsx に import './engines/454_compensation_strategy_engine.js' を副作用 import 追加することで MAS-071 ドメインエンジンも同じ SSoT 共有方式が適用される(TypeScript 複製ゼロ)。
failure_patterns #33 (MAS-066 PR #402 で発覚) 必須チェック: sync-engines.mjs への追加だけでは Vite が tree-shaking で除外する。必ず cockpit-main.tsx に副作用 import を追加すること。MAS-066 では同問題で commit 41305ea で fix された前例あり。
MAS-058 v2.0 配置原則(cockpit 上の panel 配置)
MAS-058 Step 5(PR #400)で確立した cockpit 配置原則「現状把握↑ vs 目標逆算↓」の境界に従い、本パネル CompensationStrategyPanel.tsx は MAS-058 健全性診断パネルの直下(= 目標逆算レイヤー)に配置する。MAS-058 spec L325 付近の §配置原則を参照。
理由: 4 アプローチ(特に B 内部留保 / D 融資対策)は「現状の月商を所与として、目標の法人利益・内部留保を達成するために報酬を逆算する」性質を持つため、MAS-058 シナリオ健全性診断と同じレイヤー(目標逆算)に並ぶのが概念的に自然。
修正方針
Step 1: 計算エンジン Pure Function の新設(Phase 1)
400_domain/454_compensation_strategy_engine.js を新規作成。IIFE + グローバル変数宣言パターン(既存 442〜453 と並列対称・MAS-057 注意事項 #14 (b) 採用方式)。
// 400_domain/454_compensation_strategy_engine.js (純粋関数 + IIFE 名前空間・v1.0 4 軸対応)
var CompensationStrategyEngine = (function () {
/**
* @param {Object} input
* @param {number} input.opPre 限界利益 = 売上 - 固定費(役員報酬控除前・年額)
* @param {number} input.rDelivery R_d デリバリー業務稼働率(0.0-1.0)
* @param {number} input.rSales R_s 営業・マーケ業務稼働率(0.0-1.0・v1.0 で新設)
* @param {number} input.rInvestment R_i 投資業務稼働率(0.0-1.0)
* @param {number} input.rManagement R_m 管理業務稼働率(0.0-1.0)
* @param {number} input.vDelivery V_d デリバリー業務市場年収
* @param {number} input.vSales V_s 営業・マーケ業務市場年収(v1.0 で新設)
* @param {number} input.vInvestment V_i 投資業務市場年収
* @param {number} input.vManagement V_m 管理業務市場年収
* @param {number} input.intensityFactor 労働強度係数(0.5-2.5・default 1.0・v1.0 で新設)
* @param {number} input.lMin L_min 最低必要額面年収
* @param {number} input.bufferYearly Buffer 法人最低固定バッファ(年額・役員報酬を含まない固定費 × 月数)
* @param {number} input.targetProfit TargetProfit 融資対策目標法人利益
* @returns {{ tc, approachA, approachB, approachC, approachD, recommended: { min, max, median, average } }}
* recommended.average = 4 アプローチの単純平均(v1.0 で計算済 / v1.1 で UI 表示・Step 7-A `ApproachComparisonPanel` 5 列目)
*/
function calcAllApproaches(input) {
var tc = calcTheoreticalCompensation(input);
return {
tc: tc,
approachA: calcApproachA(input, tc),
approachB: calcApproachB(input),
approachC: calcApproachC(input, tc),
approachD: calcApproachD(input, tc),
recommended: _calcRecommendedRange_(input, tc), // { min, max, median, average }
};
}
/**
* 理論報酬額 TC = ((V_d × R_d) + (V_s × R_s) + (V_i × R_i) + (V_m × R_m)) × intensityFactor
* 例: (1000×0.4 + 1000×0.2 + 1200×0.3 + 800×0.1) × 1.0 = 1,040 万
* v1.0 で 3 軸 → 4 軸 + 労働強度係数追加
*/
function calcTheoreticalCompensation(input) {
var roleSum = (input.vDelivery * input.rDelivery)
+ (input.vSales * input.rSales)
+ (input.vInvestment * input.rInvestment)
+ (input.vManagement * input.rManagement);
var intensity = (typeof input.intensityFactor === 'number' && input.intensityFactor > 0)
? input.intensityFactor : 1.0;
return roleSum * intensity;
}
/** アプローチ A: ボトムアップ・生活重視(v1.1 で「生活防衛」→「生活重視」にリネーム) = max(L_min, min(TC, OP_pre)) */
function calcApproachA(input, tc) {
return Math.max(input.lMin, Math.min(tc, input.opPre));
}
/** アプローチ B: トップダウン・内部留保 = OP_pre - (Buffer + OP_pre × R_i) */
function calcApproachB(input) {
var rdReserve = input.opPre * input.rInvestment;
var raw = input.opPre - (input.bufferYearly + rdReserve);
// failure_patterns #29: Number.isFinite ガード(OP_pre × R_i が極端値の防御)
if (!Number.isFinite(raw)) return 0;
return Math.max(0, raw);
}
/** アプローチ C: 税務最適化 = min(C_opt, TC)
* C_opt: L_min〜TC を step 12 万で走査し「法人 + 個人合算手残り最大」のスキャン解 */
function calcApproachC(input, tc) {
var cOpt = _scanOptimalCompensation_(input, tc);
return Math.min(cOpt, tc);
}
/** アプローチ D: 融資対策 = TC × (1 - R_i)
* ただし OP_pre - 報酬 >= TargetProfit を満たすようクランプ(報酬を上限から減らす方向) */
function calcApproachD(input, tc) {
var raw = tc * (1 - input.rInvestment);
var maxAllowedForTarget = input.opPre - input.targetProfit;
if (maxAllowedForTarget < 0) {
// OP_pre < TargetProfit のケース(達成不可)→ 警告 + L_min 採用
return Math.max(0, input.lMin);
}
return Math.min(raw, maxAllowedForTarget);
}
// 内部ヘルパ(末尾 _ で private 化・failure_patterns #28 遵守)
function _scanOptimalCompensation_(input, tc) { /* ... 後述 */ }
function _calcRecommendedRange_(input, tc) {
// 戻り値: { min, max, median, average }
// average = (A + B + C + D) / 4(4 アプローチ単純平均・v1.0 で計算済)
// v1.1 で Step 7-A `ApproachComparisonPanel` の 5 列目「4 アプローチ平均」として表示
/* ... 後述 */
}
return {
calcAllApproaches: calcAllApproaches,
calcTheoreticalCompensation: calcTheoreticalCompensation,
calcApproachA: calcApproachA,
calcApproachB: calcApproachB,
calcApproachC: calcApproachC,
calcApproachD: calcApproachD,
};
})();
// failure_patterns #14 (b) window 露出(sync-engines.mjs が末尾に自動付与)
if (typeof window !== 'undefined') {
window.CompensationStrategyEngine = CompensationStrategyEngine;
}
アプローチ C の _scanOptimalCompensation_ 詳細
L_min 〜 TC の範囲を Constants.getParam('MAS071_TC_SCAN_STEP', 120000)(月 1 万円相当の年額 12 万円)刻みでスキャンし、各候補額に対して 法人税後利益 + 個人手残り = 合算手残り を計算 → 最大値の候補額を返す。
スキャン 1 セル内の処理:
// 候補額 candidate に対する合算手残り計算
function _evalNetTotal_(candidate, input) {
// ① 個人側: 給与所得控除 + 基礎控除 + 社保控除 → 課税所得 → 個人税
var monthly = Math.floor(candidate / 12);
var tier = SocialInsuranceTierEngine.findTier(monthly, input.tierMap);
var premiums = SocialInsuranceTierEngine.calcPremiums(tier, { isOver40: input.isOver40 });
var personalSocialAnnual = (premiums.healthPremium + premiums.pensionPremium) * 12;
var taxableIncome = Math.max(0, candidate - _calcSalaryDeduction_(candidate)
- 480000 - personalSocialAnnual); // 基礎控除 48 万
taxableIncome = Math.floor(taxableIncome / 1000) * 1000; // 1000 円未満切捨
var incomeTax = PersonalTaxEngine.calcIncomeTax(taxableIncome);
var residentTax = PersonalTaxEngine.calcResidentTax(taxableIncome);
var personalNet = candidate - personalSocialAnnual - incomeTax - residentTax;
// ② 法人側: OP_pre - 報酬 - 法人社保 → 法人税 → 法人税後利益
var corporateSocialAnnual = personalSocialAnnual; // 折半
var preTaxProfit = input.opPre - candidate - corporateSocialAnnual;
var corporateTax = _calcCorporateTax_(preTaxProfit, Constants.TAX_RATES.brackets);
var corporateNet = preTaxProfit - corporateTax;
return personalNet + corporateNet;
}
スキャン範囲が (TC - L_min) / 120000 ステップなので、TC = 1,040 万・L_min = 480 万なら 47 セル(1ms × 47 = 50ms 以下で完走)。GAS 6 分制限への影響なし。
Step 2: React Panel UI の新設(Phase 2)
webapp_client/src/cockpit/CompensationStrategyPanel.tsx を新規作成(v1.0 で約 700 行)。
コンポーネント構造(v1.0 実装ベース)
// CompensationStrategyPanel.tsx の主要セクション(上から順に表示・v1.1 で UX 細部改善反映)
// ─────────────────────────────────────────────
// ① シナリオパネル(myr-scenario-panel・緑色テーマ)
// 🔄 再取得 / 💾 上書 / ➕ 新規 / 🗑️ 削除 + プルダウン
// ② 100% 稼働時月額単価入力(v1.0 で月商直接入力から変更)
// monthlyRateAtFull(千円カンマ表示)+ 補助表示「月商 = 単価 × R_d × intensity」
// 【v1.1 追加】月商の右隣に「× 12 ヶ月 = 年商」を併記表示(年商感の即時把握)
// ③ 4 軸稼働率入力(独立入力・連動なし・v1.0 で連動撤回)
// R_d / R_s / R_i / R_m を独立 number 入力(合計 100% は警告のみ)
// 【v1.1 改名】アプローチ A ラベル「生活防衛」→「生活重視」へ全置換
// 【v1.1 改名】投資業務 sublabel に「事業開発」を追加(研究・プロダクト開発・事業開発)
// 【v1.1 追加】業務横帯下に「貢献額合計」+「理論報酬額(労働強度加味)」を表示
// ④ 市場価値カスタマイズ(V_d / V_s / V_i / V_m・default は MAS071_V*)
// 千円単位 + 3 桁カンマ表示(例: 12,000 千円・内部 12,000,000 円)
// ⑤ 労働強度係数 intensityFactor(0.5-2.5・default 1.0)
// UI 補助表示: (140% ・ ≒ 224 時間/月)
// ⑥ 制約値カスタマイズ(L_min 最低生活費 / Buffer 月数 / TargetProfit 目標利益)
// 千円カンマ表示 + バッファは月数で入力
// ⑦ 理論報酬額(日本語表記・大型表示・v1.0 で記号 TC を日本語に置換)
// ↓ 税務調査時の「不相当に高額」防御の根拠として使用
// ⑧ 4 アプローチ比較棒グラフ(recharts BarChart)
// 生活重視 / 内部留保 / 税務最適 / 融資対策 を並列表示(v1.1 で「生活防衛」→「生活重視」)
// 推奨レンジ(A〜C 範囲)を背景色でハイライト
// ⑨ 4 アプローチの計算式(棒グラフ直下に 1 つの details で一括展開・v1.0)
// v0.1 ではアプローチ毎に details を分けていたが、横スクロール最小化のため統合
// 【v1.1 確定】アプローチ別 details は撤廃済(ここ 1 箇所に集約)
// 【v1.1 撤廃】推奨額決定 UI は撤廃(v1.0 で配置していた「推奨額をシナリオに反映」相当のボタン群を削除)
// → 後続 Step 7-A `ApproachComparisonPanel`(MAS-057 v2.4 で追加)で代替表示
// ⑩ 法人税ラベル(v1.1 で「法人税 (累進)」→「法人税等 (国税+地方税)」に改名・小フォント `累進` 注記を併記)
// ⑪ Disclaimer(税理士・社労士の個別助言代替不可)+ 法令引用(法人税法施行令 70 条 1 号)
v1.0 UX 改善ポリシー(実装で確定)
- 専門用語の日本語化: panel 内では
TC/OP_pre/V_d/R_i等の数式記号は日本語ラベルに置換(理論報酬額 / 限界利益 / 直接業務市場年収 / 投資業務稼働率 等)。記号は計算式 details の中でのみ表示。 - 千円単位 + 3 桁カンマ表示: 金額入力欄は
12,000 千円(内部 12,000,000 円)形式。経営者が暗算しやすい桁感優先。 - 計算式の統合 details: 4 アプローチの計算式は 棒グラフ直下に 1 つの
<details>で一括展開(アプローチごとに分けない)。横スクロールの最小化と一覧性向上。 - cockpit 最上部配置(v1.0 で MAS-058 直下から変更): 役員報酬戦略は 経営判断の起点であり、月商・固定費・税務戦略の前に決まる上位制約のため、cockpit 最上部に配置。MAS-058 健全性診断はその後の「現状把握↑」レイヤーで実行する流れ。
v1.1 UX 細部改善(PR #459 / commit 8f45430 で確定)
v1.0 panel UI の細部表記を 8 項目で調整。MAS-057 v2.4 Step 7-A ApproachComparisonPanel 新設(cockpit 拡張パネル群)と並行して MAS-071 panel 側にも適用された。
| # | 項目 | v1.0 | v1.1 |
|---|---|---|---|
| (a) | アプローチ A ラベル | 生活防衛 | 生活重視 |
| (b) | 投資業務 sublabel | 研究・プロダクト開発 | 研究・プロダクト開発・事業開発(3 つ目に「事業開発」追加) |
| (c) | 月商欄ラベル | 月商(直接入力) | 100% 稼働時の月額単価(派生値 revenueMonthly に連動・既に v1.0 後半で実装済を spec 明文化) |
| (d) | 月商の右隣 | (なし) | 「× 12 ヶ月 = 年商」を併記表示 |
| (e) | 業務横帯の下 | (なし) | 「貢献額合計」+「理論報酬額(労働強度加味)」を表示(4 軸稼働率 × V × intensity の積算が一目で読める) |
| (f) | 4 アプローチ計算式 details | アプローチ毎に 4 つの details(v0.1)/ 一括 1 つの details(v1.0 後半) | 棒グラフ直下に 1 つの details で一括展開(確定)・アプローチ別 details は完全撤廃 |
| (g) | 推奨額決定 UI | 「推奨額をシナリオに反映」ボタン群 | 撤廃。後続 Step 7-A ApproachComparisonPanel(MAS-057 v2.4 で追加)で代替表示 |
| (h) | 法人税ラベル | 法人税 (累進) | 法人税等 (国税+地方税) + 小フォント 累進 注記を併記 |
(c) の旧 revenueMonthly(月商直接入力)→ 新 monthlyRateAtFull(100% 稼働時月額単価)への置換は v1.0 後半で実装済だが、シナリオロード時の旧 payload migration(旧 revenueMonthly のみを持つ payload を読み込む際に monthlyRateAtFull = revenueMonthly / (R_d × intensityFactor) で逆算する変換)を v1.1 で spec 内に明示。逆算式と境界条件:
// シナリオロード時の旧 payload migration(v1.1 で明文化)
function migrateLegacyPayload(payload: any): MAS071Payload {
if (payload.monthlyRateAtFull == null && payload.revenueMonthly != null) {
const rDelivery = payload.ratios?.d ?? 0.4;
const intensity = payload.intensityFactor ?? 1.0;
const denom = rDelivery * intensity;
payload.monthlyRateAtFull = denom > 0
? Math.round(payload.revenueMonthly / denom)
: payload.revenueMonthly; // 0 除算回避フォールバック
delete payload.revenueMonthly;
}
return payload as MAS071Payload;
}
月商の派生計算(v1.0 で月商 → 単価入力に変更)
cockpit panel では 月商を直接入力ではなく、100% 稼働時の月額単価を入力する。月商はそこから派生:
月商 = 100% 稼働時月額単価 × デリバリー稼働率(R_d) × 労働強度(intensityFactor)
例: 単価 250 万 × R_d 40% × intensity 1.0 = 月商 100 万 / 単価 250 万 × R_d 60% × intensity 1.4 = 月商 210 万。
F-57 cockpit の revenueMonthly には setInputs 経由で同期反映される(cockpit パネル間連携・v1.0 確定)。
稼働率独立入力(v1.0 で連動制御を撤回)
v0.1 Draft では「合計 100% に連動して他軸を比例配分」する adjustRatios 実装だったが、実装では各 R 値を独立に編集可能とした。理由は以下:
- ユーザーが「営業を 25%」と打った瞬間に、まだ未決定のデリバリー枠が勝手に動くのは編集体験を悪化させる
- ユーザー判断尊重(「稼働率合計 100% である必要は必ずしもない・空き時間の表現も許容する」)
- 合計 ≠ 100% は UI 警告のみ(赤枠 + メッセージ)で表示し、計算は continue する
合計 100% 規約自体は廃止していない(推奨は維持)が、編集中の値が勝手に動くのを防ぐ UX 優先方針。
// v1.0: 連動なし・各 R 値独立編集 + 合計警告のみ
function applyRatio(changed: 'd' | 's' | 'i' | 'm', newValue: number, current: Ratios): Ratios {
return { ...current, [changed]: newValue }; // 他軸は変更しない
}
function getRatioWarning(ratios: Ratios): string | null {
const sum = ratios.d + ratios.s + ratios.i + ratios.m;
if (Math.abs(sum - 1.0) > 0.001) {
return `稼働率の合計が ${(sum * 100).toFixed(0)}% です(推奨: 100%)。空き時間の表現として許容されますが、TC 算出に影響します。`;
}
return null;
}
4 アプローチ比較棒グラフ(recharts)
cockpit 既存依存 (MAS-057 Phase 3) に recharts が含まれているため再利用。BarChart で 4 本横並び・推奨レンジ(min(A,B,C) 〜 max(A,B,C))を <ReferenceArea> で背景色ハイライト・D は別軸(融資対策の独立性を視覚化)。v1.1 で Step 7-A ApproachComparisonPanel(MAS-057 v2.4 で追加)が同じ result.recommended.average を 5 列目「4 アプローチ平均」として表示するため、本 panel の棒グラフでは平均値の目盛りを <ReferenceLine y={result.recommended.average} /> で薄く併記する(v1 では棒グラフ追加なし・別パネル側で表示)。
Step 3: MAS-057 cockpit 統合(Phase 3・v1.0 で配置を変更)
配置先(v1.0: cockpit 最上部に変更)
v0.1 Draft では「MAS-058 panel 直下(目標逆算レイヤー)」配置だったが、v1.0 実装では cockpit 最上部(経営判断の起点) に変更。
理由:
- 役員報酬戦略は他の月商・固定費・税務最適化の上位制約として作用する
- 「月商はいくら必要か」(MAS-058)よりも「自分の役員報酬をいくらにすべきか」が経営判断順序として先
- panel 上部からスクロールして cockpit を読む際に「役員報酬の意思決定 → 必要月商 → 健全性確認」の流れが自然
// CockpitApp.tsx (抜粋・v1.0)
<>
<ScenarioBar />
<AssumptionsBar />
<CompensationStrategyPanel /> {/* MAS-071(v1.0 で cockpit 最上部・経営判断の起点)*/}
<CompensationDropdowns /> {/* MAS-057 + MAS-066 */}
<SankeyDiagram /> {/* MAS-057 */}
<ThreeBlockTable /> {/* MAS-057 + MAS-066 */}
<NetWorthChart /> {/* MAS-057 */}
<EffectiveRateMetric /> {/* MAS-057 */}
{/* === ↑ ここまで「現状把握」レイヤー === */}
{/* === ↓ ここから「目標逆算」レイヤー === */}
<RequiredRevenuePanel /> {/* MAS-058 */}
</>
独立タブ案 vs 統合パネル案
| 観点 | 独立タブ案(旧) | 統合パネル案(採用・推奨) |
|---|---|---|
| 画面切替 | 必要 | 不要・スクロールのみ |
| 既存 cockpit 改修 | tab 制御追加(重) | panel 1 件追加のみ(軽) |
| 4 アプローチと MAS-058 健全性の連動 | tab 跨ぎで分かりづらい | スクロール 1 画面で並列確認可 |
| 推奨レンジ → MAS-057 月額反映 | tab 跨ぎ | 1 画面・即時反映 |
| MAS-066 配当併用時の整合 | 別 tab で再計算ループ発生 | 同 panel 内で完結 |
結論: 統合パネル案 を採用。MAS-058 配置原則「現状把握↑ vs 目標逆算↓」と整合し、MAS-067 マルチイヤー連携時も「ある年の役員報酬戦略」として直接転用可能。
Step 4: 03_sys_params 8 キーシード(v1.0 で必須化)
v1.0 で 7 キー → 8 キーに増加(MAS071_VS_SALES を追加)。マイグレーション番号は 800_ops/821_migration_mas071_strategy_seed.js で確定(main 側 805_migration_d04_d06.js 〜 820_* で消費済のため次空き番)。
MAS071_* 8 キーの冪等シーダー(既存値あればスキップ・なければ default 投入)。MAS-057 / MAS-066 / MAS-067 同パターン。default 動作はシード未実行でも Constants.getParam(key, default) で機能するが、03_sys_params で「現状値の可視化」+「カスタマイズ起点」のため必須運用。
Step 5: シナリオ保存機能(v1.0 で新設・Phase 5)
役員報酬戦略の検討は「複数シナリオを比較しながら進める」性質を持つため、v1.0 で シナリオ保存・読込・上書・削除機能を追加(F-57 / F-67 と同 UX)。
新規シート 40_mas071_scenarios
| 列 | 型 | 説明 |
|---|---|---|
有効フラグ | boolean (チェックボックス) | FALSE で論理削除(MAS071ScenarioRepository.findAll で除外) |
シナリオID | string | MAS071SC_xxxx(4 桁連番・採番関数 MAS071ScenarioRepository.nextId) |
シナリオ名 | string | ユーザー入力(重複可・ID で一意性担保) |
作成日時 | datetime | 新規作成時に自動設定 |
更新日時 | datetime | save / update のたびに更新 |
payloadJSON | string (JSON) | 後述の payloadJSON 構造 |
備考 | string | 任意メモ |
DDL は 100_config/101_sys_config.js の setupAllSchemas に追加 + flagTabs 登録(有効フラグ 列を A 列に配置)+ メニュー登録(テスト用に 🔧 マイグレーション メニュー直下)。
payloadJSON 構造
type MAS071Payload = {
// ─── v1.0 で確定済(13 項目)───
ratios: { d: number; s: number; i: number; m: number }; // 4 軸稼働率
vDelivery: number; // 千円単位(10000 = 1,000 万)
vSales: number;
vInvestment: number;
vManagement: number;
lMin: number;
bufferMonths: number;
targetProfit: number;
intensityFactor: number; // 0.5-2.5
monthlyRateAtFull: number; // 100% 稼働時月額単価
cogsRate: number; // 売上原価率
fixedCostMonthly: number; // 月額固定費(役員報酬を含まない)
// ─── v1.1 で追加(2 項目・SoloFinancialStatementsPanel 連携用)───
approachByYear?: ('A' | 'B' | 'C' | 'D' | 'AVG')[]; // 長さ 6(Y0-Y5 各年のアプローチ選択)
y0Months?: number; // 1-12(Y0 事業継続月数・default 12)
};
v1.1 で追加した 2 フィールド は MAS-057 v2.4 Step 7 の SoloFinancialStatementsPanel(5 年財務諸表パネル)が「各年のアプローチ選択」と「Y0 開始月」を保持するために使用する。state は CockpitApp.tsx に lift し、CompensationStrategyPanel + SoloFinancialStatementsPanel 両方に props 配布する(MAS-057 v2.4 spec を参照)。
// CockpitApp.tsx(v1.1・state lift パターン)
const [approachByYear, setApproachByYear] = useState<('A'|'B'|'C'|'D'|'AVG')[]>(
['A', 'A', 'A', 'A', 'A', 'A']); // 6 要素・Y0-Y5
const [y0Months, setY0Months] = useState<number>(12); // 1-12
<>
<CompensationStrategyPanel
approachByYear={approachByYear} setApproachByYear={setApproachByYear}
y0Months={y0Months} setY0Months={setY0Months}
/* ... 他 v1.0 props ... */
/>
{/* ... */}
<SoloFinancialStatementsPanel
approachByYear={approachByYear} setApproachByYear={setApproachByYear}
y0Months={y0Months} setY0Months={setY0Months}
/* ... 他 props ... */
/>
</>
シナリオ save / load 時の互換性: approachByYear / y0Months は optional とし、v1.0 で保存した既存 payload (これら 2 項目を持たない)をロードする際は approachByYear = ['A','A','A','A','A','A'] / y0Months = 12 の default にフォールバック。saveMAS071Scenario 側は v1.1 cockpit から呼ぶ場合 必ず 2 項目を含めて保存する(前進互換)。
公開 API(_f57Crud_ ファクトリで実装・F-57 / F-67 と同パターン)
| 関数名 | 概要 |
|---|---|
listMAS071Scenarios() | 有効フラグ TRUE の全シナリオ(ID + 名前 + 更新日時) |
saveMAS071Scenario(input) | 新規 or 上書(ID 指定なし → 新規 / 指定あり → 上書) |
loadMAS071Scenario(id) | 1 件取得(payloadJSON deserialize 込み) |
deleteMAS071Scenario(id) | 論理削除(有効フラグ FALSE) |
300_ui/302_spa_bridge.js で _f57Crud_('MAS071ScenarioRepository', 'MAS071_SCENARIO') を呼び出してファクトリ展開。F-57 / F-67 と同型のため新規ロジックは Repository 側のみ。
UX(F-67 / F-57 と同一 UX)
- 緑色テーマ
myr-scenario-panel(F-67 を踏襲) - 4 ボタン: 🔄 再取得 / 💾 上書 / ➕ 新規 / 🗑️ 削除
- プルダウン即時反映(選択 → applyScenario が即時走る)
- 削除確認ダイアログ(
window.confirm)
前回選択シナリオの自動復元(v1.0 で追加)
ハードリロード後にも前回の選択状態を復元するため、選択中のシナリオ ID を localStorage に保存:
- localStorage キー:
mas071_last_selected_scenario_id_v1 - 起動時フロー:
listMAS071Scenarios()後、localStorage から ID を read → list 結果からfind(s => s.id === id)→ 見つかればapplyScenario(scenario) - 見つからない場合(削除済 等)はデフォルト初期値表示
F-57 ScenarioBar / F-67 ScenarioPanel と同パターン(f57_cockpit_last_selected_scenario_v1 / F-67 同等)。
Step 6: v1.1 拡張(PR #459 / commit 8f45430・MAS-057 v2.4 Step 7 と並行)
v1.0 完成後に MAS-057 v2.4 Step 7(cockpit 拡張パネル群) が同 PR #459 で追加されたことに伴い、MAS-071 側にも 3 領域の整合追従を実施。
6-A. UX 細部改善 8 項目(panel 内表記の最終調整)
§Step 2「v1.1 UX 細部改善」表に集約。アプローチ A の「生活防衛」→「生活重視」リネームが panel UI / 棒グラフラベル / 計算式 details / Disclaimer 文中 すべてに伝播することに注意(grep 検証必須)。
6-B. シナリオ payload 拡張(approachByYear[6] + y0Months)
§Step 5「payloadJSON 構造」に集約。state lift パターンで CockpitApp.tsx に保持し、CompensationStrategyPanel + SoloFinancialStatementsPanel(MAS-057 v2.4 Step 7-B)両方に props 配布。シナリオロード時の旧 payload migration(revenueMonthly → monthlyRateAtFull 逆算)を migrateLegacyPayload ヘルパで実装。
6-C. 4 アプローチ平均(AVG)表示
result.recommended.average は v1.0 計算結果に既に含まれていた値((A + B + C + D) / 4・_calcRecommendedRange_ の戻り値)だが、v1.0 では UI に出していなかった。v1.1 で MAS-057 v2.4 Step 7-A ApproachComparisonPanel(cockpit 拡張パネル群の 1 つ)に 5 列目「4 アプローチ平均」 として追加表示することを spec 内で初めて明文化。
| 列 | 表示元 | 値 |
|---|---|---|
| 1 | アプローチ A(生活重視) | result.approachA |
| 2 | アプローチ B(内部留保) | result.approachB |
| 3 | アプローチ C(税務最適) | result.approachC |
| 4 | アプローチ D(融資対策) | result.approachD |
| 5(v1.1 追加) | 4 アプローチ平均(AVG) | result.recommended.average(既存値の表示のみ・計算ロジック不変) |
計算ロジックは v1.0 から不変。454_compensation_strategy_engine.js の _calcRecommendedRange_ は v1.0 時点で既に average フィールドを返しており、v1.1 では UI 側 ApproachComparisonPanel がそれを参照表示するだけ。
6-D. state lift パターン(CockpitApp 経由)
v1.1 で approachByYear / y0Months は CockpitApp.tsx の state として保持し、CompensationStrategyPanel + SoloFinancialStatementsPanel(MAS-057 v2.4 Step 7-B)の 両 panel が双方向同期する。MAS-057 v2.4 spec の Step 7-B 「SoloFinancialStatementsPanel(5 年財務諸表 + 各年アプローチ選択)」と同じ state を共有することで「役員報酬戦略 ↔ 5 年 P/L」の整合性を担保。
// state lift の概念図
CockpitApp // ← state 保持
├─ CompensationStrategyPanel // 各年のアプローチを「設定」する側
│ props: { approachByYear, setApproachByYear, y0Months, setY0Months }
├─ ApproachComparisonPanel (Step 7-A) // 4 アプローチ + AVG 比較表示
│ props: { result }
└─ SoloFinancialStatementsPanel (Step 7-B) // 各年のアプローチを「適用」して 5 年 P/L 描画
props: { approachByYear, setApproachByYear, y0Months, setY0Months }
影響範囲
| 対象 | 種別 | 変更内容 | リスク |
|---|---|---|---|
400_domain/454_compensation_strategy_engine.js | 追加 | CompensationStrategyEngine 名前空間(calcAllApproaches / calcTheoreticalCompensation / calcApproachA-D + 内部ヘルパ群・4 軸モデル + 労働強度係数・約 400 行) | MAS-057 PersonalTaxEngine / SocialInsuranceTierEngine 順呼出のみ・既存ロジックへの影響なし |
webapp_client/src/cockpit/CompensationStrategyPanel.tsx | 追加 | React 独立パネル(4 軸稼働率入力 + 4 軸市場価値カスタマイズ + 労働強度係数 + 100% 稼働時月額単価 + 4 アプローチ比較棒グラフ + シナリオパネル・約 700 行)。v1.1 で「推奨額決定 UI」撤廃(後続 Step 7-A ApproachComparisonPanel で代替表示)+ UX 細部改善 8 項目(生活重視 / 事業開発 / 月商→単価 / 年商併記 / 貢献額合計表示 / 計算式 details 統合 / 法人税ラベル改名)+ シナリオ payload 拡張(approachByYear[6] / y0Months)+ state lift(CockpitApp 経由で SoloFinancialStatementsPanel と共有) | cockpit 最上部に配置(v1.0 で MAS-058 直下から変更)・既存パネルの位置は下方シフト |
webapp_client/src/CockpitApp.tsx | 変更 | CompensationStrategyPanel を AssumptionsBar 直後(cockpit 最上部)に挿入(1 行追加) | 既存 panel レイアウトの上方に挿入されるが意味的衝突なし |
100_config/101_sys_config.js | 変更 | 40_mas071_scenarios タブ DDL 追加 + flagTabs 登録 + メニュー登録(v1.0) | 既存 DDL に影響なし |
200_data/202_repository.js | 変更 | MAS071ScenarioRepository 追加(v1.0・findAll / findById / save / delete / nextId) | 既存 Repository に影響なし |
000_infra/002_constants.js | 変更 | Constants.MAS071_DEFAULTS 新設(4 軸 market value(V_d/V_s/V_i/V_m)+ lMin / bufferMonths / targetProfit / scanStep / intensityFactor の default 値を集約) | 既存定数に影響なし |
300_ui/302_spa_bridge.js | 変更 | bootstrap に MAS071_* 8 キー + mas071Params 追加 + runCompensationStrategySimulation(input) + **4 シナリオ API(listMAS071Scenarios / saveMAS071Scenario / loadMAS071Scenario / deleteMAS071Scenario・_f57Crud_ ファクトリで実装)**追加 | 既存 SPA bridge に影響なし |
webapp_client/scripts/sync-engines.mjs | 変更 | sync 対象に 400_domain/454_compensation_strategy_engine.js を追加(既存 442/443/444/445/449/450/451/452/453 と並列) | 既存 sync に影響なし |
webapp_client/src/cockpit-main.tsx | 変更 | import './engines/454_compensation_strategy_engine.js'(副作用 import)を追加 | failure_patterns #33 必須対策・忘れると bundle に含まれない |
03_sys_params | 変更 | MAS071_* 8 キー追加(v1.0 で MAS071_VS_SALES 追加) | default 動作・シード未実行でも動作 |
40_mas071_scenarios | 追加 | シナリオ保存タブ(有効フラグ / シナリオID / シナリオ名 / 作成日時 / 更新日時 / payloadJSON / 備考)・v1.0 | 新規タブ・既存タブに影響なし |
800_ops/821_migration_mas071_strategy_seed.js | 追加(v1.0 で必須化・番号確定) | MAS071_* 8 キー冪等シーダー(MAS-066 PR #402 の 815_migration_f66_dividend_seed.js 同パターン) | 冪等性確保・既存値あればスキップ |
900_test/901_test_runner.js | 変更 | F71-01〜F71-16 単体テスト追加(16 件・4 軸 × 4 アプローチ × 主要シナリオ + エッジケース) | 既存テストへの影響なし |
| MAS-057 cockpit 既存パネル | 変更なし(v1.1 で連携拡張) | v1.0: 推奨額決定 UI から CompensationDropdowns の月額値を更新する場合は localStorage 経由(パネル間結合を避ける)。v1.1: 推奨額決定 UI 撤廃に伴い、推奨額の表示は MAS-057 v2.4 Step 7-A ApproachComparisonPanel(4 アプローチ + 4 アプローチ平均 AVG の 5 列比較)が担当。MAS-071 panel は 計算結果(4 アプローチ + AVG)の供給元として機能し、CockpitApp 経由で SoloFinancialStatementsPanel にも approachByYear / y0Months を共有 | MAS-057 既存ロジック変更不要・v1.1 で連携経路のみ追加 |
| MAS-058 RequiredRevenuePanel | 変更なし | MAS-058 の evaluateScenarioHealth 結果と並列表示するのみ(連携時は input.officerCompYearly に MAS-071 推奨額を流す) | MAS-058 既存ロジック変更不要 |
| MAS-066 DividendMixOptimizer | 変更なし | 配当併用時は MAS-066 cockpit と独立動作(連携は v2 で検討) | MAS-066 既存ロジック変更不要 |
| MAS-067 マルチイヤー | 連携拡張 | F67_COMPENSATION_STRATEGY_ENABLED フラグで段階導入(MAS-067 Phase B 以降・別 PR) | MAS-067 既存ロジック変更不要 |
| appsscript.json | 変更なし | OAuth スコープ追加不要 | failure_patterns #26 遵守 |
注意事項
#31 ID 採番衝突回避(本案件起票時の重要経緯・必読): ユーザー初期提案ファイル名は
400_domain/445_compensation_strategy_engine.jsだったが、445 は既存 MAS-058 (445_required_revenue_solver.js) で使用済で衝突発覚。次空き番号454_compensation_strategy_engine.jsに振直し(440〜453 は全て使用済: 442 social_insurance / 443 corporate_housing / 444 per_diem / 445 required_revenue / 449 dividend_mix / 450 ai_tool_roi / 451 multiyear_planner / 452 regulation_generator / 453 psf_profitability)。新規ドメインエンジン番号予約前に必ずgrep -nE '400_domain/45[0-9]_' docs/dev/*.mdで全使用状況を確認すること(dev_spec_prompt_template v1.10 Phase 1-A-pre 適用)。#18-#20 命名造語の禁止(必読):
SocialInsuranceTierEngine/PersonalTaxEngineの関数シグネチャは MAS-057 spec / MAS-058 spec から転記しており、実装着手前に必ず400_domain/442_social_insurance_tier_engine.jsを Read で確認すること。MAS-057 のリファクタにより行番号やシグネチャがずれる可能性がある。「calcCompensationOptimumのような関数名は MAS-057 / MAS-066 にも存在しない造語」になっていないか確認。#25 並列実装の対称性(必読): 4 アプローチ A/B/C/D は
calcApproachA(input, tc)/calcApproachB(input)/calcApproachC(input, tc)/calcApproachD(input, tc)の 対称な純粋関数として実装する。引数構造・戻り値型・null フォールバック・Number.isFinite ガードを全 4 関数で揃える(片側だけ別実装にすると将来の拡張時にバグの温床)。MAS-066 spec の注意事項 #8 と整合。#26 oauthScopes 部分宣言禁止(必読):
appsscript.jsonは本案件で変更しない。MAS-071 が追加で必要とする外部 API はなし(社保・税務計算は全て JS 内完結)。万一スコープ追加が必要になった場合は MAS-057 / MAS-066 の前例(appsscript.json変更なし)を踏襲し、Advanced Service ならenabledAdvancedServices側に宣言する。#29 V8 → Java Infinity null 化(必読): アプローチ B
OP_pre × R_iで OP_pre がInfinity/ R_i がNaNになる極端ケースに備え、calcApproachB内でNumber.isFinite(raw)ガードを必須実装。クライアント返却前に300_ui/302_spa_bridge.jsの_scrubInfinityForJSON_ヘルパ(MAS-066 PR #402 で確立)で再帰的にスキャンし、Infinity→Number.MAX_SAFE_INTEGER、NaN→nullに変換する。runCompensationStrategySimulationの戻り値経路で必ず通過させる。#33 SPA 副作用 import 漏れ防止(必読・最頻発バグ):
webapp_client/scripts/sync-engines.mjsへの 454 追加だけでは不十分。webapp_client/src/cockpit-main.tsxにimport './engines/454_compensation_strategy_engine.js'を必ず追加すること。Vite の tree-shaking が「副作用なし」と判断して bundle から除外する典型パターン。MAS-066 PR #402 で同問題が commit41305eaで fix された前例あり。チェックリスト: ① 454 ファイル新設(IIFE + window 露出)→ ② sync-engines.mjs 追加 → ③ cockpit-main.tsx 副作用 import 追加 ← 必須・抜けやすい → ④npm run build→ ⑤ ブラウザでconsole.log(window.CompensationStrategyEngine)で undefined でないことを確認。「不相当に高額な役員給与」判定リスクと税務調査での防衛論理(本案件の差別化要素・最重要): 法人税法施行令 70 条 1 号は役員給与の損金算入要件として「同種事業類似規模の 0.5〜2 倍範囲」を判定基準とする。本案件の 理論報酬 TC = ロールバリュー積算 (V_d × R_d + V_i × R_i + V_m × R_m) は、この判定基準を「自社の業務内容を分解して市場相当額を積み上げる」客観的根拠として書面化する。税務調査時に「なぜこの報酬額か」の説明資料として、稼働率内訳と市場価値ベンチマーク(出典: doda / type / OpenWork 等)を併記する設計。実装で必ず Disclaimer: 「本提案は税理士・公認会計士の個別助言に代わるものではありません。実際の税務判断は顧問税理士にご相談ください」を panel 下部に常時表示(MAS-057 / MAS-058 / MAS-066 と同パターン)。
稼働率自己申告の客観性担保: R_d / R_s / R_i / R_m (v1.0 4 軸)はユーザー自己申告のため、税務調査では「タイムシート等の証憑」要求リスクあり。MAS-218(タイムトラッキング導入・R&D 税制連携・現 P3)と将来連携することで、自己申告 → 実績記録ベースに昇格させる経路を確保(人間検討事項 #4)。本案件 v1 は自己申告ベースのみ。
市場価値の業種別ベンチマーク更新頻度: V_d / V_i / V_m の default 値(1,000 / 1,200 / 800 万)は IT/コンサル系を想定した参考値。業種・地域・スキル別に大きく変動するため、
03_sys_paramsで個別カスタマイズ可能とした。default 値の年次更新は人間検討事項 #5 で運用ルール化する。アプローチ B 内部留保が負値になるケース:
OP_pre - (Buffer + OP_pre × R_i)が負になる場合(例: OP_pre = 500 万 / Buffer = 600 万 / R_i = 50%)はMath.max(0, raw)でクランプ。UI で「内部留保アプローチは現状の限界利益では成立しません」警告を表示(エッジケース #7)。アプローチ D 融資対策の TargetProfit 達成不可ケース:
OP_pre - 報酬 < TargetProfitが達成不可(OP_pre < TargetProfit)の場合はL_minを返却し UI で「目標利益達成不可・売上向上が先決」警告を表示(エッジケース #9)。MAS-058 v2.0 の「healthy 達成困難」警告と整合。法令変更時の年次更新フロー: 法人税法施行令 70 条 1 号の判定基準(0.5〜2 倍)は条文上の数値ではなく税務通達・裁判例の蓄積。
Constants.MAS071_DEFAULTS内に TODO コメントで「税理士相談で年次見直し」を明示し、毎年 3 月税制改正後にレビュー対象とする運用。MAS-066 spec 注意事項 #13 と同パターン。Pure Function 厳格化(MAS-057 注意事項 #14 準拠):
400_domain/454_compensation_strategy_engine.jsはSpreadsheetApp/UrlFetchAppだけでなくUtils/Constantsへの直接依存も排除する。料率・market value default 等は300_ui/302_spa_bridge.js経由で input 引数として注入。ログ出力は戻り値のwarnings: [{ level, message }]配列で返し、呼出元(SPA bridge)でUtils.persistLogを呼ぶ。Jest 統合テスト時に依存ゼロでテスト可能。退職金算定基礎との整合: 役員退職金の算定基礎は「最終月額報酬 × 在任年数 × 功績倍率」が一般式。MAS-071 で月額を低く抑える戦略(アプローチ B / D)を採用すると、将来の退職金枠が縮小する長期トレードオフが発生。本案件 v1 では指摘のみ(人間検討事項 #5)、v2 で退職金 NPV を含めた評価軸に拡張検討。
定期同額給与改定タイミング 3 ヶ月ルール: 役員報酬の月額変更は事業年度開始から 3 ヶ月以内(法人税法施行令 69 条 1 項)が原則。本案件の推奨額を即時反映するには「次期事業年度開始時」が適切。UI で「現事業年度開始: YYYY-MM / 改定可能期限: YYYY-MM」を表示(MAS-067 マルチイヤー連携時に該当年タブで表示)。
【v1.0 追加】法人運転バッファの解釈(必読・実装方針確定): アプローチ B / D で使う
bufferYearlyの解釈は実装上 「役員報酬を含まない固定費 × 月数」 とした。これは「役員報酬を一時停止しても会社が事業を続けられる期間」の意味。役員報酬込みのバッファ(給与+固定費)にしたい場合は バッファ月数を増やす方がシンプル(例: 固定費のみ × 5-6 ヶ月で実質「現状総支出 3 ヶ月分」相当)。本実装は前者の「最低限の事業継続」を優先するシンプルモデル。後者を厳密にやりたい場合はbufferYearlyの input 値を呼出側で(fixedCost + officerComp) × monthsとして上乗せして渡す方針も可(v2 候補)。【v1.0 追加】稼働率独立入力(合計 100% は警告のみ): v0.1 Draft の連動制御(
adjustRatios比例配分)は 撤回。各 R 値は独立に編集可能。合計 ≠ 100% は UI 警告のみ(赤枠 + メッセージ)で表示し、計算は_validateRatios_で例外 throw せず continue する。ユーザー判断尊重 + 編集中の値が勝手に動かない UX 優先。エッジケース #1 もこれに合わせて「警告のみ・処理は継続」に書換済。【v1.0 追加】UX 日本語化と千円カンマ表示: panel 内では
TC/OP_pre/V_d/R_i等の数式記号は日本語ラベル(理論報酬額 / 限界利益 / 直接業務市場年収 / 投資業務稼働率 等)に置換。記号は計算式<details>の中でのみ表示。金額入力欄は 千円単位 + 3 桁カンマ表示(12,000 千円内部 12,000,000 円)。経営者の暗算負担軽減と桁感の即時把握が目的。【v1.0 追加】月商 → 100% 稼働時月額単価入力への置換: cockpit panel では月商を直接入力ではなく、100% 稼働時月額単価を入力。月商は
単価 × R_d × intensityFactorで派生。F-57 cockpitrevenueMonthlyにはsetInputs経由で同期反映する。これにより「単価 × 稼働率 × 強度」の 3 要素分解が UI で明示され、経営戦略の構造化が進む。【v1.1 追加】アプローチ A の「生活防衛」→「生活重視」リネーム(必読・grep 検証必須): PR #459 で Solo-CEO のメンタルモデルに合わせて「生活防衛」(守備的・縮こまった印象)→「生活重視」(積極的・優先度を表す中立用語)にリネーム。panel UI / 棒グラフラベル / 計算式 details / Disclaimer 文 / docstring すべてに伝播することに注意。実装後
grep -rn "生活防衛" webapp_client/src/cockpit/CompensationStrategyPanel.tsxで漏れがないこと確認。spec 内では §概要 / §目的 / §仕様書作成プロンプト / §Gemini 調査結果 等の歴史記述では「生活防衛」表記を残し、実装ラベルとしての扱いは v1.1 で「生活重視」に統一。【v1.1 追加】推奨額決定 UI 撤廃 → Step 7-A
ApproachComparisonPanel移管(cockpit 構造変更): v1.0 で MAS-071 panel 下部に配置していた「推奨額をシナリオに反映」ボタン群を撤廃。代替として MAS-057 v2.4 Step 7-A で新設されたApproachComparisonPanel(4 アプローチ + AVG 平均の 5 列比較)が推奨額表示の責務を負う。MAS-071 panel は計算結果(4 アプローチ + AVG)の供給元として機能し、結果は CockpitApp の state を経由して Step 7-A panel に流れる。本変更により MAS-071 panel 単体で「推奨額の決定」を完結させない疎結合設計に移行(panel 単体テスト容易化 + cockpit 全体での推奨額表示の一元化)。【v1.1 追加】シナリオ payload 拡張時の旧形式 migration(必読・データ互換性): v1.0 で保存した payload は
approachByYear/y0Monthsを持たないため、v1.1 でロードする際は default 値(['A','A','A','A','A','A']/ 12)にフォールバック。また、v1.0 後半でrevenueMonthly→monthlyRateAtFull置換した際の旧形式はmigrateLegacyPayloadヘルパで逆算(monthlyRateAtFull = revenueMonthly / (R_d × intensityFactor))。前進互換のため v1.1 cockpit から保存する payload は必ず 2 項目を含めて保存する(loadMAS071Scenario の戻り値は migrate 済の MAS071Payload を返す)。
エッジケース
実装時に必ず以下 16 件を単体テスト F71-01〜F71-16 でカバーする。
| # | 条件 | 検知方法 | 期待される挙動 | ログ出力 |
|---|---|---|---|---|
| 1 | 稼働率合計 ≠ 100%(R_d + R_s + R_i + R_m ≠ 1.0) 【v1.0 警告のみ】 | 入力時の getRatioWarning | UI で赤枠警告のみ表示・計算は continue(例外 throw しない)。ユーザー判断尊重 + 編集中の値が勝手に動かない UX 優先(v1.0 で連動制御撤回) | WARN |
| 2 | V_d / V_s / V_i / V_m に 0 が含まれる | input.vDelivery === 0 等 | TC が該当業務分だけ減るが計算継続(業務に従事していない場合の正当な値) | なし |
| 3 | 全 V がゼロ(V_d = V_s = V_i = V_m = 0) | TC === 0 | TC = 0 / アプローチ A は L_min / アプローチ B は OP_pre - Buffer / アプローチ C はスキャン下限 / アプローチ D は L_min(TC ゼロ時の特殊扱い) | WARN |
| 4 | OP_pre が負(赤字法人) | input.opPre < 0 | アプローチ A は L_min(赤字でも生活費は確保すべきという業務判断)/ B/C/D は計算継続(負値も許容)+ UI で「赤字シナリオ」警告 | WARN |
| 5 | TC > OP_pre(理論報酬が限界利益超過) | tc > input.opPre | アプローチ A は OP_pre でクランプ(min(TC, OP_pre))/ UI で「市場価値が限界利益を上回るため一部のみ実現可能」表示 | INFO |
| 6 | L_min > OP_pre(最低生活費 > 限界利益) | input.lMin > input.opPre | アプローチ A は L_min を返却(赤字計上覚悟の生活防衛)+ UI で「法人赤字許容モード」赤枠警告 | WARN |
| 7 | アプローチ B が負値(Buffer + OP_pre × R_i > OP_pre) | _calcApproachB_ の raw < 0 | Math.max(0, raw) で 0 クランプ + UI で「内部留保アプローチは現状の限界利益では成立しません」警告 | WARN |
| 8 | R_i = 100%(全部 R&D・直接業務ゼロ) | input.rInvestment === 1.0 | TC = V_i のみ / アプローチ B = OP_pre - (Buffer + OP_pre) = -Buffer(負)→ 0 クランプ / アプローチ D = TC × 0 = 0 | INFO |
| 9 | アプローチ D で TargetProfit 達成不可(OP_pre < TargetProfit) | maxAllowedForTarget < 0 | アプローチ D = L_min を返却 + UI で「目標利益達成不可・売上向上が先決」警告 | WARN |
| 10 | アプローチ C スキャンでグローバル最適に到達しない(local maximum 性) | 凸性破れケース(社保等級境界等) | step を細かくする(120000 → 60000)+ multi-start scan で複数初期値から探索(v2 拡張)/ v1 では step 12 万固定で許容 | INFO |
| 11 | 4 アプローチが全て 0 円(OP_pre 極小・L_min 極大の異常組合せ) | max(A,B,C,D) === 0 | UI で「シミュレーション成立せず・前提値見直し」赤枠警告 + Step 7-A ApproachComparisonPanel の 5 列(A/B/C/D/AVG)すべて 0 表示(v1.1 で推奨額決定 UI 撤廃後の挙動) | ERROR |
| 12 | Infinity 発生(OP_pre が極大値・R_i が極小値で乗算オーバーフロー) | Number.isFinite(raw) === false | 各 calcApproachX で 0 を返却 + _scrubInfinityForJSON_ で Number.MAX_SAFE_INTEGER に scrub(spa_bridge 経由・failure_patterns #29) | ERROR |
| 13 | マイナスゼロ(-0)の境界 | Object.is(value, -0) === true | Math.max(0, value) で +0 に統一(JSON シリアライズで -0 は 0 化されるが念のため明示処理) | なし |
| 14 | 役員社宅併用(MAS-057 連携)で実質可処分が変わる | input.housingAllowance > 0 | spec v1 では考慮外(独立計算)/ v2 で effectiveCompensation = candidate + housingDeductibleEquivalent として再計算検討(人間検討事項 #6) | INFO |
| 15 | 配偶者役員化(MAS-066 配当と独立判定) | input.spouseAsDirector === true | spec v1 では考慮外(一人法人前提)/ v2 で配偶者報酬を別軸として追加検討(人間検討事項 #7) | INFO |
| 16 | 事前確定届出給与(賞与寄せパターン) | MAS-057 cockpit で bonus > 0 設定済 | MAS-071 panel は「年額ベース」で計算(月額換算は MAS-057 cockpit に委譲)/ Step 7-A ApproachComparisonPanel 経由で MAS-057 月額/賞与配分の自動計算を提案(v2 候補・人間検討事項 #9・v1.1 で推奨額決定 UI 撤廃に伴い経路を更新) | INFO |
実データ検証
1. 齋藤 Baseline(年商 5,000 万 + OP_pre 2,000 万 + R = 40:20:30:10 / intensityFactor = 1.0)【v1.0 4 軸ベースに更新】
実装完了後に以下を 901_test_runner.js で自動検証し、±5% 以内で一致を合格基準とする。
| アプローチ | 期待値 | 計算根拠 |
|---|---|---|
| TC 理論報酬 | 1,040 万 | ((1000×0.4) + (1000×0.2) + (1200×0.3) + (800×0.1)) × 1.0 = (400 + 200 + 360 + 80) × 1.0 = 1,040 |
| A 生活防衛 | 1,040 万 | max(480, min(1040, 2000)) = max(480, 1040) = 1,040 |
| B 内部留保 | 1,250 万 | 2000 - (150 + 2000 × 0.3) = 2000 - 750 = 1,250(Buffer = 月商 416 万 × 3 ヶ月 / 12 = 150 万年換算) |
| C 税務最適 | 約 850-950 万 | スキャン解(社保上限 + 個人累進境界の組合せで決定・MAS-057 単体テストの最適解と整合) |
| D 融資対策 | 728 万 | TC × (1 - R_i) = 1040 × 0.7 = 728・OP_pre - 728 = 1,272 ≥ TargetProfit 600 万 OK |
期待される推奨レンジ: 728 万(D)〜 1,250 万(B)。MAS-058 健全性診断の「現シナリオで Y1-Y5 期末黒字維持」を満たすかも併せて確認。
注意: v0.1 Draft では 3 軸(60/30/10)で TC = (1000 × 0.6) + (1200 × 0.3) + (800 × 0.1) = 1,040 万 だったが、v1.0 では 4 軸(40/20/30/10)+ V_s = 1,000 万 で TC = 1,040 万 と同値になるよう default を調整(既存テスト期待値の互換性維持)。intensityFactor = 1.4 では TC = 1,456 万 となる。
2. R_i 変動による感度分析
| R_i | TC | アプローチ A | アプローチ B | アプローチ C | アプローチ D |
|---|---|---|---|---|---|
| 0% | 920 万 | 920 万 | 1,850 万 | 約 850 万 | 920 万 |
| 30%(齋藤 Baseline) | 1,040 万 | 1,040 万 | 1,250 万 | 約 900 万 | 728 万 |
| 50% | 1,120 万 | 1,120 万 | 850 万 | 約 950 万 | 560 万 |
| 80% | 1,200 万 | 1,200 万 | 250 万 | 約 1,000 万 | 240 万 |
| 100% | 1,200 万 | 1,200 万 | 0 万(Buffer 控除のみ・負クランプ) | 約 1,000 万 | 0 万 |
R_i が高いほど B/D が圧縮され「個人より法人に資産を残す」志向が強くなることを可視化。
3. 4 アプローチの差分が極端なケース
- OP_pre = 500 万(赤字寸前)/ TC = 1,040 万 / R_i = 30%
- A = 480 万(L_min クランプ)/ B = 0 万(負クランプ)/ C = 約 480 万 / D = 0 万(OP_pre - 600 < 0)
- Step 7-A
ApproachComparisonPanel(v1.1 以降)で「現状の収益規模では戦略的な役員報酬最適化の余地が乏しい・売上向上が先決」を表示(v1.0 では推奨額決定 UI に表示・v1.1 で撤廃に伴い後続パネルへ移管)
4. MAS-057 PersonalTaxEngine / SocialInsuranceTierEngine との数値整合
_scanOptimalCompensation_ 内で呼出した SocialInsuranceTierEngine.findTier / calcPremiums / PersonalTaxEngine.calcIncomeTax / calcResidentTax の戻り値を MAS-057 単体テストの期待値と照合し、±1 円一致を合格基準とする(同一ライブラリ呼出のため)。
5. エッジケース検証(単体テスト F71-01〜F71-16)
エッジケースセクションの 16 項目それぞれを 1 テストケースとして 901_test_runner.js に追加。特に #1(合計 ≠ 100%)/ #11(4 アプローチ全 0 円)/ #12(Infinity)は失敗時の例外メッセージ内容まで検証する。
6. 税務調査防衛資料の文章生成(v1 では手動・v2 で自動化検討)
実装後に「アプローチ別の説明文」を panel 下部に表示する機能を追加(v1 では固定文言のみ)。v2 で「ロールバリュー積算の正当化文書(PDF)」自動生成を MAS-144 規程ジェネレーター(452_regulation_generator.js)と連携検討。
関連ドキュメント
| カテゴリ | ドキュメント | 関係 |
|---|---|---|
| 親案件 (Solo-CEO Cockpit) | dev_mas-057_solo_ceo_cockpit.md v2.4 | 給与系最適化(A + B)の SSoT・UI 拡張先・PersonalTaxEngine / SocialInsuranceTierEngine の供給元・v2.4 Step 7-A ApproachComparisonPanel(4 アプローチ + AVG)+ Step 7-B SoloFinancialStatementsPanel(5 年財務諸表 + approachByYear / y0Months 共有)連携先(v1.1 で追加) |
| MAS-058 必要年商シミュレーター | dev_mas-058_required_revenue_solver.md v2.1 | panel 配置原則「現状把握↑ vs 目標逆算↓」の確立元・MAS-071 panel は MAS-058 panel 直下に配置 |
| MAS-066 配当ミックス最適化 | dev_mas-066_dividend_mix_optimizer.md v1.2 | _scrubInfinityForJSON_ 汎用ヘルパの実装元(PR #402)・MAS-071 でも同パターン適用 |
| MAS-067 マルチイヤー計画 | dev_mas-067_multiyear_planning_workspace.md v1.2 | 後続連携先(F67_COMPENSATION_STRATEGY_ENABLED フラグで段階導入) |
| MAS-141 節税共済シミュレーター | dev_mas-141_tax_saving_simulator.md | 節税戦略の独立軸(共済 / 退職金)・本案件と相互参照 |
| MAS-061 Cash ETR トラッキング | dev_mas-061_cash_etr_tracking.md v1.1 | 節税優先順位サジェスト・MAS-071 推奨額の妥当性検証に使用 |
| MAS-218 タイムトラッキング導入 | (TODO_future.md 起票済・P3) | 稼働率自己申告 → 実績記録ベース昇格の連携先(v2 拡張・人間検討事項 #4) |
| failure_patterns | failure_patterns.md | #18-#20(命名造語)/ #25(並列実装対称性)/ #26(oauthScopes)/ #29(V8→Java Infinity null)/ #31(ID 採番衝突・本案件 445→454 振直し起源)/ #33(SPA 副作用 import 漏れ) |
| dev_spec_prompt_template | dev_spec_prompt_template.md v1.10 | 14 セクション準拠・Phase 1-A-pre 番号衝突チェック適用済 |
| CLAUDE.md | CLAUDE.md | 名前空間ルール / GAS ファイル番号体系 / Pure Function 規約 |
| PRD(プロダクトポリシー) | prd.md | Human-in-the-Loop 原則 + Disclaimer |
| 法人税法施行令 70 条 1 号(外部) | e-Gov 法令検索 | 「不相当に高額な役員給与」判定基準・本案件の差別化要素の根拠条文 |
| MAS-337 融資審査スコアリング機能 | dev_mas-337_loan_screening_score.md | アプローチ D の targetProfit 動的算出版を本仕様で提供。MAS071_TARGET_PROFIT (default 600 万) は経験則ベースの定数だが、MAS-337 で借入希望額・業種・業歴・自己資本比率等から動的算出した推奨 TargetProfit を逆流注入する。優先順位: UI 手動上書き > 動的算出 (MAS-337) > historical_default (600 万) |
| Gemini 調査結果(外部 input・要約版) | tasks/prompts/task_F-43.gemini.md(本 PR で追加) | 4 アプローチ統合視点の素案 + 稼働率連動の論理構築(main 側 PR で full text 保管推奨) |
| Claude 調査結果(外部 input・要約版) | tasks/prompts/task_F-43.md(本 PR で追加) | 4 アプローチ統合視点の素案 + 計算式定義(main 側 PR で full text 保管推奨) |
人間が検討すべき事項
稼働率自己申告の客観性担保: R_d / R_s / R_i / R_m (v1.0 4 軸)はユーザー自己申告のため税務調査時に「タイムシート等の証憑」要求リスクあり。MAS-218 タイムトラッキング導入と連携することで自己申告 → 実績記録ベースに昇格させるか、自己申告のまま運用ガイドで「四半期に 1 回 R 値を見直し記録する」運用ルール化するか。判断基準: bizlp 自身の運用で「R 値の実績乖離」がどの程度発生するかを 6 ヶ月モニタリング後に判断。
市場価値の業種別ベンチマーク更新頻度: V_d = 1,000 万 / V_i = 1,200 万 / V_m = 800 万の default 値は IT/コンサル系参考値。年次更新の出典をどう確定するか(doda / type / OpenWork / 経産省賃金構造基本統計調査)。運用案: 毎年 4 月(厚労省賃金構造基本統計調査公表月)に default 値を見直す運用を
Constants.MAS071_DEFAULTSの TODO コメントに明記。4 アプローチ重み付けの自動 vs 手動: v1.0 では推奨額決定 UI 内で 4 アプローチの単純平均 vs 重み付け平均(生活重視 / 内部留保重視等)を選べる設計だったが、v1.1 で推奨額決定 UI を撤廃し、Step 7-A
ApproachComparisonPanelに 「単純平均 AVG」を 5 列目として常時表示する方式に変更。v2 で「フェーズ別重み(成長期 = B 重視 / 安定期 = C 重視 / 融資直前 = D 重視)」プリセットをApproachComparisonPanel側に追加検討。配偶者役員化の組込タイミング(v2+): 一人法人 → 夫婦法人化時に MAS-071 panel を配偶者分も並列表示するか、別 panel に分離するか。MAS-066 配当ミックス(株主が複数になるケース)と整合性確保が必要。
退職金算定基礎(月額報酬ベース)との整合: アプローチ B / D で月額を低く抑える戦略を採用すると将来の退職金枠が縮小する長期トレードオフ。退職金 NPV を 4 アプローチの評価軸に追加するか、別 panel(MAS-141 共済シミュレーター連携)に切出すか。v1 では指摘のみ、v2 で NPV ベース評価検討。
役員社宅(MAS-057 / MAS-144 連携)で実質可処分が変わる扱い: 役員社宅家賃の法人負担分 50% は給与課税されないため、実質可処分は「報酬額 + 社宅相当額」となる。MAS-071 の
effectiveCompensation計算に社宅控除分を加算するか、独立計算のまま運用するか。spec v1 では独立計算、v2 でeffectiveCompensation = candidate + housingDeductibleEquivalentとして再計算検討。定期同額給与改定タイミング 3 ヶ月ルールの UI 表示: 法人税法施行令 69 条 1 項の「事業年度開始から 3 ヶ月以内」原則を MAS-067 マルチイヤー連携時に該当年タブで明示するか、本 panel 単体でも表示するか。v1 では panel 下部に「次期事業年度開始: YYYY-MM」を表示するのみ、MAS-067 連携時に色分けアラート(緑/黄/赤)化検討。
事前確定届出給与の社保削減 vs 退職金枠縮小トレードオフ: 賞与寄せ(MAS-057 / MAS-066 連携)で社保を削減すると退職金算定基礎が縮小する。本案件の 4 アプローチに「退職金考慮アプローチ E」を追加するか、注記のみで運用するか。v1 では注記のみ、v2 でアプローチ E 追加検討。
業績悪化改定事由の厳格性 UX: 法人税法施行令 69 条 1 項 3 号「業績悪化改定事由」の厳格適用を UI 上どう表現するか。「赤字シナリオ」検出時に「業績悪化改定事由の客観的根拠(取引先倒産等)が必要」警告を表示するか。
賞与寄せ型シミュレーション拡張(v2): MAS-057 cockpit の「月額/賞与配分」最適化と本案件の「年額ベース 4 アプローチ」をどう統合するか。MAS-057 月額/賞与配分の最適解を Step 7-A
ApproachComparisonPanel(v1.1 で推奨額決定 UI から代替)から自動算出し、結果を MAS-057 cockpit に反映する双方向連携を実装するか。v1 では片方向のみ(MAS-071 推奨年額 → MAS-057 月額換算)、v2 で双方向化検討。多通貨化時の市場価値外貨対応(out of scope MAS-064 連動): 海外フリーランス採用 / オフショア勤務時に V_d を USD / EUR ベースで設定するか。MAS-064 多通貨対応の進捗に応じて連携検討。v1 では JPY 固定。
税務調査防衛資料の自動生成(v2 候補): アプローチ TC = ロールバリュー積算の根拠書面(Word / PDF)を MAS-144 規程ジェネレーター(
452_regulation_generator.js)と連携して自動生成するか。v1 では panel 下部の固定文言のみ、v2 で MAS-144 連携実装。
実装プロンプト(Claude Code 用)
Claude Opus 4.7(1M context)推奨。MAS-057 PersonalTaxEngine 結合 + 4 アプローチ対称実装 + React 独立パネル + MAS-058 配置原則準拠の複合判断のため。
## 案件
MAS-071 — 稼働率連動型役員報酬シミュレーター(4 アプローチ統合・MAS-057 cockpit 拡張)
## 事前調査(必ず Read する・failure_patterns #18-#20 対策)
1. `docs/dev/dev_mas-071_compensation_strategy_simulator.md` 全文(本仕様書)
2. `400_domain/442_social_insurance_tier_engine.js` 全文
— SocialInsuranceTierEngine.findTier / calcPremiums の関数シグネチャ確認
— PersonalTaxEngine.calcIncomeTax / calcResidentTax の関数シグネチャ確認
— 端数処理(Math.floor(taxableIncome / 1000) * 1000 等)の正確な実装位置
3. `400_domain/445_required_revenue_solver.js` 全文
— 同型 cockpit 統合パネルの実装パターン(`evaluateScenarioHealth` の input/output 構造)
4. `400_domain/449_dividend_mix_optimizer.js` 全文
— IIFE + 内部ヘルパ命名 / failure_patterns #29 対策パターン
5. `webapp_client/src/cockpit/RequiredRevenuePanel.tsx` 全文(909 行)
— React 独立パネルの実装パターン(panel-local state + cockpit 全体 state の分離)
6. `webapp_client/src/cockpit/CompensationDropdowns.tsx` 全文
— MAS-057 ドロップダウンの状態管理パターン(推奨額決定 UI からの月額自動更新の連携先)
7. `webapp_client/src/cockpit/calc.ts` 全文
— calcDividendTax 組込パターン(MAS-066)/ MAS-071 でも同パターン適用可能性検討
8. `webapp_client/scripts/sync-engines.mjs` 全文
— ENGINES_TO_SYNC 配列に 454 を追加する具体的位置
9. `webapp_client/src/cockpit-main.tsx` 全文
— 既存の副作用 import 群(442/443/444/445/449/450/451/452/453)の直後に
454 を追加する具体的位置(failure_patterns #33 対策・必須)
10. `300_ui/302_spa_bridge.js` 全文
— bootstrap 構造 / runDividendMixSimulation の実装パターン
— `_scrubInfinityForJSON_(value)` 汎用ヘルパの使い方(MAS-066 PR #402 で確立)
11. `000_infra/002_constants.js` 全文(特に L1-200)
— Constants.INCOME_TAX_BRACKETS / TAX_RATES.brackets / DIVIDEND_TAX_BRACKETS / getParam
— Constants.MAS071_DEFAULTS の追加位置(既存定数末尾推奨)
12. `docs/dev/dev_mas-057_solo_ceo_cockpit.md` v2.2(特に Step 6.9-extension 配置原則)
13. `docs/dev/dev_mas-058_required_revenue_solver.md` v2.1(特に §配置原則・Step 5)
14. `docs/dev/dev_mas-066_dividend_mix_optimizer.md` v1.2(特に注意事項 #10 / #14・実装サマリ)
15. `docs/_internal/failure_patterns.md` #18-#20 / #25 / #26 / #29 / #31 / #33
## 実装対象(Phase 1 → Phase 2 → Phase 3 の順)
### Phase 1: 計算エンジン Pure Function(Sonnet → Opus)
1. `400_domain/454_compensation_strategy_engine.js` 新規作成
(IIFE 名前空間 CompensationStrategyEngine・約 350 行):
- calcAllApproaches(input) — 4 アプローチ + TC + 推奨レンジを一括返却
- calcTheoreticalCompensation(input) — TC = (V × R) 内積
- calcApproachA(input, tc) — max(L_min, min(TC, OP_pre))
- calcApproachB(input) — OP_pre - (Buffer + OP_pre × R_i) + Number.isFinite ガード
- calcApproachC(input, tc) — min(scan(L_min, TC, step=12 万), TC)
- calcApproachD(input, tc) — TC × (1 - R_i) を OP_pre - TargetProfit でクランプ
- 内部ヘルパ(末尾 _ 付き private):
- _scanOptimalCompensation_(input, tc) — L_min〜TC を step 12 万でスキャン
- _evalNetTotal_(candidate, input) — 個人手残り + 法人手残り合算
- _calcSalaryDeduction_(income) — 給与所得控除(年収 850 万超で 195 万固定)
- _calcCorporateTax_(profit, brackets) — 法人税累進
- _validateRatios_(input) — R_d + R_i + R_m === 1.0 確認
- _calcRecommendedRange_(input, tc) — 4 アプローチから min/max/median 算出
- 末尾に window 露出ラッパ(GAS 側では window 未定義のため安全)
2. `000_infra/002_constants.js` 拡張:
- Constants.MAS071_DEFAULTS = { vDelivery, vInvestment, vManagement,
lMin, bufferMonths, targetProfit, scanStep } を新設
(既存 INCOME_TAX_BRACKETS / TAX_RATES.brackets / DIVIDEND_TAX_BRACKETS の直後)
3. 03_sys_params の MAS071_* 7 キー追加
(`100_config/101_sys_config.js` の DDL or 8XX_migration_mas071_strategy_seed.js)
4. 900_test/901_test_runner.js に F71-01〜F71-16 単体テスト
(エッジケース 16 件 + Baseline 数値検証 + R_i 感度分析 5 ケース)
### Phase 2: React Panel + UI(Opus)
5. `webapp_client/src/cockpit/CompensationStrategyPanel.tsx` 新規作成
(約 500 行・MAS-058 RequiredRevenuePanel.tsx を参考実装):
- 稼働率入力(3 連動 number 入力 + 残量自動調整 adjustRatios ヘルパ)
- 市場価値カスタマイズ(V_d / V_i / V_m 数値入力・default は MAS071_*)
- 制約値カスタマイズ(L_min / Buffer / TargetProfit)
- 理論報酬額 TC 単独大型表示(税務調査防衛根拠)
- 4 アプローチ比較棒グラフ(recharts BarChart + ReferenceArea で推奨レンジ)
- 推奨額決定 UI(4 アプローチから選択 or 単純平均 or カスタム)
- Disclaimer(税理士・社労士の個別助言代替不可)+ 法人税法施行令 70 条 1 号の引用
6. `webapp_client/src/CockpitApp.tsx` を変更:
- <RequiredRevenuePanel /> の直後に <CompensationStrategyPanel /> を 1 行追加
(MAS-058 配置原則「現状把握↑ vs 目標逆算↓」境界の更に下に配置)
7. `webapp_client/scripts/sync-engines.mjs` を変更:
- ENGINES_TO_SYNC 配列に '454_compensation_strategy_engine.js' を追加
(既存 442/443/444/445/449/450/451/452/453 と並列)
8. `webapp_client/src/cockpit-main.tsx` を変更(**failure_patterns #33 必須対策**):
- 既存の副作用 import 群(442〜453)の直後に
`import './engines/454_compensation_strategy_engine.js';` を追加
- 忘れると Vite tree-shaking で bundle から除外され window.CompensationStrategyEngine が undefined
### Phase 3: GAS 側 SPA bridge 拡張(Sonnet)
9. `300_ui/302_spa_bridge.js` 拡張:
- bootstrap に MAS071_* 7 キー追加(既存 F66_* / F57_* と並列)
- runCompensationStrategySimulation(input) 関数追加
(CompensationStrategyEngine.calcAllApproaches を呼出 →
_scrubInfinityForJSON_ で scrub → クライアントへ返却)
10. `800_ops/8XX_migration_mas071_strategy_seed.js` 新規作成(任意・番号は次空き):
- MAS071_* 7 キーシーダー(MAS-066 PR #402 の 815_migration_f66_dividend_seed.js 同パターン)
## 制約
- `400_domain/454_compensation_strategy_engine.js` は **純粋関数のみ**
(SpreadsheetApp / UrlFetchApp / Utils / Constants 直接依存禁止・MAS-057 注意事項 #14 準拠)
- 既存の 442〜453 ファイルは **変更しない**
(MAS-057 / MAS-066 / MAS-058 等の既存 spec / 実装に影響を与えない)
- `appsscript.json` は **変更しない**(failure_patterns #26 遵守・OAuth スコープ追加不要)
- 4 アプローチ A/B/C/D は **対称な純粋関数** として実装
(引数構造・戻り値型・null フォールバック・Number.isFinite ガードを全 4 関数で揃える)
- `webapp_client/src/cockpit-main.tsx` への副作用 import 追加を **絶対に忘れない**
(failure_patterns #33・MAS-066 PR #402 で同問題が発生済)
## 動作確認
1. dev で push:dev → cockpit を開いて MAS-058 panel 直下に MAS-071 panel が表示されること
2. 稼働率合計 ≠ 100% で赤枠警告が表示されること(エッジケース #1)
3. 齋藤 Baseline(OP_pre 2,000 万 / R = 60:30:10)で TC = 1,040 万・推奨レンジ 728-1,250 万
4. R_i = 100% でアプローチ B / D が 0 円になり警告表示(エッジケース #8)
5. ブラウザ console で `console.log(window.CompensationStrategyEngine)` で undefined でないこと
(failure_patterns #33 確認)
6. 4 アプローチ比較棒グラフが正しく描画され、推奨レンジ ReferenceArea がハイライトされること
7. 推奨額決定 UI で「アプローチ A 採用」をクリックすると MAS-057 月額ドロップダウンが
1,040 万 / 12 = 約 87 万に更新されること(v1 では localStorage 経由・直接結合は避ける)
8. F71-01〜F71-16 単体テスト全 PASS(GAS エディタから testRunner.runAll を実行)
9. Go なら push:prod → prod cockpit でも同等動作確認
## デプロイ
1. dev で push:dev → 動作確認 → コミット
feat(MAS-071): 稼働率連動型役員報酬シミュレーター(4 アプローチ統合・MAS-057 cockpit 拡張)
2. PR 作成(main 側ワークスペース)
3. ユーザー承認後 main マージ → prod 自動デプロイ
## failure_patterns チェック(必読・実装直前に再確認)
- **#18-#20**: SocialInsuranceTierEngine / PersonalTaxEngine / Constants.MAS071_DEFAULTS
の関数名・シグネチャ・行番号は Read で裏取り済か(MAS-057 のリファクタによる行ずれに注意)
- **#25**: calcApproachA / B / C / D を対称な純粋関数として実装
(引数構造・戻り値・null フォールバック・isFinite ガードが揃っているか)
- **#26**: appsscript.json は変更なし(OAuth スコープ追加なし)
- **#29**: calcApproachB の OP_pre × R_i に Number.isFinite ガード必須・
_scrubInfinityForJSON_ を runCompensationStrategySimulation 戻り値で経由
- **#31**: 本仕様書起票時に Phase 1-A-pre 適用済(445 → 454 振直し経緯を変更履歴に記録)
- **#33**: webapp_client/src/cockpit-main.tsx への副作用 import 追加・実装後に
`console.log(window.CompensationStrategyEngine)` で undefined でないこと確認
推奨実行モデル
| 工程 | 推奨モデル | 根拠 |
|---|---|---|
Phase 1 Step 1 454_compensation_strategy_engine.js 新規作成(4 アプローチ対称実装) | Claude Opus 4.7 (1M context) | 4 アプローチの対称性 + MAS-057 PersonalTaxEngine 統合 + アプローチ C スキャン解設計の複合判断 |
Phase 1 Step 2 Constants.MAS071_DEFAULTS 追加 | Claude Sonnet 4.6 | 既存 INCOME_TAX_BRACKETS / DIVIDEND_TAX_BRACKETS と並列対称な定数追加 |
| Phase 1 Step 3 03_sys_params 7 キー追加 | Claude Haiku 4.5 | パターン化されたキー定義 |
| Phase 1 Step 4 F71-01〜F71-16 単体テスト | Claude Sonnet 4.6 | エッジケース 16 件 + Baseline + 感度分析の期待値検証 |
Phase 2 Step 5 CompensationStrategyPanel.tsx 新規作成 | Claude Opus 4.7 (1M context) | React 独立パネル + 稼働率連動 UI + recharts 棒グラフ + 推奨額決定 UI の総合判断 |
Phase 2 Step 6 CockpitApp.tsx に panel 挿入 | Claude Haiku 4.5 | 1 行追加・配置原則は spec で確定済 |
Phase 2 Step 7 sync-engines.mjs に 454 追加 | Claude Haiku 4.5 | 既存パターン流用 |
Phase 2 Step 8 cockpit-main.tsx 副作用 import 追加 | Claude Haiku 4.5 | 1 行追加(failure_patterns #33 必須対策・忘れず実施) |
Phase 3 Step 9 302_spa_bridge.js 拡張 | Claude Sonnet 4.6 | bootstrap 拡張 + runCompensationStrategySimulation + _scrubInfinityForJSON_ 経由 |
Phase 3 Step 10 マイグレーション 8XX_migration_mas071_strategy_seed.js(任意) | Claude Haiku 4.5 | 800_ops 既存パターン流用(MAS-066 815 と同パターン) |
| 仕様書レビュー(任意) | Gemini 3 Pro Preview + Deep Think | 第三者税務妥当性検証 + 4 アプローチ整合性 + MAS-058 / MAS-066 連携の妥当性確認 |
変更履歴
| 日時 | バージョン | 変更内容 |
|---|---|---|
| 2026-05-02 | v1.2 (前提条件 3 枠分割 + 制約条件枠新設 + 詳細設定整理 + minimumMonthlySalary 削除 — F-57 大規模 UI 再構成 dev @230 反映) | MAS-071 戦略シミュレーター UI が大規模再構成された (commits 60fd334 / 6020bb4 / 5e43d1c / f0a505b / eb33645 / f6ec915 / c4aadfe / 240c74c)。主要再構成: (1) 前提条件を 3 枠分割 (commit 60fd334): 旧「前提条件 16 項目をフラットに表示」→ P/L 前提条件 / B/S 前提条件 / C/F 前提条件 の 3 つのセクションに整理 (会計諸表に対応)。 / (2) 制約条件枠を新設 (commit 6020bb4): lMin (生活防衛ライン・最低必要額面年収) / bufferMonths (法人運転バッファ月数) / targetProfit (融資対策目標利益) を独立した「制約条件」枠として分離。これにより 4 アプローチの計算根拠が UI 上で明示される。 / (3) 詳細設定 (折りたたみ) に旧 AssumptionsPanel から移管 (commit 5e43d1c): 旧 AssumptionsPanel.tsx (前提条件 16 項目を独立パネルで表示) を削除 → MAS-071 panel の 「詳細設定」(折りたたみ) に移管・default 折りたたみで UI 簡素化。 / (4) 現在月額役員報酬 (currentMonthlySalary) 入力追加 (commit f0a505b): 4 アプローチ比較の CURRENT 列基準値として活用。 / (5) 入力セクションを 個人/法人 タブ + アプローチ切替に再構成 (commit eb33645): アプローチ切替タブ [現状] [A 生活防衛] [B 内部留保] [C 税務最適] [D 融資対策] [平均] をクリックすると MAS-071 推奨年額 → 月額 (5 万円単位) 反映 + 賞与 = 0 / 個人タブ: 月額報酬 / 賞与 / 社宅 / 個人生命保険 / 配当 / 法人タブ: 月商 / 共済 / 法人生命保険。削除項目 (sub 側 draft 廃止判断): (1-7) minimumMonthlySalary フィールド (commit 240c74c) → (a) 完全削除。理由: lMin (最低必要額面年収・制約条件枠に新設) と意味重複・MAS-071 計算ロジック側は lMin のみを参照しており minimumMonthlySalary は dead state だった。削除範囲: CockpitInputs 型 / DEFAULT_INPUTS / AssumptionsStore / ScenarioStore / CompensationStrategyPanel の NumberRow。 / (1-8) MAS-071 詳細設定からの重複 3 項目削除 (commit f6ec915・代表月額単価 / 売上貢献稼働率 / 変動費比率) → (a) 仕様書修正のみ。理由: MAS-071 の前提条件枠 (P/L 前提条件) に同等項目が既に存在し UI 上で重複していたため統合。 / (1-9) MAS-071 詳細設定からの初年度フラグ + 初年度稼働月数削除 (commit c4aadfe) → (b) 将来再開・section 末尾メモ。理由: 通年 12 ヶ月 default 運用に統一・初年度短縮シナリオは将来必要なら再追加 (M&A 直前期 / 設立年度短縮対応 / 決算月変更時に必要性発生)・短縮事業年度シナリオ復活時の入力エンジン拡張ポイントは intensityFactor 周辺に保存。MAS-071 spec の今後の扱い: (1) 4 アプローチ計算ロジック (A 生活重視 / B 内部留保 / C 税務最適 / D 融資対策 + AVG) は v1.0 / v1.1 から不変・本仕様書を SSoT として維持・(2) UI 仕様は v1.2 で「前提条件 3 枠 + 制約条件枠 + 詳細設定 + 個人/法人タブ + アプローチ切替」に進化 (concierge layer)・(3) currentMonthlySalary 入力は cockpit 全体の SSoT として MAS-057 / MAS-355 (資本効率ダッシュボード) でも参照される共通入力。MAS-355 との関係: MAS-355 Rule of 40 計算で MAS-071 の revenueMonthly (月商) と cogsRate (変動費比率) と operatingProfit (4 アプローチ別計算) を参照する設計が確立済 → 本 v1.2 の「前提条件 3 枠分割」は MAS-355 にとっても前提条件の所在が明確になる改善。docs-only PR で prod 自動デプロイへの影響なし。最終更新日 2026-05-02。 |
| 2026-05-01 | v1.1 (PR #459 反映・UX 細部改善 + シナリオ payload 拡張 + AVG 表示) | MAS-071 v1.0 (PR #457) の後続 PR #459 (commit 8f45430) で MAS-057 Step 7 (cockpit 拡張パネル群) と並行して MAS-071 panel にも UX 改善が適用されたため v1.1 として整合追従。(2-A) UX 細部改善: (a) アプローチ A ラベル「生活防衛」→「生活重視」/ (b) 投資業務 sublabel に「事業開発」追記 / (c) 月商 → 「100% 稼働時の月額単価」に置換 (派生値で revenueMonthly 連動) / (d) 月商の右隣に「× 12 ヶ月 = 年商」表示 / (e) 業務横帯下に「貢献額合計」+「理論報酬額 (労働強度加味)」表示 / (f) 4 アプローチ計算式は棒グラフ直下 1 つの details で一括展開 (アプローチ別 details 撤廃) / (g) 推奨額決定 UI 撤廃 (Step 7-A ApproachComparisonPanel で代替表示) / (h) 法人税ラベル「法人税 (累進)」→「法人税等 (国税+地方税)」+ 小フォント 累進 注記。(2-B) シナリオ payload 拡張: v1.0 (ratios (4 軸) / 各 vXxx / lMin / bufferMonths / targetProfit / intensityFactor / monthlyRateAtFull / cogsRate / fixedCostMonthly) に加え、approachByYear[6] (Y0-Y5 各年のアプローチ選択・SoloFinancialStatementsPanel 用) + y0Months (Y0 事業継続月数・1-12) を追加。state lift: CockpitApp に保持し CompensationStrategyPanel + SoloFinancialStatementsPanel 両方に props 配布。(2-C) 4 アプローチ平均 (AVG) 表示: ApproachComparisonPanel (MAS-057 Step 7-A) に 5 列目「4 アプローチ平均」を追加 (result.recommended.average を表示するだけで計算ロジックは v1.0 から不変)。「実装が spec を先行 → spec を整合追従」のパターン累計 13 例目 (MAS-057 v2.4 と同 PR・MAS-067 / MAS-071 と並行)。docs-only PR で prod 自動デプロイへの影響なし。 |
| 2026-05-01 | v1.0 (実装完了反映・PR #457) | MAS-071 を main 側 PR #457 (commit 16fdffb) で実装完了。Spec を v0.1 Draft → v1.0 Implemented に整合追従。8 領域の実装乖離を反映: (1) 4 軸モデル拡張 (3 軸 → 4 軸・営業マーケティング軸新設・default 配分 40/20/30/10%) / (2) 労働強度係数 intensityFactor 追加 (0.5-2.5・default 1.0・160h/月相当) / (3) 月商 → 100% 稼働時月額単価入力に変更 (月商は派生値) / (4) Phase 5 シナリオ保存機能 (40_mas071_scenarios タブ + 4 API + 前回選択自動復元) / (5) 稼働率独立入力 (合計 100% 警告のみ・連動調整は撤回) / (6) UX 改善 (日本語化・千円カンマ表示・cockpit 最上部配置) / (7) 法人運転バッファ解釈の明確化 (固定費のみ × 月数・役員報酬込みは月数で調整) / (8) sys_params 7 → 8 キー (MAS071_VS_SALES 追加・マイグレーション 821 で冪等シード)。実装規模: 400_domain/454_compensation_strategy_engine.js + webapp_client/src/cockpit/CompensationStrategyPanel.tsx (約 700 行) + 単体テスト F71-01〜F71-16 (16 件)。「実装が spec を先行 → spec を整合追従」のパターン累計 11 例目。docs-only PR で prod 自動デプロイへの影響なし。 |
| 2026-04-30 | v0.1(初版・Draft) | 初版作成。ID 採番衝突回避経緯: ユーザー初期提案ファイル名 400_domain/445_compensation_strategy_engine.js は既存 MAS-058 (445_required_revenue_solver.js) で使用済のため衝突発覚。grep -nE '400_domain/45[0-9]_' docs/dev/*.md で全使用状況を確認した結果、440〜453 は全て使用済(442 social_insurance / 443 corporate_housing / 444 per_diem / 445 required_revenue / 449 dividend_mix / 450 ai_tool_roi / 451 multiyear_planner / 452 regulation_generator / 453 psf_profitability)であり、次空き番号 454_compensation_strategy_engine.js に振直し。案件 ID は MAS-071(MAS-066/067/068/069 の FP&A 系列直近・MAS-070 マイクロ法人 棄却済の次空き番号)。failure_patterns #31 対策(dev_spec_prompt_template v1.10 Phase 1-A-pre)の実適用例。14 セクション全網羅: 概要 + 目的 + 現在のコード(MAS-057 PersonalTaxEngine / SocialInsuranceTierEngine 利用関数 + MAS-058 配置原則 + MAS-066 _scrubInfinityForJSON_ 流用)+ 修正方針 4 Step(Step 1 計算エンジン Pure Function / Step 2 React Panel + UI / Step 3 MAS-057 cockpit 統合 / Step 4 03_sys_params 7 キーシード)+ 影響範囲(新規 2 + 任意 1 / 変更 6 / 変更なし 4)+ 注意事項 15 件(#31 ID 採番 / #18-#20 命名造語 / #25 並列対称性 / #26 oauthScopes / #29 Infinity / #33 SPA 副作用 import / 不相当に高額判定リスク / 稼働率自己申告 / 市場価値ベンチマーク / アプローチ B 負値 / アプローチ D 達成不可 / 法令変更年次更新 / Pure Function 厳格化 / 退職金算定基礎 / 3 ヶ月ルール)+ エッジケース 16 件(稼働率合計 / V ゼロ / 全 V ゼロ / OP_pre 負 / TC > OP_pre / L_min > OP_pre / B 負値 / R_i = 100% / D 達成不可 / C 凸性破れ / 4 アプローチ全 0 / Infinity / マイナスゼロ / 役員社宅併用 / 配偶者役員化 / 事前確定届出給与)+ 実データ検証 6 本(齋藤 Baseline / R_i 感度 / 4 アプローチ差分極端 / MAS-057 数値整合 / F71-01〜F71-16 / 税務調査防衛資料)+ 関連ドキュメント 14 件(MAS-057/058/066/067/141/061/218 + failure_patterns + dev_spec_prompt_template + CLAUDE.md + PRD + 法人税法施行令 70 条 + Gemini/Claude 調査結果)+ 人間検討事項 12 件(稼働率自己申告 / 市場価値ベンチマーク / 4 アプローチ重み付け / 配偶者役員化 / 退職金 NPV / 役員社宅 / 3 ヶ月ルール UI / 賞与寄せトレードオフ / 業績悪化改定 / 賞与寄せ双方向 / 多通貨 / 税務調査防衛資料自動生成)+ 実装プロンプト(Claude Opus 4.7 向け・事前調査 15 / 実装対象 10 / 動作確認 9 / failure_patterns チェック 6)+ 推奨実行モデル(Phase 1-3 + テスト + マイグレーション + レビュー)。実装着手は MAS-067 マルチイヤー Phase B-4 配当連携完了後を推奨(MAS-067 / MAS-066 / MAS-058 が安定した cockpit 上に統合)。今回のセッションで Gemini Deep Think レビューは実施せず(任意・別 PR で実施可能)。docs-only PR で prod 自動デプロイへの影響なし。 |
仕様書作成プロンプト
再現性・監査性のため、本仕様書を生成する際に Claude Code(Opus 4.7・1M context)に投入したプロンプトの全文を記録する(dev_spec_prompt_template v1.10 §Phase 2 必須セクション準拠)。
注記: Gemini 調査結果 / Claude 調査結果は冗長なため要約のみ記載。full text は main 側 PR の
tasks/prompts/task_F-43.gemini.md/task_F-43.mdで保管推奨。両ファイルは sub ワークスペース(本 PR)で初期投入したものを main 側でレビュー後にマージ予定。
展開して表示
あなたは GAS 会計システム (bizlp-gas-accounting) のシニア開発者兼仕様書ライターです。
## タスク
案件 ID **MAS-071**「稼働率連動型役員報酬シミュレーター(4 アプローチ統合・MAS-057 cockpit 拡張)」の開発仕様書を作成し、`/Users/ts_kuma/projects/my-gas-project-doc/docs/dev/dev_mas-071_compensation_strategy_simulator.md` に保存してください。
## 案件概要
- **Phase**: P2 / **★**: ★★★ / **Layer**: 🧠 Domain (純粋関数エンジン) + 🎨 UI (React コンポーネント)
- **位置付け**: 既存 **MAS-057 Solo-CEO Visual Cockpit** の拡張機能として配置
- **目的**: 1 人社長が役員報酬を決定する際、単なる「節税」だけでなく「自身の稼働割合(時間の使い方)」と「4 つの財務的アプローチ(生活防衛・内部留保・税務最適化・融資対策)」を統合的に評価し、最適な報酬額をシステマティックに導き出す
## ID 採番経緯 (failure_patterns #31 適用)
- ユーザー初期提案ファイル名: `400_domain/445_compensation_strategy_engine.js`
- **衝突発覚**: 445 は既存 MAS-058 (`445_required_revenue_solver.js`) で使用済
- **振直し**: 次空き番号 **`454_compensation_strategy_engine.js`** に変更 (440〜453 は全て使用済)
- 案件 ID は **MAS-071** (MAS-066/067/068/069 の FP&A 系列直近・MAS-070 マイクロ法人 棄却済の次)
## ビジネスロジック (4 アプローチ統合計算)
### 入力パラメータ
- **OP_pre**: 限界利益 = 売上 - 固定費 (役員報酬控除前)
- **稼働率** (合計 100%・UI で連動制御):
- **R_d** (Delivery): 直接業務の稼働率 (例: 60%)
- **R_i** (Investment): 投資業務 R&D 等の稼働率 (例: 30%)
- **R_m** (Management): 管理業務の稼働率 (例: 10%)
- **市場価値** (default 値 + カスタマイズ可):
- **V_d**: 直接業務の市場年収 (例: 1,000 万)
- **V_i**: 投資業務の市場年収 (例: 1,200 万)
- **V_m**: 管理業務の市場年収 (例: 800 万)
- **L_min**: 個人の必要生活費から逆算した最低額面年収 (default 480 万)
- **Buffer**: 法人に残すべき最低固定バッファ (default 月商 3 ヶ月分)
- **TargetProfit**: 融資対策用の目標法人利益 (default 600 万)
### 計算式
1. **理論報酬額 TC** = (V_d × R_d) + (V_i × R_i) + (V_m × R_m)
- 例: (1000 × 0.6) + (1200 × 0.3) + (800 × 0.1) = 600 + 360 + 80 = **1,040 万**
2. **アプローチ A (ボトムアップ・生活防衛)** = max(L_min, min(TC, OP_pre))
- 個人の最低必要額を確保した上で TC と OP_pre の小さい方
3. **アプローチ B (トップダウン・内部留保)** = OP_pre - (Buffer + OP_pre × R_i)
- R&D 比率を内部留保 + バッファとして残す
4. **アプローチ C (税務最適化)** = min(C_opt, TC)
- **C_opt** は既存 `SocialInsuranceTierEngine` (442_*) + `PersonalTaxEngine` (444_*) を再利用して**法人 + 個人の合算手残りが最大化する金額をスキャン探索**
- 範囲は L_min〜TC、step は 12 万円 (月 1 万) 程度で十分
5. **アプローチ D (融資対策)** = TC × (1 - R_i)
- R&D 部分は法人内部留保へ。**ただし `OP_pre - 報酬 >= TargetProfit`** を満たすようクランプ (報酬を上限から減らす方向)
## 必読ファイル (調査して固有名詞を確定・failure_patterns #18-#20)
実装の前に以下のファイルを `Read` で参照し、関数名・列名・定数名を確実に存在するものに揃えてください:
1. `docs/_internal/dev_spec_prompt_template.md` — 仕様書 14 セクションテンプレート (必須準拠)
2. `docs/_internal/failure_patterns.md` — #18-#33 全失敗パターン
3. `docs/dev/dev_mas-057_solo_ceo_cockpit.md` — 親案件・連携先 (Step 6 cockpit 構造・SocialInsuranceTierEngine / PersonalTaxEngine の利用パターン参照)
4. `docs/dev/dev_mas-058_required_revenue_solver.md` — 同型 cockpit 統合パネルの実装パターン参照 (RequiredRevenuePanel の配置原則)
5. `docs/dev/dev_mas-066_dividend_mix_optimizer.md` — `_scrubInfinityForJSON_` 等の同型実装パターン
6. `CLAUDE.md` — コーディング規約・名前空間ルール
## アーキテクチャ要件
- **計算ロジック**: `400_domain/454_compensation_strategy_engine.js` に新規・**Pure Function** (`CompensationStrategyEngine` 名前空間・IIFE パターン・既存 449/450/451/452/453 と並列対称)
- **クライアント実行**: GAS レイテンシ排除のため計算は React (TypeScript) 側で実行・engine は同型を `webapp_client/src/engines/` に sync-engines.mjs 経由でコピー (MAS-057 / MAS-066 と同パターン)
- **既存エンジン再利用**:
- `SocialInsuranceTierEngine` (推定 `400_domain/442_*.js`) — 標準報酬月額計算
- `PersonalTaxEngine` (推定 `400_domain/444_*.js`) — 個人所得税・住民税計算
- 両者とも MAS-057 Phase 1 で実装済 (Read で実在確認すること)
- **配置先**: 「目標逆算レイヤー」(MAS-058 健全性診断パネルの直下) を推奨。配置原則は MAS-057 spec v2.2 「現状把握↑ vs 目標逆算↓」境界に準拠。**独立タブ案 vs 統合パネル案** の両者を spec で比較し、推奨を独立 React コンポーネント `CompensationStrategyPanel.tsx` として MAS-058 直下に配置と提案
## UI/UX 要件
- **稼働率入力**: R_d / R_i / R_m の合計が 100% になるよう 3 連動スライダー or 3 つの number 入力 + 残量自動調整 (どれか変更すると他 2 つが比例配分で再計算)
- **4 アプローチ比較**: 棒グラフ (recharts or SVG 自前描画) で並列表示 + 推奨レンジ (A〜C 範囲) をハイライト
- **理論報酬 TC**: 単独表示 (税務調査時の「不相当に高額」防御の根拠として)
- **設定変更**: V_d / V_i / V_m / L_min / Buffer / TargetProfit を `03_sys_params` で `MAS071_*` キーとして可変設定 (default 値も明示)
## 仕様書フォーマット要件 (14 セクション)
`dev_spec_prompt_template.md` 準拠。ユーザー要望の出力構成 (1. 概要・目的 / 2. ビジネスロジック・計算式定義 / 3. UI/UX設計 / 4. システムアーキテクチャ / 5. エッジケース・バリデーション / 6. テスト要件) は 14 セクション内に収まるように対応 (例: 「概要・目的」は §概要 + §目的、「ビジネスロジック」は §修正方針 / §現在のコード で扱う)。
含めるべき内容:
- フロントマター (id: MAS-071, aliases: [], type: Story, status: Draft)
- 概要テーブル (案件 ID / カテゴリ / Phase / 優先度 / 所要時間 / 前提案件: MAS-057 + MAS-058 / 後続案件: MAS-067 マルチイヤー化 v2)
- 目的 / 修正方針 / 実装スコープ / Step 分割 (Phase 1 = 計算エンジン Pure Function / Phase 2 = React Panel + UI / Phase 3 = MAS-057 cockpit 統合)
- 注意事項
- **#31 ID 採番衝突回避**: 445 提案 → 454 振直し経緯を変更履歴 + 注意事項両方に記載
- **#18-#20 命名造語**: `SocialInsuranceTierEngine` / `PersonalTaxEngine` の正確な関数名は実 spec / コードで確認
- **#25 並列実装対称性**: 4 アプローチ (A/B/C/D) を対称な計算関数として実装 (`calcApproachA` / `B` / `C` / `D`)
- **#26 oauthScopes 部分宣言禁止**
- **#29 V8 → Java Infinity null**: アプローチ B で `OP_pre × R_i` が極端値の場合の `Number.isFinite` ガード必須
- **#33 SPA 副作用 import 漏れ**: `webapp_client/scripts/sync-engines.mjs` への新エンジン追加忘れ防止チェックリスト
- 「不相当に高額」判定リスク・税務調査での防衛論理 (理論報酬 TC = ロールバリュー積算が法人税法施行令 70 条 1 号「同種事業類似規模 0.5〜2 倍」の正当化根拠となる旨を明示)
- エッジケース表 (12 件以上)
- 稼働率合計 ≠ 100% / V_d/V_i/V_m に 0 / OP_pre が負 (赤字) / TC > OP_pre / L_min > OP_pre / Buffer > OP_pre / R_i = 100% (全部 R&D) / アプローチ B が負値 / アプローチ C 探索でグローバル最適に達しない / アプローチ D で TargetProfit 達成不可 / 4 アプローチが全て 0 円 / Infinity 発生 / マイナスゼロ / 役員社宅 (MAS-057 連携) で実質可処分が変わる / 配偶者役員化 (MAS-066 配当 と独立判定) / 事前確定届出給与の賞与寄せパターン
- 人間が検討すべき事項 (10 件以上)
- 稼働率自己申告の客観性担保 / 市場価値の業種別ベンチマーク更新頻度 / 4 アプローチ重み付けの自動 vs 手動 / 配偶者役員化の組込タイミング (v2+) / 退職金算定基礎 (月額報酬ベース) との整合 / 定期同額給与改定タイミング 3 ヶ月ルール表示 / 事前確定届出給与の社保削減 vs 退職金枠縮小トレードオフ / 業績悪化改定事由の厳格性 UX / 賞与寄せ型シミュレーション拡張 (v2) / 多通貨化時の市場価値外貨対応 (out of scope MAS-064 連動)
- 推奨実行モデル (Step ごとに Haiku/Sonnet/Opus)
- 関連ドキュメント (MAS-057 / MAS-058 / MAS-066 / MAS-067 / MAS-141 共済 / failure_patterns / dev_spec_prompt_template / Gemini 調査結果 / Claude 調査結果)
- 開発プロンプト (Claude Code 向け実装指示・行頭 4 スペースインデント)
- 変更履歴 (v0.1 初版 + ID 採番衝突回避経緯)
- 末尾に `<details><summary>展開して表示</summary>` ブロックでこのプロンプト全文を記録
## アウトプット
ファイル: `docs/dev/dev_mas-071_compensation_strategy_simulator.md`
Step 分割で順次 Write/Edit:
1. Step 2-1: 骨格 Write (フロントマター + 14 H2 見出し)
2. Step 2-2: 概要〜注意事項 Edit
3. Step 2-3a: エッジケース 12 件以上 + 人間検討事項 10 件以上 Edit
4. Step 2-3b: 開発プロンプト + 変更履歴 + 推奨実行モデル Edit
5. Step 2-4: `<details>` プロンプト全文記録 Edit (※ Gemini / Claude 調査結果は冗長なため、要約 + 「main 側 PR で full text を保管推奨」と注記する)
最終確認として `wc -l` で行数を測定し報告してください (期待: 500-700 行・4 アプローチ + UI 設計 + tax/social insurance 連携で MAS-066 / MAS-058 並み)。
Gemini 調査結果(要約・full text は main 側 PR tasks/prompts/task_F-43.gemini.md 参照)
Gemini 3 Pro Preview + Deep Think による「役員報酬決定の上位視点」リサーチ。主な示唆:
- 役員報酬は「節税」「内部留保」「融資対策」「生活防衛」の 4 軸で評価すべきというフレーム提唱
- 稼働率 × 市場価値の積算(ロールバリュー)を「不相当に高額」防衛根拠として用いる先例(OBC 経理コラム / TKC 解説等)の整理
- アプローチ B(内部留保)と D(融資対策)の併用時は法人留保が二重カウントされる点に注意
- アプローチ C(税務最適化)の凸性破れ問題と multi-start scan の必要性
full text は main 側 PR でレビュー後に
tasks/prompts/task_F-43.gemini.mdとして保管。
Claude 調査結果(要約・full text は main 側 PR tasks/prompts/task_F-43.md 参照)
Claude Opus 4.7 による「4 アプローチ統合計算式の設計」リサーチ。主な示唆:
- 計算式の対称性(A/B/C/D を同一引数構造の対称関数)が将来の拡張容易性を担保する
- アプローチ C のスキャン解は「社保等級境界」と「個人累進境界」が複合する非凸関数になる可能性高い → step 12 万で許容、v2 で multi-start scan 検討
- 推奨レンジ算出は「min(A,B,C) 〜 max(A,B,C)」とし、D は別軸表示(融資対策の独立性を視覚化)
- 4 アプローチ比較棒グラフは recharts BarChart + ReferenceArea で推奨レンジハイライトが最も読みやすい
full text は main 側 PR でレビュー後に
tasks/prompts/task_F-43.mdとして保管。