MAS-059: 1 人コンサルタント 非連続成長シミュレーター(4 レバー成長戦略:Pricing / Product / Human / Capital)
概要
| 項目 | 内容 |
|---|---|
| 案件 ID | MAS-059 |
| 案件名 | 1 人コンサルタント 非連続成長シミュレーター(4 レバー成長戦略) |
| カテゴリ | シミュレーション・成長戦略・FP&A |
| 優先度 | P2 ★★★(一人法人 SMB の天井突破支援・MAS-057 cockpit の上位レイヤー) |
| 所要時間 | 約 1.5 ヶ月(週 10h 前提・Phase 1-3 計) |
| 実装ステータス | 📝 仕様書段階・実装未着手(v2.0 = 2026-05-01 全面 scope reset) |
| 対象ファイル(新規) | 400_domain/446_growth_strategy_engine.js(純粋関数 4 レバーシミュレーター・約 500 行)/ webapp_client/src/cockpit/GrowthStrategyPanel.tsx(左 4 スライダー + 右 2 チャート UI・約 700 行) |
| 対象ファイル(変更) | webapp_client/scripts/sync-engines.mjs(ENGINES_TO_SYNC に 446 追加)/ webapp_client/src/cockpit-main.tsx(副作用 import 追加)/ webapp_client/src/cockpit/calc.ts(calcGrowthStrategy 公開)/ 300_ui/302_spa_bridge.js(bootstrap に sys_params 配信追加)/ 100_config/101_sys_config.js(03_sys_params 12 キーシード)/ 000_infra/002_constants.js(MENU_DEFINITION に「🚀 成長戦略シミュレーター」追加) |
| 新規シート | なし(panel-local 入力 + 既存 03_sys_params 拡張のみ) |
新規 03_sys_params キー | F59_HOURS_PER_MONTH_SOFT_LIMIT(default 160 h)/ F59_HOURS_PER_MONTH_HARD_LIMIT(default 200 h)/ F59_PRICING_ELASTICITY(default 0.7・価格弾力性)/ F59_PRODUCTIZATION_BOOST_MULTIPLIER(default 1.5・最大生産性倍率)/ F59_HUMAN_LEVERAGE_OVERHEAD_RATIO(default 0.30・人員追加時の管理コスト比率)/ F59_CAPITAL_REINVEST_ROIC_HURDLE(default 0.15・再投資 ROIC 閾値)/ F59_CAPITAL_MNA_PREMIUM_DEFAULT(default 5・M&A EBITDA 倍率)/ F59_CAPITAL_DIVIDEND_HURDLE_RATE(default 0.05・配当機会費用)/ F59_BUDGET_OVER_THRESHOLD_RATIO(default 0.95・予算超過警告閾値)/ F59_LIMIT_PROFIT_STACKED_BAR_BASE_LABEL(default "Y0 ベースライン")/ F59_HOURS_LINE_BASELINE(default "現状稼働")/ F59_FORECAST_HORIZON_YEARS(default 5)の計 12 キー |
| 前提案件 | MAS-057 Phase 3 cockpit ✅ 完了 (PR #379/#394/#454/#459) = SPA 基盤 + 副作用 import 規約 + sync-engines.mjs / MAS-058 必要年商ソルバー ✅ Step 4 完了 (PR #401) = RequiredRevenueSolver.solveRequiredRevenue / MAS-067 マルチイヤー ✅ v1.8 完了 (PR #418/#423/.../#454) = MultiyearPlanner.runFiveYearPL / MAS-066 配当ミックス ✅ 完了 (PR #402) = 配当連携基盤 / MAS-071 4 アプローチ役員報酬 ✅ 完了 (PR #457/#459) = CompensationStrategyEngine.simulateFourApproaches |
| 後続連携 | MAS-072 企業価値スコアボード(4 レバー → EV スコア連動)/ MAS-060 組織構成シミュレーター(Human レバー Tool 化)/ MAS-061 Cash ETR(節税で Capital レバー貢献度化)/ MAS-144 規程ジェネレーター(Human レバー業務委託 / 採用 → 規程整備の前段) |
| scope reset 経緯(v1.x → v2.0) | v1.0-v1.1(2026-04-27/28)は「統合意思決定ツリー UI + LangGraph + Postgres checkpointer」スコープで起草していたが、2026-05-01 のユーザー要望「1 人社長コンサル業の非連続成長 = 4 レバー(価格・生産物・人・資本)の組合せシミュレーター」を受けスコープ全面リセット。旧 v1.x スコープ(Decision Tree Orchestrator + LangGraph + Cloud SQL Postgres)は §A アーカイブとして末尾に保存し、必要なら別案件 MAS-XXX としてカーブアウト可能(MAS-361 候補・本 PR ではキャリーオーバー扱い)。 |
目的
「1 人コンサルタントの事業が順調なのに、年収 1500-2000 万円台で頭打ちになる」課題に対し、4 つの成長レバー(Pricing / Product / Human / Capital)の組合せシミュレーターを提供する。
一人法人成長の天井 = 4 レバーの未活用
順調な 1 人コンサルは Y3-Y5 で以下の天井に到達:
| 天井 | 数値的特徴 | 既存案件で扱える? |
|---|---|---|
| 時間天井 | 月稼働 160h × 単価 5-8 万円 = 年商 1,600-1,920 万円 | × (MAS-057 は静的試算のみ) |
| 市場天井 | 同単価帯顧客の需要量 = 単一サービスでは不可避 | × |
| 思考天井 | 「もっと働くしかない」モードに固定化 | × |
| 資本天井 | 余剰 CF の使い道が銀行口座放置のみ | × (MAS-066 配当ミックス、MAS-072 EV だけでは不十分) |
これらの天井を非連続的に突破する 4 レバーを組合せ可視化し、「次に何のレバーを引くか」を意思決定可能にする。
4 レバー成長戦略フレーム(Deep Research 由来)
Gemini Deep Research(2026-04-30 実施)+ Claude 内部調査の突合により以下 4 レバーが世界の SMB 成長理論で共通項として確立されている:
| レバー | 中核戦略 | 数値効果(年商換算) | 主要施策 |
|---|---|---|---|
| ① Pricing 価格 | 価値ベース価格設定 / 単価非連続上昇 / リテイナー化 / 成果報酬 | +30-100% | 顧客選別 / パッケージ化 / 段階的単価アップ |
| ② Product 生産物 | デリバラブル化 / 製品化 / AI 補完 / 知識資産化(コース・著作・SaaS) | +50-200% | テンプレート化 / 反復販売 / 1 時間あたり収入の非線形化 |
| ③ Human 人的レバレッジ | 業務委託 / 配偶者役員化 / 採用 / マイクロ M&A | +50-300% | フリーランス活用 / 採用 BEP / 同業小規模事業者の買収 |
| ④ Capital 資本配分 | Buffett-Munger 階層(再投資 → M&A → 配当 → 自社株買い) | CF 投下効率 +50-200% | ROIC > WACC で再投資 / 5 年 NPV 比較 |
重要原則: 4 レバーは独立ではなく相互作用する(例: Product レバー [製品化] が成立すると Pricing レバー [単価アップ] が容易になる、Capital レバー [M&A] は Human レバー [人員拡張] に直結)。本シミュレーターは 4 レバーの組合せ効果を「限界利益スタックド棒グラフ」と「月間稼働時間ラインチャート」で同時可視化し、時間制約(物理上限 200h/月)と予算制約(固定費 + Capital 投下総額)を超えない範囲での最適組合せを探索可能にする。
MAS-072 / MAS-071 / MAS-067 / MAS-058 cockpit との関係
- MAS-058 必要年商: 単年「希望年収 → 必要年商」逆算(1 シナリオ)
- MAS-067 マルチイヤー: 静的 5 年計画(B/S 引継ぎ + ステージ準備度)
- MAS-071 役員報酬 4 アプローチ: 報酬最適化(4 アプローチ比較)
- MAS-072 企業価値スコアボード: 経営の通信簿(3 評価手法)
- MAS-059 本案件: ⬆️ これらの上位レイヤー = 成長戦略 4 レバーの組合せ意思決定(1 cockpit の中で動的に 4 軸を引いて天井突破)
現在のコード(前提案件・利用関数)
MAS-058 必要年商ソルバー(✅ Step 4 完了 / PR #401)
| 関数 | 定義ファイル | シグネチャ | 用途 |
|---|---|---|---|
RequiredRevenueSolver.solveRequiredRevenue(input) | 400_domain/445_required_revenue_solver.js | (input) → {min, healthy, buffered} | 希望年収から必要年商を逆算(Pricing レバー検証用) |
RequiredRevenueSolver.evaluateScenarioHealth(input) | 400_domain/445_required_revenue_solver.js | (input) → {feasible, riskLevel, runwayMonths} | 4 レバー組合せ後の年商シナリオを健全性評価 |
MAS-067 マルチイヤー計画(✅ v1.8 完了 / PR #454)
| 関数 | 定義ファイル | シグネチャ | 用途 |
|---|---|---|---|
MultiyearPlanner.runFiveYearPL(input) | 400_domain/451_multiyear_planner.js | (input) → {pl[5], bs[5], cf[5], stageReadiness} | Y1-Y5 P/L · B/S · CF · ステージ準備度(4 レバー適用後の 5 年シミュレーション基盤) |
MAS-071 役員報酬 4 アプローチ(✅ v1.1 完了 / PR #457/#459)
| 関数 | 定義ファイル | シグネチャ | 用途 |
|---|---|---|---|
CompensationStrategyEngine.simulateFourApproaches(input) | 400_domain/454_compensation_strategy_engine.js | (input) → {A, B, C, D} | 4 アプローチ役員報酬最適化(Capital レバー [配当 vs 報酬] 比較で活用) |
CompensationStrategyEngine.calcLimitProfit(input) | 400_domain/454_compensation_strategy_engine.js:~120 | ({revenue, cogs, fixedCost}) → number | 限界利益(Limit Profit)= 売上 − 変動費 − 固定費(4 レバー貢献度の積上げ基底値) |
MAS-066 配当ミックス(✅ 完了 / PR #402)
| 関数 | 定義ファイル | シグネチャ | 用途 |
|---|---|---|---|
DividendMixOptimizer.simulateScan(input) | 400_domain/449_dividend_mix_optimizer.js | (input) → {bestRatio, scenarios[]} | Capital レバー [配当] の最適化(手残り最大化 vs 内部留保のトレードオフ) |
MAS-057 SPA cockpit 基盤(✅ Phase 3 + Step 7 完了 / PR #379/#394/#454/#459)
| 部品 | パス | 役割 |
|---|---|---|
webapp_client/src/cockpit-main.tsx | SPA エントリ | 副作用 import 規約(failure_patterns #33)で各 panel をマウント |
webapp_client/src/cockpit/calc.ts | client-side 計算 hub | 各 panel の計算は calc.ts 経由で engine 呼出 |
webapp_client/scripts/sync-engines.mjs | engine sync | ENGINES_TO_SYNC 配列で SPA bundle に GAS 純粋関数を取込 |
webapp_client/src/cockpit/CompensationDropdowns.tsx | UI 規約 | 離散単位ドロップダウン優先(ai_agent_tips.md §7) |
_scrubInfinityForJSON_ 汎用ヘルパ(MAS-066 PR #402 で確立)
| 関数 | 定義ファイル | 用途 |
|---|---|---|
_scrubInfinityForJSON_(value) | 300_ui/302_spa_bridge.js 末尾 | failure_patterns #29 対策(Infinity / NaN を null に変換) |
修正方針
Step 1 — 400_domain/446_growth_strategy_engine.js 新設(純粋関数・約 500 行)
⚠️ ID 採番衝突回避(failure_patterns #31): ユーザー初期提案ファイル名は 400_domain/448_growth_strategy_engine.js だったが、448 は MAS-061 (448_cash_etr_simulator.js) で予約済で衝突発覚。次空き番号として MAS-059 v1.x で予約していた 446 slot を v2.0 で再利用(v1.x の 446_decision_tree_orchestrator.js は §A にアーカイブ・実体ファイル未作成のため slot 競合なし)。新規ドメインエンジン番号予約前に必ず grep -nE '400_domain/44[6-9]_' docs/dev/*.md で全使用状況を確認すること(dev_spec_prompt_template v1.10 Phase 1-A-pre 適用)。
// 400_domain/446_growth_strategy_engine.js (純粋関数 + IIFE 名前空間)
var GrowthStrategyEngine = (function () {
// ─────────────────────────────────────────────────────────
// ① Pricing レバー: 価格 × 顧客数 × 単価アップ
// ─────────────────────────────────────────────────────────
/**
* @param {Object} input
* @param {number} input.baseRevenue Y0 ベース年商
* @param {number} input.priceUpRatio 単価アップ率 (0-1, 例 0.30 = 30% 引上げ)
* @param {number} input.elasticity 価格弾力性 (default 0.7)
* @param {number} input.churnRiskRatio 顧客流出率 (single-elasticity モデル)
* @returns {{deltaRevenue, deltaProfit, churnedClients, hoursDelta}}
*/
function simulatePricingLever(input) {
var elasticity = input.elasticity || 0.7;
var churnRatio = elasticity * input.priceUpRatio;
var newRevenue = input.baseRevenue * (1 + input.priceUpRatio) * (1 - churnRatio);
var deltaRevenue = newRevenue - input.baseRevenue;
return {
deltaRevenue: deltaRevenue,
deltaProfit: deltaRevenue, // Pricing レバーは追加コストなし
churnedClients: churnRatio,
hoursDelta: 0, // 時間は不変
};
}
// ─────────────────────────────────────────────────────────
// ② Product レバー: 製品化 / AI 補完 / 知識資産化
// ─────────────────────────────────────────────────────────
/**
* @param {Object} input
* @param {number} input.baseHourlyRevenue Y0 1 時間あたり収入
* @param {number} input.productizationLevel 0-5 (0=完全カスタム, 5=完全 SaaS)
* @param {number} input.boostMultiplier 最大生産性倍率 (default 1.5)
* @returns {{newHourlyRevenue, deltaProfit, hoursDelta, knowledgeAssetValue}}
*/
function simulateProductLever(input) {
var levelRatio = input.productizationLevel / 5; // 0-1 normalize
var boost = 1 + (input.boostMultiplier - 1) * levelRatio;
var newHourlyRevenue = input.baseHourlyRevenue * boost;
var deltaHourly = newHourlyRevenue - input.baseHourlyRevenue;
return {
newHourlyRevenue: newHourlyRevenue,
deltaProfit: deltaHourly * (input.baseHours || 0), // 同じ時間で多く稼ぐ
hoursDelta: -input.baseHours * (1 - 1 / boost), // 同売上を維持なら時間削減
knowledgeAssetValue: input.baseRevenue * levelRatio * 0.20, // 知識資産簿外価値
};
}
// ─────────────────────────────────────────────────────────
// ③ Human レバー: 業務委託 / 採用 / マイクロ M&A
// ─────────────────────────────────────────────────────────
/**
* @param {Object} input
* @param {number} input.contractorHours 業務委託時間 (月)
* @param {number} input.contractorRate 業務委託単価
* @param {number} input.employeeCount 採用人員 (整数)
* @param {number} input.employeeAvgCost 採用人員単価 (年額・社保込)
* @param {number} input.mnaTargetRevenue マイクロ M&A 対象年商
* @param {number} input.mnaPremiumMultiple 買収 EBITDA 倍率 (default 5)
* @param {number} input.overheadRatio 管理コスト比率 (default 0.30)
* @returns {{capacityDelta, costDelta, mnaInvestment, hoursDelta, requiresHitl}}
*/
function simulateHumanLever(input) {
var contractorAnnual = (input.contractorHours || 0) * 12 * (input.contractorRate || 0);
var employeeAnnual = (input.employeeCount || 0) * (input.employeeAvgCost || 0)
* (1 + (input.overheadRatio || 0.30));
var mnaInvestment = (input.mnaTargetRevenue || 0) * (input.mnaPremiumMultiple || 5);
var capacityDelta = (input.contractorHours || 0) * 12
+ (input.employeeCount || 0) * 2000; // 正社員年間稼働 2000h
return {
capacityDelta: capacityDelta, // 追加可能稼働時間 (年)
costDelta: contractorAnnual + employeeAnnual,
mnaInvestment: mnaInvestment, // M&A 一時支出 (B/S 計上)
hoursDelta: -capacityDelta * 0.6, // CEO 自身の時間は委譲分削減 (60% 効率)
requiresHitl: (input.employeeCount > 0) || (input.mnaTargetRevenue > 0),
};
}
// ─────────────────────────────────────────────────────────
// ④ Capital レバー: Buffett-Munger 階層 (再投資 → M&A → 配当 → 自社株買い)
// ─────────────────────────────────────────────────────────
/**
* @param {Object} input
* @param {number} input.surplusCf 余剰 CF
* @param {number} input.reinvestRatio 再投資比率 (0-1)
* @param {number} input.reinvestRoic 再投資 ROIC 想定
* @param {number} input.mnaRatio M&A 比率
* @param {number} input.dividendRatio 配当比率 (MAS-066 連携)
* @param {number} input.buybackRatio 自社株買い比率 (1 人法人では通常 0)
* @param {number} input.roicHurdle ROIC 閾値 (default 0.15)
* @param {number} input.dividendHurdle 配当機会費用 (default 0.05)
* @returns {{npvByOption, recommendedAllocation, totalNpv5y, warnings[]}}
*/
function simulateCapitalLever(input) {
var hurdle = input.roicHurdle || 0.15;
var dividendHurdle = input.dividendHurdle || 0.05;
var npvReinvest = (input.reinvestRoic >= hurdle)
? input.surplusCf * input.reinvestRatio * _annuityFactor_(5, input.reinvestRoic)
: 0;
var npvMna = input.surplusCf * input.mnaRatio * _annuityFactor_(5, hurdle);
var npvDividend = input.surplusCf * input.dividendRatio * _annuityFactor_(5, dividendHurdle);
var npvBuyback = input.surplusCf * (input.buybackRatio || 0) * _annuityFactor_(5, hurdle);
var warnings = [];
if (input.reinvestRoic < hurdle && input.reinvestRatio > 0) {
warnings.push("再投資 ROIC " + (input.reinvestRoic * 100).toFixed(1)
+ "% が閾値 " + (hurdle * 100).toFixed(0) + "% を下回る — 配当 / M&A を検討");
}
return {
npvByOption: {
reinvest: npvReinvest,
mna: npvMna,
dividend: npvDividend,
buyback: npvBuyback,
},
recommendedAllocation: _rankByNpv_(npvReinvest, npvMna, npvDividend, npvBuyback),
totalNpv5y: npvReinvest + npvMna + npvDividend + npvBuyback,
warnings: warnings,
};
}
// ─────────────────────────────────────────────────────────
// 統合 API: runGrowthStrategy(input) — 4 レバーを順次計算
// ─────────────────────────────────────────────────────────
/**
* @param {Object} input
* @param {number} input.baseRevenue
* @param {number} input.baseHours Y0 ベース月稼働時間
* @param {Object} input.pricingInput
* @param {Object} input.productInput
* @param {Object} input.humanInput
* @param {Object} input.capitalInput
* @param {Object} input.constraints {hoursSoftLimit, hoursHardLimit, budgetTotal}
* @returns {{
* levers: {pricing, product, human, capital},
* stackedBarData: Array<{year, pricing, product, human, capital, base}>,
* hoursLineData: Array<{year, hours, softLimit, hardLimit}>,
* budgetOverWarning: {flag, message, amount} | null,
* requiresHitl: boolean,
* limitProfitTotal: number,
* feasibility: 'feasible' | 'tight' | 'infeasible'
* }}
*/
function runGrowthStrategy(input) {
var pricing = simulatePricingLever(input.pricingInput);
var product = simulateProductLever(input.productInput);
var human = simulateHumanLever(input.humanInput);
var capital = simulateCapitalLever(input.capitalInput);
// 5 年スタックドバー組立 (Y0-Y5)
var horizon = input.constraints.forecastHorizonYears || 5;
var stackedBarData = _buildStackedBarData_(input.baseRevenue, pricing, product, human, capital, horizon);
// 月間稼働時間ラインチャート組立
var hoursLineData = _buildHoursLineData_(input.baseHours, pricing, product, human,
input.constraints.hoursSoftLimit || 160, input.constraints.hoursHardLimit || 200, horizon);
// 予算オーバー警告
var totalCost = (human.costDelta || 0) + (human.mnaInvestment || 0)
+ (capital.npvByOption.reinvest > 0 ? input.capitalInput.surplusCf * input.capitalInput.reinvestRatio : 0);
var budgetThreshold = (input.constraints.budgetTotal || 0)
* (input.constraints.budgetOverThresholdRatio || 0.95);
var budgetOverWarning = (totalCost > budgetThreshold) ? {
flag: true,
message: "総支出 " + _formatJpy_(totalCost) + " が予算枠 "
+ _formatJpy_(input.constraints.budgetTotal) + " の 95% を超過",
amount: totalCost,
} : null;
// feasibility 判定
var maxHours = Math.max.apply(null, hoursLineData.map(function (d) { return d.hours; }));
var feasibility = (maxHours > (input.constraints.hoursHardLimit || 200))
? 'infeasible'
: (maxHours > (input.constraints.hoursSoftLimit || 160) ? 'tight' : 'feasible');
return {
levers: { pricing: pricing, product: product, human: human, capital: capital },
stackedBarData: stackedBarData,
hoursLineData: hoursLineData,
budgetOverWarning: budgetOverWarning,
requiresHitl: human.requiresHitl,
limitProfitTotal: pricing.deltaProfit + product.deltaProfit + (capital.totalNpv5y / horizon),
feasibility: feasibility,
};
}
// ─────────────────────────────────────────────────────────
// 内部ヘルパ
// ─────────────────────────────────────────────────────────
function _annuityFactor_(years, rate) {
if (rate === 0) return years;
return (1 - Math.pow(1 + rate, -years)) / rate;
}
function _rankByNpv_(reinvest, mna, dividend, buyback) {
var options = [
{ key: 'reinvest', npv: reinvest },
{ key: 'mna', npv: mna },
{ key: 'dividend', npv: dividend },
{ key: 'buyback', npv: buyback },
];
options.sort(function (a, b) { return b.npv - a.npv; });
return options;
}
function _buildStackedBarData_(baseRevenue, pricing, product, human, capital, horizon) {
var data = [];
for (var y = 0; y <= horizon; y++) {
var growthFactor = y / horizon; // 線形ランプアップ
data.push({
year: 'Y' + y,
base: baseRevenue,
pricing: pricing.deltaProfit * growthFactor,
product: product.deltaProfit * growthFactor,
human: (human.capacityDelta * 0.5) * growthFactor, // 容量増 → 売上換算
capital: (capital.totalNpv5y / horizon) * (y > 0 ? 1 : 0), // Y1 以降に発現
});
}
return data;
}
function _buildHoursLineData_(baseHours, pricing, product, human, softLimit, hardLimit, horizon) {
var data = [];
for (var y = 0; y <= horizon; y++) {
var growthFactor = y / horizon;
var hours = baseHours
+ pricing.hoursDelta * growthFactor
+ product.hoursDelta * growthFactor
+ human.hoursDelta * growthFactor;
data.push({
year: 'Y' + y,
hours: Math.max(0, hours),
softLimit: softLimit,
hardLimit: hardLimit,
});
}
return data;
}
function _formatJpy_(amount) {
return Math.round(amount).toLocaleString('ja-JP') + ' 円';
}
return {
simulatePricingLever: simulatePricingLever,
simulateProductLever: simulateProductLever,
simulateHumanLever: simulateHumanLever,
simulateCapitalLever: simulateCapitalLever,
runGrowthStrategy: runGrowthStrategy,
};
})();
純粋性の維持: SpreadsheetApp / Repository / PropertiesService 一切呼ばず、全て input で完結。MAS-058 / MAS-066 / MAS-067 / MAS-071 と同型の Pure Function 規約(failure_patterns #25 対称性遵守)。
Step 2 — webapp_client/src/cockpit/GrowthStrategyPanel.tsx 新設(約 700 行)
// 左 4 スライダー + 右 2 チャート + 下部予算オーバー警告
import React, { useState, useMemo } from 'react';
import { calcGrowthStrategy } from './calc';
const GrowthStrategyPanel: React.FC<Props> = ({ baseRevenue, baseHours, sysParams }) => {
const [pricingLevel, setPricingLevel] = useState(0); // 0-5
const [productLevel, setProductLevel] = useState(0);
const [humanLevel, setHumanLevel] = useState(0);
const [capitalLevel, setCapitalLevel] = useState(0);
const result = useMemo(() => calcGrowthStrategy({
baseRevenue, baseHours,
pricingInput: { baseRevenue, priceUpRatio: pricingLevel * 0.10 /* 0-50% */ },
productInput: { baseHourlyRevenue: baseRevenue / (baseHours * 12), productizationLevel: productLevel },
humanInput: _mapHumanLevel(humanLevel),
capitalInput: _mapCapitalLevel(capitalLevel),
constraints: sysParams,
}), [pricingLevel, productLevel, humanLevel, capitalLevel, baseRevenue, baseHours]);
return (
<div className="growth-strategy-panel">
<div className="left-pane">
<h3>🚀 4 成長レバー</h3>
<SliderRow label="① Pricing 価格" value={pricingLevel} onChange={setPricingLevel}
marks={['現状', '+10%', '+20%', '+30%', '+40%', '+50%']} />
<SliderRow label="② Product 製品化" value={productLevel} onChange={setProductLevel}
marks={['完全カスタム', '...', '...', '...', '...', '完全 SaaS']} />
<SliderRow label="③ Human 人的レバレッジ" value={humanLevel} onChange={setHumanLevel}
marks={['1 人', '+業委 80h', '+業委 160h', '+正社 1', '+正社 2', '+M&A']} />
<SliderRow label="④ Capital 資本配分" value={capitalLevel} onChange={setCapitalLevel}
marks={['全額留保', '配当 25%', '再投資 50%', 'M&A 50%', '再投資 80%', 'M&A 80%']} />
{result.requiresHitl && <HitlBadge message="採用 / M&A は HITL 承認必須" />}
</div>
<div className="right-pane">
<div className="chart-stacked-bar">
<h4>限界利益スタックドバー (Y0-Y5)</h4>
<LimitProfitStackedBar data={result.stackedBarData} />
</div>
<div className="chart-hours-line">
<h4>月間稼働時間 (時間制約: 160h ソフト / 200h ハード)</h4>
<MonthlyHoursLineChart data={result.hoursLineData} />
</div>
</div>
{result.budgetOverWarning && (
<BudgetOverWarningBanner warning={result.budgetOverWarning} />
)}
<FeasibilityIndicator level={result.feasibility} />
</div>
);
};
Step 3 — webapp_client/scripts/sync-engines.mjs の ENGINES_TO_SYNC 拡張
const ENGINES_TO_SYNC = [
// ... 既存
'400_domain/446_growth_strategy_engine.js', // ← 追加
];
Step 4 — webapp_client/src/cockpit-main.tsx 副作用 import 追加
// failure_patterns #33 対策: panel-level の useEffect ベースエントリは
// import 副作用で必ず登録する
import './cockpit/GrowthStrategyPanel';
Step 5 — webapp_client/src/cockpit/calc.ts への calcGrowthStrategy 公開
export function calcGrowthStrategy(input) {
// GAS 純粋関数を direct call (sync-engines.mjs で bundle 済)
const result = GrowthStrategyEngine.runGrowthStrategy(input);
// failure_patterns #29: Infinity / NaN を null に変換
return scrubInfinityForJSON(result);
}
Step 6 — 300_ui/302_spa_bridge.js bootstrap に F59_* sys_params 配信追加
function _buildF59CockpitBootstrap_() {
return {
f59Params: {
hoursPerMonthSoftLimit: Constants.getParam('F59_HOURS_PER_MONTH_SOFT_LIMIT', 160),
hoursPerMonthHardLimit: Constants.getParam('F59_HOURS_PER_MONTH_HARD_LIMIT', 200),
pricingElasticity: Constants.getParam('F59_PRICING_ELASTICITY', 0.7),
productizationBoostMultiplier: Constants.getParam('F59_PRODUCTIZATION_BOOST_MULTIPLIER', 1.5),
humanLeverageOverheadRatio: Constants.getParam('F59_HUMAN_LEVERAGE_OVERHEAD_RATIO', 0.30),
capitalReinvestRoicHurdle: Constants.getParam('F59_CAPITAL_REINVEST_ROIC_HURDLE', 0.15),
capitalMnaPremiumDefault: Constants.getParam('F59_CAPITAL_MNA_PREMIUM_DEFAULT', 5),
capitalDividendHurdleRate: Constants.getParam('F59_CAPITAL_DIVIDEND_HURDLE_RATE', 0.05),
budgetOverThresholdRatio: Constants.getParam('F59_BUDGET_OVER_THRESHOLD_RATIO', 0.95),
forecastHorizonYears: Constants.getParam('F59_FORECAST_HORIZON_YEARS', 5),
}
};
}
Step 7 — 100_config/101_sys_config.js に F59_* 12 キーシード追加
confSheet.appendRow パターン(MAS-066 / MAS-067 と同型)で 12 キーを 03_sys_params に投入。default 値は注意事項 #4 の運用調整余地を残し Constants.getParam の第 2 引数 fallback を併用。
影響範囲
| 対象 | 種別 | 変更内容 | リスク |
|---|---|---|---|
400_domain/446_growth_strategy_engine.js | 追加 | GrowthStrategyEngine 名前空間 (4 レバー pure function + runGrowthStrategy + 内部ヘルパ・約 500 行) | 既存ロジックへの影響なし |
webapp_client/src/cockpit/GrowthStrategyPanel.tsx | 追加 | 左 4 スライダー + 右 2 チャート + 予算超過警告 + feasibility indicator (約 700 行) | MAS-057 cockpit-main.tsx の追加 panel として独立 |
webapp_client/scripts/sync-engines.mjs | 変更 | ENGINES_TO_SYNC に 446 追加 | bundle サイズ +500 行・既存 engine sync に影響なし |
webapp_client/src/cockpit-main.tsx | 変更 | import './cockpit/GrowthStrategyPanel' 副作用 import 追加 | failure_patterns #33 対策 |
webapp_client/src/cockpit/calc.ts | 変更 | calcGrowthStrategy 公開関数追加・scrubInfinityForJSON 流用 | 既存計算 hub に影響なし |
300_ui/302_spa_bridge.js | 変更 | _buildF59CockpitBootstrap_ 追加 + doGet の bootstrap merge | failure_patterns #29 (_scrubInfinityForJSON_ は MAS-066 PR #402 で確立済) |
100_config/101_sys_config.js | 変更 | confSheet.appendRow で 12 キー追加 | シード未実行でも Constants.getParam 第 2 引数 default で動作 |
000_infra/002_constants.js | 変更 | MENU_DEFINITION に「🚀 成長戦略シミュレーター」追加(cockpit から独立タブ起動) | 既存メニューに影響なし |
900_test/901_test_runner.js | 変更 | F059-01〜F059-18 単体テスト追加 | 既存テストへの影響なし |
| MAS-057 cockpit | 連携拡張 | パネル並び: 健全性診断 → 4 アプローチ → EV → 🚀 成長戦略(最下部追加・MAS-072 直下) | 既存 cockpit に影響なし |
| appsscript.json | 変更なし | OAuth スコープは v1 で変更なし(Postgres 移行は §A 旧スコープ保留・本案件 v2.0 ではスコープ外) | failure_patterns #26 遵守 |
注意事項
【failure_patterns #31】ID 採番衝突回避(v1.x → v2.0 の slot 継承): ユーザー初期提案
400_domain/448_growth_strategy_engine.jsは MAS-061 (448_cash_etr_simulator.js) で予約済のため衝突。MAS-059 v1.x で予約していた446slot を v2.0 で再利用(v1.x の446_decision_tree_orchestrator.jsは §A アーカイブで実体未作成のため slot 競合なし)。grep -nE '400_domain/44[6-9]_' docs/dev/*.md結果: 446 = MAS-059 v1.x(旧)/ 447 = MAS-060 (workforce_mix_optimizer 予約) / 448 = MAS-061 (cash_etr_simulator 予約) / 449 = MAS-066 (dividend_mix ✅ 完了)。新規 slot 予約前に必ず全使用状況を grep 確認。【failure_patterns #18-#20】命名造語の禁止(必読):
simulatePricingLever/simulateProductLever/simulateHumanLever/simulateCapitalLever/runGrowthStrategyは MAS-058 (solveRequiredRevenue) / MAS-067 (runFiveYearPL) / MAS-071 (simulateFourApproaches) と命名対称(動詞 + 目的語)。runGrowthStrategyは造語ではなく業界標準(McKinsey 4 Levers / BCG Growth-Share Matrix の延長)。実装着手前に必ず400_domain/445_required_revenue_solver.js/400_domain/451_multiyear_planner.js/400_domain/454_compensation_strategy_engine.jsを Read で確認し、関数シグネチャの整合性を裏取り。【failure_patterns #25】並列実装対称性: MAS-058 / MAS-066 / MAS-067 / MAS-071 と純粋関数 + IIFE 名前空間 + Repository 注入なし(panel-local 入力モード)パターンで対称。
runGrowthStrategy(input)↔MultiyearPlanner.runFiveYearPL(input)↔CompensationStrategyEngine.simulateFourApproaches(input)の API シグネチャ整合(input 全 plain object / output 全 plain object)。【failure_patterns #26】appsscript.json は v1 段階で変更なし: 4 レバー全て純粋関数 + 既存 sys_params 配信パターンで完結。Cloud SQL Postgres 移行 / LangGraph 統合は §A 旧 v1.x スコープに保留しており、本 v2.0 ではスコープ外。OAuth スコープ追加は v2 以降の別 PR で実施。
【failure_patterns #29】Infinity / NaN の JSON 配信:
simulateCapitalLeverの_annuityFactor_でrate=0時の特例処理を実装済。さらに300_ui/302_spa_bridge.jsの_scrubInfinityForJSON_をf59Params配信前に必ず通す(MAS-066 PR #402 で確立した汎用ヘルパ)。【failure_patterns #33】副作用 import の必須化:
webapp_client/src/cockpit-main.tsxにimport './cockpit/GrowthStrategyPanel'を追加しないと、本番ビルドで panel が tree-shaking で消える。MAS-066 実装中に発覚した bug pattern(commit41305eaで fix 済)の再発防止。時間制約(物理上限)の硬性ガード:
F59_HOURS_PER_MONTH_HARD_LIMIT(default 200h) を超える組合せはfeasibility: 'infeasible'で警告表示し、ユーザーに「Human レバーを引かないと達成不可」と明示。1 人法人 CEO の自身稼働時間は週 50h × 4 週 = 200h を物理上限とし、それ以上は Human レバー(業務委託 / 採用 / M&A)を必須化。Pricing 弾力性の前提:
F59_PRICING_ELASTICITY(default 0.7) は経済学の標準弾力性レンジ(0.5-1.0)で、コンサル業種特性として「単価 +30% → 顧客流出 21%」を意味する保守値。実運用ではユーザー業種(IT コンサル / 戦略コンサル / 業務コンサル)で調整余地あり、03_sys_paramsで運用調整可能。Product レバーの製品化レベル定義:
productizationLevel0-5 は離散単位(dropdown 推奨・ai_agent_tips.md §7準拠)。0 = 完全カスタム / 5 = 完全 SaaS / 1-4 = 段階的(テンプレート化 → ガイドブック → コース → 半自動 SaaS)。boost multiplierF59_PRODUCTIZATION_BOOST_MULTIPLIER(default 1.5) は最大生産性倍率で、レベル 5 で 1.5 倍(同じ時間で 1.5 倍稼ぐ)。Human レバーの HITL 強制:
simulateHumanLeverでemployeeCount > 0またはmnaTargetRevenue > 0の組合せはrequiresHitl: trueを返し、UI 側で必ず承認モーダルを挟む(PRD プロダクトポリシー Human-in-the-Loop 原則準拠)。Pricing / Product レバーは数値変更のみで HITL 不要、Capital レバーは閾値超過時のみ HITL(注意事項 #11)。Capital レバー Buffett-Munger 階層の優先順位: 4 オプション(再投資 / M&A / 配当 / 自社株買い)の NPV ランキングを表示。1 人法人で自社株買いは通常 0(株主 = 代表者 1 名のため自社株買いの意味なし)。default では
buybackRatio: 0、UI でも非表示推奨。再投資 ROIC がF59_CAPITAL_REINVEST_ROIC_HURDLE(default 15%) を下回る場合、warningsに「配当 / M&A を検討」が出る(バフェット第 1 原則: ROIC > WACC でなければ再投資せず配当を選ぶ)。限界利益(Limit Profit)の積上げ規約:
LimitProfitStackedBarの Y 軸 = 限界利益(売上 − 変動費 − 固定費)。各レバーの寄与は deltaProfit で積上げる(base = Y0 限界利益、各色 = 4 レバーの追加寄与)。MAS-071calcLimitProfitと整合(変動費 = 原価率 × 売上、固定費 = 月額固定費 × 12)。マイクロ M&A の B/S 影響:
simulateHumanLeverのmnaInvestmentは M&A 一時支出(B/S のれん計上 + キャッシュアウト)。Y0 で B/S 計上 + Y1 以降に統合効果(capacityDeltaとして年次反映)。詳細な PMI(Post-Merger Integration)コストは v1 で簡易扱い(買収プレミアム × 5 = EBITDA × 5 倍数で一括)。実運用では税務 DD・労務 DD コストを別途検討(人間検討事項 #6)。予算オーバー警告のしきい値:
F59_BUDGET_OVER_THRESHOLD_RATIO(default 0.95) で「予算枠の 95% 到達で警告」を default。100% を超えるとfeasibility: 'infeasible'に降格。ユーザーが Capital レバー [再投資 80%] + Human レバー [採用 + M&A] を同時最大化した場合の「夢追いシナリオ警告」として機能。シナリオ保存 (v2 拡張余地): v1 では panel-local 入力 + URL クエリパラメータ保存(
?growthStrategy=p3,p2,h4,c2)を default。シナリオ永続化(40_scenario_registry連携)は v2 拡張として留保(MAS-067 / MAS-066 同型・必要時に Spreadsheet 保存追加)。
エッジケース
| # | 条件 | 期待される挙動 | 理由・ログ出力 |
|---|---|---|---|
| 1 | 全レバー = 0(現状維持) | base のみ stacked bar / 現状稼働時間 line | Y0 ベースライン表示 |
| 2 | 全レバー最大(Pricing+50% / Product=5 / Human=+M&A / Capital 80% 再投資) | feasibility = 'infeasible' + 予算オーバー警告 + HITL 強制 | 物理時間 + 予算超過 + 採用 / M&A 重複 |
| 3 | Pricing +50% 単独引上げ | pricing.churnedClients 35% 表示 + 売上 +30%(弾力性 0.7 反映) | 高単価少数顧客戦略の前提確認 |
| 4 | Product レベル 5 + Pricing 0 | productLever.knowledgeAssetValue > 0 + hours -40% (productivity 1.5x) | 製品化で時間圧縮 |
| 5 | Human レバー [業務委託のみ] | requiresHitl: false(フリーランスは契約のため HITL 不要)+ capacityDelta 増 | 業務委託 vs 採用の責任範囲差 |
| 6 | Human レバー [採用 1 名] | requiresHitl: true + 雇用契約 / 社保 / 規程整備の前提 | MAS-144 規程ジェネレーター連携を促す警告 |
| 7 | Human レバー [マイクロ M&A] | mnaInvestment > 0 + B/S のれん計上 + 税務 DD 警告 | 買収プレミアム 5 倍 + 簿外債務 20% を gross-up(注意事項 #13) |
| 8 | Capital レバー再投資 ROIC < 15% | warnings: ["再投資 ROIC が閾値を下回る - 配当 / M&A を検討"] | バフェット第 1 原則違反警告 |
| 9 | Capital レバー全配当 100% | npvByOption.dividend のみ + 再投資 ゼロ | MAS-066 配当ミックス連携で税効率最適化を促す |
| 10 | 余剰 CF = 0(赤字期) | 全 Capital レバー npv = 0 + 「Capital レバー前に Pricing/Product/Human を先行検討」UI ヒント | 赤字フェーズで Capital を引いても無意味 |
| 11 | baseHours = 200h(既に物理上限) | Human レバーなしで他のレバーだけ引くと feasibility = 'tight' or 'infeasible' | 1 人で天井到達済の警告 |
| 12 | 弾力性 = 0(顧客流出ゼロ前提) | Pricing +50% で売上 +50% 全反映 | 独占的サービスの仮定(楽観値・実運用では default 0.7 推奨) |
| 13 | 弾力性 = 1.0(完全弾力的) | Pricing +50% で売上 ±0 | コモディティサービスの警告 |
| 14 | productizationLevel = 5 でも baseHours = 0 | knowledgeAssetValue 計算可・hoursDelta = 0 | 既に時間ゼロなら時間圧縮効果なし |
| 15 | M&A 対象年商 = 0(買収先未定) | mnaInvestment = 0 + 「対象先を入力してください」ヒント | UI 側で入力ガイド |
| 16 | 予算枠 = 0(無入力) | 予算オーバー警告は出ず、feasibility のみ判定 | 制約なしでの理論値表示モード |
| 17 | Infinity / NaN(不正入力) | _scrubInfinityForJSON_ で null 化 + UI 「入力エラー」 | failure_patterns #29 対策 |
| 18 | forecastHorizonYears = 1(短期) | stackedBar 1 年分のみ + Capital レバーは Y0 全反映 | 短期シナリオ表示 |
実データ検証 / テスト
F059-01〜F059-18 単体テスト(901_test_runner.js)
| # | テスト名 | 入力 | 期待値 | 失敗時の影響 |
|---|---|---|---|---|
| F059-01 | Pricing +30% 単独 | baseRevenue 1500万 / 弾力性 0.7 | deltaRevenue ≈ +85万、churnedClients 21% | 価格弾力性ロジック検証 |
| F059-02 | Pricing +50% 単独 | baseRevenue 1500万 / 弾力性 0.7 | deltaRevenue ≈ +97万、churnedClients 35% | 高引上げ時の流出反映 |
| F059-03 | Product レベル 5 単独 | baseRevenue 1500万 / boost 1.5 | newHourlyRevenue × 1.5、hoursDelta -33% | 製品化生産性検証 |
| F059-04 | Human 業務委託 80h | contractorHours 80 / rate 1万円 | costDelta = 96万、capacityDelta 960h、HITL false | 業務委託 = HITL 不要 |
| F059-05 | Human 採用 1 名 | employeeCount 1 / avgCost 580万 | costDelta = 754万 (+30% overhead)、HITL true | 採用 = HITL 必須 |
| F059-06 | Human M&A 1500万 | mnaTargetRevenue 1500万 / multiple 5 | mnaInvestment = 7500万、HITL true | M&A 倍数 5 反映 |
| F059-07 | Capital 再投資 ROIC 20% | surplusCf 1000万 / reinvestRatio 0.5 / roic 0.2 / hurdle 0.15 | npvReinvest > 0、warnings なし | ROIC > 閾値で warn なし |
| F059-08 | Capital 再投資 ROIC 10% | surplusCf 1000万 / reinvestRatio 0.5 / roic 0.10 / hurdle 0.15 | npvReinvest = 0、warnings 1 件 | ROIC < 閾値 warn 発動 |
| F059-09 | Capital 全配当 | surplusCf 1000万 / dividendRatio 1.0 | npvDividend > 0、recommendedAllocation[0] = dividend | 配当ランキング検証 |
| F059-10 | 4 レバー組合せ最大 | Pricing 0.5 / Product 5 / Human +M&A / Capital 全再投資 | feasibility 'infeasible' + budgetOverWarning + HITL | 過剰組合せ警告 |
| F059-11 | 全レバー 0 | 全 input 0 | base のみ + warnings 0 | ベースライン |
| F059-12 | 時間ハード上限超過 | baseHours 200 + Pricing+50% で hoursDelta 微増 | feasibility 'tight' or 'infeasible' | 物理時間ガード |
| F059-13 | 予算枠 95% 超過 | totalCost 950万 / budget 1000万 | budgetOverWarning.flag = true | 予算オーバー警告 |
| F059-14 | Infinity 注入 | reinvestRoic = Infinity | npv = null、warnings に「不正入力」 | failure_patterns #29 |
| F059-15 | NaN 注入 | priceUpRatio = NaN | deltaRevenue = null | failure_patterns #29 |
| F059-16 | annuityFactor rate=0 | rate 0 / years 5 | factor = 5(特例処理) | 数学エッジケース |
| F059-17 | stackedBar Y5 線形ランプ | horizon 5 / pricing.deltaProfit 100万 | Y5 で 100万、Y2 で 40万 | 線形ランプ検証 |
| F059-18 | hours line baseHours 160 | baseHours 160 / human.hoursDelta -50 | Y5 で 110h | 時間削減反映 |
齋藤 Baseline 多年検証(手動)
| シナリオ | 入力 | 期待観察 |
|---|---|---|
| A (現状維持) | 全レバー 0 | Y0 = Y5 = 限界利益 1,200万、稼働 160h |
| B (Pricing+30% のみ) | Pricing slider 3 | Y5 限界利益 +85万、顧客流出 21% 警告 |
| C (Product 5 + Pricing+30%) | Product 5 + Pricing 3 | Y5 限界利益 +250万、稼働 -33%、知識資産 300万 |
| D (フル拡張) | 全レバー max | feasibility 'infeasible' + 「Human 必須」警告 |
Limit Profit Stacked Bar の整合性
webapp_client/src/cockpit/calc.ts で calcGrowthStrategy の output stackedBarData が以下を満たすか単体テスト:
Y0row: pricing/product/human/capital 全て 0、base のみY5row: 各色の合計 = limitProfitTotal- 中間年: 線形ランプ(growthFactor = y / horizon)
Monthly Hours Line Chart の整合性
hoursLineData が以下を満たすか単体テスト:
- 全 row で
softLimit/hardLimit一定 hoursが baseHours から線形に変化- Human レバー引いた場合に hours が減少
関連ドキュメント
| カテゴリ | ドキュメント | 関係 |
|---|---|---|
| MAS-058 必要年商ソルバー | dev_mas-058_required_revenue_solver.md | Pricing レバー検証用 (solveRequiredRevenue を evaluateScenarioHealth 経由で呼出) |
| MAS-067 マルチイヤー計画 | dev_mas-067_multiyear_planning_workspace.md | 5 年 P/L · B/S · CF 基盤(4 レバー適用後の年次反映) |
| MAS-071 役員報酬 4 アプローチ | dev_mas-071_compensation_strategy_simulator.md | Capital レバー [報酬 vs 配当] 比較・限界利益計算式 |
| MAS-066 配当ミックス | dev_mas-066_dividend_mix_optimizer.md | Capital レバー [配当] の手残り最大化 |
| MAS-072 企業価値スコアボード | dev_mas-072_valuation_scoreboard.md | 4 レバー → EV スコア連動(後続案件) |
| MAS-057 Solo-CEO Cockpit | dev_mas-057_solo_ceo_cockpit.md | SPA 基盤 + 副作用 import 規約 + sync-engines.mjs |
| MAS-060 組織構成シミュレーター | dev_mas-060_workforce_mix_optimizer.md | Human レバー Tool 化(業務委託 / 採用ミックス最適化) |
| MAS-061 Cash ETR | dev_mas-061_cash_etr_tracking.md | 節税 → Capital レバー貢献度化(合法節税範囲) |
| MAS-144 規程ジェネレーター | dev_mas-144_regulation_generator.md | Human レバー(採用 / 業務委託)→ 規程整備の前段 |
| PRD プロダクトポリシー | prd.md | Human-in-the-Loop 原則(採用 / M&A 強制 HITL) |
| failure_patterns | failure_patterns.md | 特に #18-#20(命名造語)/ #25(並列実装対称性)/ #26(OAuth スコープ)/ #29(Infinity/NaN)/ #31(ID 採番衝突)/ #33(副作用 import) |
| ai_agent_tips.md §7 | ai_agent_tips.md | UI: スライダー禁止 → 離散単位ドロップダウン優先 |
| CLAUDE.md | CLAUDE.md | プロジェクトルール・GAS ファイル番号体系・推奨実行モデル |
| BRD Solo-CEO Financial Navigator | brd_solo_ceo_financial_navigator.md | 「天井突破 = 4 レバー」フレームの戦略的位置付け |
人間が検討すべき事項
4 レバーの相互作用モデル: v1 は各レバー独立計算(足し算)。実運用では Product レバー成立 → Pricing レバー容易、Capital レバー [M&A] → Human レバー [採用] 自動連動など相互増幅がある。v2 で相関係数モデルに拡張するか。
価格弾力性の業種別カスタマイズ:
F59_PRICING_ELASTICITY(default 0.7) は IT コンサル想定。戦略コンサル(弾力性 0.5・希少性高)/ 業務コンサル(弾力性 0.9・代替容易)で大きく異なる。業種別 default をConstants.BUSINESS_TYPE_ELASTICITY_MAPに追加するか。製品化レベル 0-5 の境界定義: レベル 1-4 の中間段階(テンプレート / ガイド / コース / 半自動)を離散ドロップダウンで表現するか、連続スライダーにするか。
ai_agent_tips.md §7準拠なら離散だが、4 レバー UI で他 3 レバーが連続だと不揃い。マイクロ M&A の対象先入力 UX: 「対象年商 1500 万 + プレミアム 5 倍」だけでは粗い。実運用では業種・PMI コスト・税務 DD コスト・労務 DD コスト・買収後の文化統合リスクが必要。v2 で
MnaTargetInputpanel を別 panel として分離するか。Buffett-Munger 階層の 1 人法人特化: 自社株買いは 1 人法人で意味なし → default 非表示の判断は妥当か。配当 vs 内部留保のトレードオフは MAS-066 配当ミックスに委譲、再投資 vs M&A は本案件で扱う、自社株買いは商用化期に解禁、で OK か。
PMI コストの簡易扱い: 注意事項 #13 で「v1 で簡易扱い」としたが、買収プレミアム × 5(EBITDA 5 倍)だけでは過小評価リスクあり。日本中小 M&A 平均 PMI コスト = 買収額の 10-20%(経済産業省調査)を簡易加算するか。
時間ハード上限 200h の医療学的根拠: 週 50h × 4 週は労基法 36 協定上限超え(45h × 12 月)。1 人法人 CEO は労基法対象外だが、健康面では週 60h を超えると過労リスク。
F59_HOURS_PER_MONTH_HARD_LIMITdefault を 240(週 60h)に上げるか、180(週 45h)に下げるか。シナリオ保存方式: v1 = URL クエリパラメータ、v2 =
40_scenario_registry永続化。マルチイヤー(MAS-067)と同型でシナリオ DB 統合するか、独立 spreadsheet シートにするか。HITL 承認モーダルの UX: 採用 / M&A の HITL は「承認ボタン押下」だけでは弱い。承認文言の自動生成(採用 1 名 → 「年間 754万のキャッシュアウト + 雇用契約 / 規程整備が必要 → 承認しますか?」)と承認履歴ログ(誰がいつ承認したか)を実装するか。
多通貨対応: 海外 M&A / 海外採用 / 海外配当の場合、現状 JPY hardcoding。商用化時に通貨切替(USD / JPY / EUR)を支援するか。
Capital レバー [M&A] の機会費用計算: M&A NPV は買収後 5 年シナジーを
_annuityFactor_(5, hurdle)で割引。実運用では PMI 失敗リスク(IRR ベース 30% 失敗確率)を反映する確率調整 NPV に拡張するか。シミュレーション履歴の AI レビュー: 4 レバー組合せの「過去 X 回試行で何を選んだか」を記録し、Gemini Deep Think で「あなたは Pricing レバーを過大評価する傾向があります」等のメタ分析を提供するか(v3 拡張)。
限界利益スタックドバーの色彩設計: 4 レバー(Pricing 青 / Product 緑 / Human 橙 / Capital 紫)+ base 灰の 5 色。色覚多様性対応で模様 / パターン併用するか。
月間稼働時間ラインチャートの軸: 縦軸 = h/月、横軸 = Y0-Y5。Soft 160 / Hard 200 のしきい値ラインは赤 / 黄の 2 本。月次粒度(Y3M6 等)に粒度を細かくするかは v2 拡張余地(短期は縮退)。
実装プロンプト(Claude Code 用)
Claude Opus 4.7(1M context)推奨。4 純粋関数レバー + UI 統合 + sync-engines + bootstrap + sys_params の複合実装。
## 案件
MAS-059 v2.0 — 1 人コンサルタント 非連続成長シミュレーター(4 レバー成長戦略)
## 事前調査(必ず Read する)
1. `docs/dev/dev_mas-059_growth_planning_workspace.md` 全文(本仕様書 v2.0)
2. `400_domain/445_required_revenue_solver.js` 全文(純粋関数 IIFE 名前空間 / `evaluateScenarioHealth`)
3. `400_domain/451_multiyear_planner.js` 全文(同型・5 年シミュ基盤)
4. `400_domain/454_compensation_strategy_engine.js` 全文(同型・`calcLimitProfit` を流用)
5. `400_domain/449_dividend_mix_optimizer.js` 全文(`_scrubInfinityForJSON_` の参照例)
6. `300_ui/302_spa_bridge.js` 全文(特に末尾の `_scrubInfinityForJSON_` 汎用ヘルパ)
7. `webapp_client/src/cockpit-main.tsx`(副作用 import 規約)
8. `webapp_client/src/cockpit/calc.ts`(client-side 計算 hub)
9. `webapp_client/src/cockpit/CompensationDropdowns.tsx`(離散単位ドロップダウン UI 規約)
10. `webapp_client/scripts/sync-engines.mjs`(`ENGINES_TO_SYNC` 配列規約)
11. `100_config/101_sys_config.js`(`confSheet.appendRow` パターン)
12. `docs/_internal/failure_patterns.md` #18-#20 / #25 / #26 / #29 / #31 / #33
## 実装対象(Phase 1-3 段階実装)
Phase 1 (0.5 ヶ月): 純粋関数エンジン
1. `400_domain/446_growth_strategy_engine.js` 新規(IIFE 名前空間 GrowthStrategyEngine):
- simulatePricingLever(input)
- simulateProductLever(input)
- simulateHumanLever(input)
- simulateCapitalLever(input)
- runGrowthStrategy(input) — 統合 API
- 内部ヘルパ: _annuityFactor_ / _rankByNpv_ / _buildStackedBarData_ / _buildHoursLineData_ / _formatJpy_
2. `webapp_client/scripts/sync-engines.mjs` の ENGINES_TO_SYNC に 446 追加
Phase 2 (0.5 ヶ月): React UI Panel
3. `webapp_client/src/cockpit/GrowthStrategyPanel.tsx` 新規:
- 左: 4 sliders (Pricing / Product / Human / Capital・各 0-5 離散)
- 右上: LimitProfitStackedBar (Y0-Y5)
- 右下: MonthlyHoursLineChart (Y0-Y5 + soft/hard limit)
- 下部: BudgetOverWarningBanner + FeasibilityIndicator + HitlBadge
4. `webapp_client/src/cockpit/calc.ts` の calcGrowthStrategy 公開
5. `webapp_client/src/cockpit-main.tsx` に副作用 import 追加
Phase 3 (0.5 ヶ月): 設定 / メニュー / テスト
6. `300_ui/302_spa_bridge.js` の _buildF59CockpitBootstrap_ 追加 + bootstrap merge
7. `100_config/101_sys_config.js` に F59_* 12 キー seed 追加
8. `000_infra/002_constants.js` の MENU_DEFINITION に「🚀 成長戦略シミュレーター」追加
9. `900_test/901_test_runner.js` に F059-01〜F059-18 単体テスト追加
## 動作確認
1. dev で push:dev → cockpit を開く → GrowthStrategyPanel が表示される
2. 全レバー = 0 で base のみ表示・warnings なし
3. Pricing+30% で deltaProfit ≈ +85万・churn 21% 警告
4. Human レバー [採用 1 名] で HITL モーダル発動
5. Capital レバー再投資 ROIC 10% で「閾値割れ」warning
6. 全レバー max で feasibility 'infeasible' + 予算オーバー
7. F059-01〜F059-18 全 PASS
8. URL クエリパラメータ ?growthStrategy=p3,p2,h1,c2 でレベル復元
## デプロイ(Phase 1-3 統合)
1. dev で push:dev → メニュー「🚀 成長戦略シミュレーター」or cockpit から表示
2. Go なら push:prod
3. コミット: feat(MAS-059 v2.0): 1 人コンサル 非連続成長シミュレーター (4 レバー: Pricing/Product/Human/Capital)
## failure_patterns チェック
- #18-#20: simulatePricingLever / simulateProductLever / simulateHumanLever / simulateCapitalLever / runGrowthStrategy を Read で裏取り(既存 simulate* と整合)
- #25: 445/449/451/454 と純粋関数 + IIFE パターン対称
- #26: appsscript.json は v2.0 で変更なし
- #29: _scrubInfinityForJSON_ を bootstrap 配信前に通す
- #31: 446 slot は v1.x で予約済(v2.0 で再利用)・448 は MAS-061 で予約済
- #33: cockpit-main.tsx に副作用 import 必須
推奨実行モデル
| 工程 | 推奨モデル | 根拠 |
|---|---|---|
| Phase 1 GrowthStrategyEngine 純粋関数(4 レバー + 統合 API + 内部ヘルパ) | Claude Opus 4.7 (1M context) | 4 レバー独立純粋関数の設計 + Buffett-Munger 階層 NPV ロジック + Infinity 防御 |
| Phase 2 React UI Panel(4 sliders + 2 charts + warning banners) | Claude Opus 4.7 (1M context) | 大規模 UI 設計 + recharts/d3 ライブラリ選定 + レスポンシブ |
| Phase 3 sys_params seed + メニュー + 単体テスト | Claude Sonnet 4.6 | パターン化された seed + テスト追加 |
| マイグレーション 8XX_migration_f59_*(任意・v2 でシナリオ DB 化時のみ) | Claude Haiku 4.5 | 800_ops 既存パターン流用 |
| 仕様書レビュー | Gemini 3 Pro Preview + Deep Think | 第三者視点での 4 レバー妥当性 + 物理時間ガード + バフェット階層検証 |
§A 旧 v1.x スコープ(アーカイブ・参考)
⚠️ 注意: 以下は v1.0-v1.1(2026-04-27/28)の「統合意思決定ツリー UI + LangGraph + Cloud SQL Postgres checkpointer」スコープのアーカイブ。v2.0(2026-05-01 全面 scope reset)では本案件 MAS-059 から切り離され、必要に応じて別案件 MAS-361 候補(仮) としてカーブアウト可能。
A.1 旧 v1.x の核となるスコープ
400_domain/446_decision_tree_orchestrator.js(純粋関数オーケストレーター・約 400 行)= MAS-058/MAS-012/MAS-048/MAS-017/MAS-056 の連鎖 APIwebapp_client/src/panels/GrowthPlanningWorkspace.tsx(左右分割 SPA UI = 左ツリー / 右入力)runDecisionLoop(input)= 必要年商 → 必要 HC → 採用 TCO → CF 制約違反 → Next Actions → HITL 制御- HITL 強制条件 + Autonomy Slider(Conservative / Balanced / Autonomous)
- シナリオ分岐管理(
40_scenario_registryに「親シナリオ ID」列追加 + 5 階層上限) - LangGraph + Cloud SQL Postgres checkpointer(Phase 4 拡張・月 $56-95)
- Causal AI(do-calculus エンジン)は不採用(DAG 思考フレームのみ採用 / arXiv 2506.00844 等)
- LLM に計算結果を復唱させない(Air Canada v. Moffatt 2024 BCCRT 149 型責任回避)
- 真のツリー UI は不採用(Runway 型カード並列 UI + Progressive Disclosure)
A.2 v2.0 で切り離した理由
- v1.x は「統合意思決定ループ全体を駆動するオーケストレーター」として大規模(5 既存エンジン結合 + LangGraph 移行ロードマップ)
- v2.0 ユーザー要望は「1 人コンサルが順調なのに天井で頭打ちになる課題に 4 レバーで突破するツール」というシンプルな成長戦略可視化(既存 cockpit の上位レイヤーとして 1 panel 追加)
- 両者はスコープ・実装規模・前提案件が大きく異なるため別案件として分離するのが筋
- v1.x は MAS-058 / MAS-067 / MAS-066 / MAS-071 が完了した今、「自動オーケストレーション」案件として独立起票が可能(MAS-361 候補)
A.3 v1.x キャリーオーバー先候補
| 候補案件 | 内容 |
|---|---|
| MAS-361(仮) | 旧 v1.x 全スコープを「意思決定ツリー オーケストレーター + LangGraph 統合」として独立起票。MAS-058/067/066/071 完了後の 第 5 cockpit として位置付け(MAS-057 単年 / MAS-067 マルチイヤー / MAS-072 EV / MAS-059 4 レバー / MAS-361 AI オーケストレーター) |
| MAS-059 v3 (将来) | 本 v2.0 の 4 レバー UI を v1.x のオーケストレーターでラップする統合形(1 人法人 GROWTH OS) |
A.4 v1.x の保存リソース
- 旧 spec 全文 (462 行 v1.1) は本ファイルの git 履歴 (commit 直前バージョン) で復元可能
- RQ-035 synthesis(LangGraph + Postgres / Causal AI 不採用 / Autonomy Slider)は
docs/_internal/research_prompts/RQ-035_*.mdで別途保存済み tasks/prompts/task_F-59.md(手動骨格・PR #350 起票時版)はtasks/prompts/で保存済み
変更履歴
| 日時 | バージョン | 変更内容 |
|---|---|---|
| 2026-04-27 | v0.1 (骨組み) | 初版骨組み作成。全セクション見出し + 概要テーブルのみ。ai_agent_tips.md §6 の章単位生成方針を準用。 |
| 2026-04-27 | v0.2 (本体) | 現在のコード(MAS-058/MAS-012/MAS-048/MAS-017/MAS-056/MAS-232 利用関数 6 個)+ 修正方針 6 Step 本文。JavaScript 疑似コードで runDecisionLoop を提示。 |
| 2026-04-27 | v0.3 (堅牢化) | 影響範囲 + 注意事項 14 項目 + エッジケース 13 + 実データ検証 5 本(齋藤 Baseline 連鎖 / HITL 発動 / LLM 数値整合性 / 5 階層上限 / F59-01〜F59-13)。 |
| 2026-04-27 | v1.0 (仕様書完了) | 関連ドキュメント 17 件 + 人間検討事項 14 + 実装プロンプト + 推奨実行モデル。前提案件 5 件のうち MAS-017 以外は仕様書完了済。 |
| 2026-04-28 | v1.1 (前提案件ステータス訂正) | MAS-012 ステータスを「📝 仕様書段階・未着手」に修正 + ⚠️ 警告コメント追加。 |
| 2026-05-01 | v2.0 (scope reset・4 レバー成長戦略へ全面書換) | ユーザー要望「1 人コンサルが順調なのに 1500-2000 万円台で頭打ち = 4 レバー(Pricing/Product/Human/Capital)の組合せで非連続成長を可視化」を受けスコープ全面リセット。Gemini Deep Research(2026-04-30)+ Claude 内部調査の突合により 4 レバー成長戦略フレーム(Pricing 弾力性 / Product 製品化 / Human 人的レバレッジ / Capital Buffett-Munger 階層)を採用。新規ファイル: 400_domain/446_growth_strategy_engine.js(純粋関数 IIFE 名前空間 / 4 レバー独立 + 統合 API・約 500 行)+ webapp_client/src/cockpit/GrowthStrategyPanel.tsx(左 4 スライダー + 右 限界利益スタックドバー / 月間稼働時間ライン + 予算オーバー警告・約 700 行)。ID 採番衝突回避(failure_patterns #31): ユーザー初期提案 448_growth_strategy_engine.js は MAS-061 で予約済で衝突発覚 → MAS-059 v1.x で予約していた 446 slot を v2.0 で再利用(v1.x の 446_decision_tree_orchestrator.js は §A アーカイブで実体未作成)。14 セクション全網羅: 概要 + 目的(4 レバーフレーム + 4 cockpit 関係)+ 現在のコード(前提案件 5 + 副作用 import 規約)+ 修正方針 7 Step(Engine / Panel / sync-engines / 副作用 import / calc.ts / spa_bridge bootstrap / 12 sys_params seed)+ 影響範囲(新規 2 / 変更 7)+ 注意事項 15 件(#31 ID 採番 / #18-#20 命名造語 / #25 並列対称性 / #26 OAuth / #29 Infinity / #33 副作用 import / 時間ハード上限 / Pricing 弾力性 / Product レベル定義 / Human HITL / Capital バフェット階層 / 限界利益積上げ / マイクロ M&A B/S / 予算しきい値 / シナリオ保存)+ エッジケース 18 件 + テスト F059-01〜F059-18 + 関連ドキュメント 14 件 + 人間検討事項 14 件 + 実装プロンプト(Claude Opus 4.7 向け・事前調査 12 / Phase 1-3)+ 推奨実行モデル + §A 旧 v1.x スコープのアーカイブ(LangGraph + Postgres + Decision Tree Orchestrator は MAS-361 候補としてキャリーオーバー)。docs-only PR で prod 自動デプロイへの影響なし。 |