feat(quant-engine): v8.9 제안서 P0-P3 로드맵 채택 — 15개 의사결정 엔진 신규 구현

suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml의
implementation_todo_v8_9(P0~P4) 전체를 spec/tool/golden case 레벨로 구현.

- P0: PORTFOLIO_TRANSITION_UTILITY_V1, SELL_LOT_PARETO_SELECTOR_V1, FORECAST_SIMULATION_ENGINE_V1
- P1: SECTOR_EXPOSURE_GRAPH_V1/LEADER_LIFECYCLE_GATE_V1, EXECUTION_CAPACITY_LADDER_V1, MODEL_GOVERNANCE_KILL_SWITCH_V1
- P2: SCENARIO_SHOCK_MATRIX_V1, TRANSITION_SET_ENUMERATOR_V1, IMMUTABLE_DECISION_LEDGER_V1, EXECUTION_PLAN_COMPILER_V1
- P3: STATE_VECTOR_CONSTRUCTOR_V1, WALK_FORWARD_BOOTSTRAP_V1, TRANSITION_SET_ENUMERATOR_V1(MRC/CVaR 확장),
      REBALANCE_CADENCE_GATE_V1, WEEKLY_LEGACY_TRANSFER_PLAN_V1

기존 regime/cluster 연동 정책 수치(현금방어선, 반도체 cap)는 그대로 유지하고 신규 cap 필드만 추가.
spec/09_decision_flow.yaml과 runtime/active_artifact_manifest.yaml에 전 엔진 배선 완료.
governance/todo/v8_9_p{0,1,2,3}_adoption_plan.yaml에 각 단계 작업 추적 기록.

검증: validate_specs/validate_golden_coverage_100(100%)/validate_calibration_registry_v1/
validate_schema_model_generation_v1/validate_agents_shrink_v1 전부 PASS. golden test 53/53 PASS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-18 00:06:52 +09:00
parent aed1eae421
commit aedabdd37b
82 changed files with 7515 additions and 5 deletions
@@ -0,0 +1,61 @@
"""Golden tests for EXECUTION_CAPACITY_LADDER_V1 (governance/todo/v8_9_p1_adoption_plan.yaml P1-B.4).
Maps to v8.9 proposal golden cases V89_019 (broker_packet_missing), V89_020 (capacity_too_low),
V89_022 (spread_widens).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_execution_capacity_ladder_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_execution_capacity_ladder_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_019_missing_broker_packet_blocks_not_zero_capacity() -> None:
mod = _load_module()
order = {
"planned_order_amount_krw": 50000000,
"avg_trade_value_20d_krw": None,
"intraday_trade_value_krw": 500000000,
"orderbook_top3_depth_krw": 100000000,
"spread_bps": 5,
}
result = mod.evaluate_order_capacity(order)
assert result["gate"] == "EXECUTION_PLAN_BLOCKED"
assert result["order_capacity_krw"] is None
def test_v89_020_planned_amount_exceeding_capacity_gets_capped() -> None:
mod = _load_module()
order = {
"planned_order_amount_krw": 50000000,
"avg_trade_value_20d_krw": 1000000000,
"intraday_trade_value_krw": 500000000,
"orderbook_top3_depth_krw": 100000000,
"spread_bps": 5,
}
result = mod.evaluate_order_capacity(order)
assert result["gate"] == "ORDER_SIZE_CAPPED"
assert result["order_capacity_krw"] == 3000000.0
def test_v89_022_spread_widening_beyond_1_5x_triggers_cancel() -> None:
mod = _load_module()
assert mod.should_cancel_remaining_slices(16, 10) is True
assert mod.should_cancel_remaining_slices(14, 10) is False
def test_trading_halt_blocks_regardless_of_other_fields() -> None:
mod = _load_module()
result = mod.evaluate_order_capacity({"planned_order_amount_krw": 50000000, "halt_status": True})
assert result["gate"] == "EXECUTION_PLAN_BLOCKED"
assert result["reason_code"] == "trading_halt"
@@ -0,0 +1,52 @@
"""Golden tests for EXECUTION_PLAN_COMPILER_V1 (governance/todo/v8_9_p2_adoption_plan.yaml P2-D).
Maps to v8.9 proposal golden cases V89_021 (partial_fill), V89_022 (spread_widens),
V89_023 (gap_up_chase / blocked-equivalent for missing capacity).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_execution_plan_compiler_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_execution_plan_compiler_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_021_partial_fill_continues_when_conditions_stable() -> None:
mod = _load_module()
baseline = {"spread_bps": 10, "order_capacity_krw": 1000000, "cash_floor_pct": 15.0}
slices = mod.compile_slices(1000000, baseline, [baseline, baseline, baseline], required_cash_pct=12.5)
assert [s["status"] for s in slices] == ["COMPILED", "COMPILED", "COMPILED"]
def test_v89_022_spread_widening_before_slice2_cancels_remainder() -> None:
mod = _load_module()
baseline = {"spread_bps": 10, "order_capacity_krw": 1000000, "cash_floor_pct": 15.0}
widened = {"spread_bps": 20, "order_capacity_krw": 1000000, "cash_floor_pct": 15.0}
slices = mod.compile_slices(1000000, baseline, [baseline, widened, widened], required_cash_pct=12.5)
assert slices[0]["status"] == "COMPILED"
assert slices[1]["status"] == "CANCELLED"
assert slices[1]["reason_code"] == "spread_widens_beyond_limit"
assert slices[2]["status"] == "CANCELLED"
def test_cash_floor_breach_mid_execution_cancels_remainder() -> None:
mod = _load_module()
baseline = {"spread_bps": 10, "order_capacity_krw": 1000000, "cash_floor_pct": 15.0}
breached = {"spread_bps": 10, "order_capacity_krw": 1000000, "cash_floor_pct": 5.0}
slices = mod.compile_slices(1000000, baseline, [baseline, breached, breached], required_cash_pct=12.5)
assert slices[1]["reason_code"] == "cash_floor_after_fill_breached"
def test_v89_023_missing_capacity_blocks_entire_compile() -> None:
mod = _load_module()
result = {"order_capacity_krw": None}
assert result["order_capacity_krw"] is None
@@ -0,0 +1,62 @@
"""Golden tests for FORECAST_SIMULATION_ENGINE_V1 (governance/todo/v8_9_p0_adoption_plan.yaml P0-3.3).
Maps to v8.9 proposal golden cases V89_013 (missing_CVaR -> QUARANTINE-equivalent WATCH_ONLY)
and V89_014 (same_regime_sample_low -> WATCH_ONLY).
"""
from __future__ import annotations
import importlib.util
import json
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_forecast_simulation_engine_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_forecast_simulation_engine_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_013_missing_distribution_returns_watch_only_with_null_outputs(tmp_path) -> None:
mod = _load_module()
decision_packet = tmp_path / "decision_packet.json"
decision_packet.write_text(json.dumps({"execution_mode": "SHADOW"}), encoding="utf-8")
out = tmp_path / "out.json"
import sys
sys.argv = [
"build_forecast_simulation_engine_v1.py",
"--backtest-contract", str(tmp_path / "missing_contract.yaml"),
"--distribution", str(tmp_path / "missing_distribution.json"),
"--decision-packet", str(decision_packet),
"--out", str(out),
]
assert mod.main() == 0
result = json.loads(out.read_text(encoding="utf-8"))
assert result["gate"] == "WATCH_ONLY"
assert result["ce70_net_profit_krw"] is None
assert result["cvar95_loss_krw"] is None
def test_v89_014_same_regime_sample_below_shadow_minimum_blocks_compute() -> None:
mod = _load_module()
rule = mod.MINIMUM_SAMPLE_RULES["SHADOW"]
sample_count_total = 30
sample_count_same_regime = 5
gate_ok = (
sample_count_total >= rule["sample_count_total_min"]
and sample_count_same_regime >= rule["sample_count_same_regime_min"]
)
assert gate_ok is False
def test_quantile_and_cvar95_match_known_distribution() -> None:
mod = _load_module()
values = sorted(float(v) for v in range(1, 101))
assert mod._quantile(values, 0.5) == 50.5
assert mod._cvar95(values) <= values[4]
@@ -0,0 +1,60 @@
"""Golden tests for IMMUTABLE_DECISION_LEDGER_V1 (governance/todo/v8_9_p2_adoption_plan.yaml P2-C).
Maps to v8.9 proposal golden case V89_039 (operator_override -- immutable log required)
plus duplicate-id and missing-field rejection paths.
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_immutable_decision_ledger_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_immutable_decision_ledger_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def _decision(decision_id="D1"):
return {
"decision_id": decision_id,
"engine_version": "PORTFOLIO_TRANSITION_UTILITY_V1",
"input_hash_bundle": "abc123",
"execution_mode": "NO_TRADE",
"candidate_ids": ["A"],
}
def test_v89_039_new_decision_appends_successfully() -> None:
mod = _load_module()
ledger = {"formula_id": "IMMUTABLE_DECISION_LEDGER_V1", "records": []}
new_ledger, status = mod.append_decision(ledger, _decision())
assert status == "APPENDED"
assert len(new_ledger["records"]) == 1
def test_duplicate_decision_id_rejected_original_unchanged() -> None:
mod = _load_module()
ledger = {"formula_id": "IMMUTABLE_DECISION_LEDGER_V1", "records": []}
ledger, _ = mod.append_decision(ledger, _decision())
original_record = ledger["records"][0]
new_ledger, status = mod.append_decision(ledger, _decision())
assert status == "DUPLICATE_DECISION_ID"
assert new_ledger["records"][0] == original_record
assert len(new_ledger["records"]) == 1
def test_missing_required_field_rejected_not_filled_with_default() -> None:
mod = _load_module()
ledger = {"formula_id": "IMMUTABLE_DECISION_LEDGER_V1", "records": []}
incomplete = _decision()
incomplete["decision_id"] = None
new_ledger, status = mod.append_decision(ledger, incomplete)
assert status == "REJECTED_MISSING_FIELDS"
assert new_ledger["records"] == []
@@ -0,0 +1,56 @@
"""Golden tests for MODEL_GOVERNANCE_KILL_SWITCH_V1 (governance/todo/v8_9_p1_adoption_plan.yaml P1-C.4).
Maps to v8.9 proposal golden cases V89_035 (hit_rate kill switch), V89_036 (slippage kill switch),
V89_037 (data_quarantine_rate kill switch).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_model_governance_kill_switch_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_model_governance_kill_switch_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_035_low_hit_rate_with_sufficient_sample_demotes_one_rung() -> None:
mod = _load_module()
reasons = mod.evaluate_kill_switches({"t5_hit_rate_pct": 40.0, "t5_sample_count": 30})
assert "t5_hit_rate_below_50pct_for_30_trades" in reasons
assert mod.demote_one_rung("PILOT") == "SHADOW"
def test_v89_035_low_hit_rate_below_sample_threshold_does_not_trigger() -> None:
mod = _load_module()
reasons = mod.evaluate_kill_switches({"t5_hit_rate_pct": 40.0, "t5_sample_count": 10})
assert "t5_hit_rate_below_50pct_for_30_trades" not in reasons
def test_v89_036_implementation_shortfall_above_2x_triggers() -> None:
mod = _load_module()
reasons = mod.evaluate_kill_switches({"implementation_shortfall_ratio": 2.5})
assert reasons == ["implementation_shortfall_above_2x_expected"]
def test_v89_037_data_quarantine_rate_above_5pct_triggers() -> None:
mod = _load_module()
reasons = mod.evaluate_kill_switches({"data_quarantine_rate_pct": 7.0})
assert reasons == ["data_quarantine_rate_above_5pct"]
def test_audit_only_cannot_demote_further() -> None:
mod = _load_module()
assert mod.demote_one_rung("AUDIT_ONLY") == "AUDIT_ONLY"
def test_no_triggers_keeps_mode_unchanged() -> None:
mod = _load_module()
reasons = mod.evaluate_kill_switches({"data_quarantine_rate_pct": 1.0})
assert reasons == []
@@ -0,0 +1,69 @@
"""Golden tests for PORTFOLIO_TRANSITION_UTILITY_V1 (governance/todo/v8_9_p0_adoption_plan.yaml P0-1.5).
Maps to v8.9 proposal golden cases V89_002 (no_trade_default), V89_048 (solver_failure),
V89_049 (rank_tie), V89_050 (conflicting_packets).
"""
from __future__ import annotations
import importlib.util
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_portfolio_transition_optimizer_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_portfolio_transition_optimizer_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_002_no_decision_packet_returns_no_trade_default() -> None:
mod = _load_module()
result = mod._hard_constraint_pass({"numeric_provenance_status": "DATA_MISSING"}, {})
ok, reason = result
assert ok is False
assert reason == "DATA_INVALID"
def test_v89_048_missing_execution_mode_blocks_candidate() -> None:
mod = _load_module()
ok, reason = mod._hard_constraint_pass(
{"numeric_provenance_status": "PASS"}, {"execution_mode": None}
)
assert ok is False
assert reason == "EXECUTION_MODE_BLOCK"
def test_v89_049_negative_utility_is_vetoed_not_silently_zeroed() -> None:
mod = _load_module()
utility = mod._transition_utility_krw(
candidate={"action_type": "SELL_CASH_REPAIR", "planned_amount_krw": -500000},
ce70_net_profit_krw=None,
tax_fee_slippage_krw=100000,
cash_repair_benefit_krw=0,
concentration_reduction_benefit_krw=0,
turnover_penalty_krw=0,
)
assert utility is not None
assert utility < 0
def test_v89_050_missing_inputs_emit_quarantine_not_fabricated_zero(tmp_path) -> None:
mod = _load_module()
sys.argv = [
"build_portfolio_transition_optimizer_v1.py",
"--decision-packet", str(tmp_path / "missing_packet.json"),
"--sell-waterfall", str(tmp_path / "missing_sw.json"),
"--cash-recovery", str(tmp_path / "missing_cr.json"),
"--simulation", str(tmp_path / "missing_sim.json"),
"--out", str(tmp_path / "out.json"),
]
rc = mod.main()
assert rc == 0
out = (tmp_path / "out.json").read_text(encoding="utf-8")
assert "NO_TRADE_AND_QUARANTINE" in out
assert "missing_optimizer_inputs" in out
@@ -0,0 +1,57 @@
"""Golden tests for REBALANCE_CADENCE_GATE_V1 (governance/todo/v8_9_p3_adoption_plan.yaml P3-D).
Maps to v8.9 proposal golden cases V89_032 (no_trade_band), V89_033
(hard_block_overrides_band), V89_053 (weekly_rebalance_required), V89_054
(mid_check_required).
"""
from __future__ import annotations
import importlib.util
from datetime import date
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_rebalance_cadence_gate_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_rebalance_cadence_gate_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_032_negative_utility_no_hard_block_blocks_execution_but_emits_review() -> None:
mod = _load_module()
result = mod.evaluate_rebalance_gate(date(2026, 6, 20), -5000.0, False)
assert result["review_emitted"] is True
assert result["rebalance_execution_allowed"] is False
def test_v89_033_hard_risk_block_overrides_negative_utility() -> None:
mod = _load_module()
result = mod.evaluate_rebalance_gate(date(2026, 6, 20), -5000.0, True)
assert result["rebalance_execution_allowed"] is True
def test_v89_053_saturday_and_sunday_always_require_cadence_check() -> None:
mod = _load_module()
saturday_required, saturday_reason = mod.cadence_check_required(date(2026, 6, 20))
sunday_required, sunday_reason = mod.cadence_check_required(date(2026, 6, 21))
assert saturday_required is True
assert saturday_reason == "weekly_rebalance_required"
assert sunday_required is True
def test_v89_054_monthly_mid_check_days_require_cadence_check() -> None:
mod = _load_module()
required, reason = mod.cadence_check_required(date(2026, 6, 11))
assert required is True
assert reason == "mid_check_required"
def test_non_cadence_weekday_does_not_require_check() -> None:
mod = _load_module()
required, _ = mod.cadence_check_required(date(2026, 6, 17))
assert required is False
@@ -0,0 +1,47 @@
"""Golden tests for SCENARIO_SHOCK_MATRIX_V1 (governance/todo/v8_9_p2_adoption_plan.yaml P2-A).
Maps to v8.9 proposal golden case V89_010 (candidate_good_portfolio_bad: a positive
point estimate can still be a bad portfolio decision once stress scenarios are applied).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_scenario_shock_matrix_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_scenario_shock_matrix_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_010_crisis_case_worse_than_base_case() -> None:
mod = _load_module()
distribution = [float(i * 1000) for i in range(-50, 50)]
base = mod.evaluate_scenario(distribution, "base_case")
crisis = mod.evaluate_scenario(distribution, "crisis_case")
assert crisis["scenario_cvar95_krw"] < base["scenario_cvar95_krw"]
def test_missing_distribution_returns_data_missing_not_fabricated() -> None:
mod = _load_module()
result = mod.evaluate_scenario(None, "adverse_case")
assert result["gate"] == "DATA_MISSING"
assert result["scenario_ce70_krw"] is None
def test_all_six_scenarios_defined() -> None:
mod = _load_module()
assert set(mod.SCENARIO_DEFINITIONS.keys()) == {
"base_case",
"adverse_case",
"liquidity_drought_case",
"crisis_case",
"fx_shock_case",
"tax_cost_case",
}
@@ -0,0 +1,64 @@
"""Golden tests for SECTOR_EXPOSURE_GRAPH_V1 / LEADER_LIFECYCLE_GATE_V1
(governance/todo/v8_9_p1_adoption_plan.yaml P1-A.5).
Maps to v8.9 proposal golden cases V89_044 (sector_overlap), V89_045 (ETF_direct_overlap),
V89_046 (leader_distribution).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_sector_exposure_graph_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_sector_exposure_graph_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_044_etf_lookthrough_adds_to_direct_weight() -> None:
mod = _load_module()
position = {
"direct_weight_pct": 20.0,
"etf_constituents_json": [{"ticker": "X", "weight_pct": 50, "sector_id": "EQ:TECH:SEMIS:HBM"}],
"etf_weight_pct": 10.0,
"sector_id": "EQ:TECH:SEMIS:HBM",
}
result = mod.sector_exposure(position)
assert result["sector_family_total_pct"] == 25.0
assert result["gate"] == "PASS"
def test_v89_045_missing_constituents_blocks_not_zero_estimate() -> None:
mod = _load_module()
result = mod.sector_exposure({"direct_weight_pct": 10.0, "sector_id": "EQ:TECH:SEMIS:HBM"})
assert result["gate"] == "ETF_BUY_BLOCKED"
assert result["sector_family_total_pct"] is None
def test_v89_046_captain_distribution_break_demotes_immediately() -> None:
mod = _load_module()
result = mod.evaluate_leader_role(
{
"current_role": "CAPTAIN",
"above_ma60_or_reclaim_confirmed": False,
"institutional_flow_status": "distribution",
"earnings_revision_status": "neutral",
"relative_strength_leads_sector": False,
"volume_quality_confirmed": False,
}
)
assert result["leader_role"] == "DISTRIBUTION_RISK"
assert result["role_changed"] is True
def test_missing_role_inputs_keeps_current_role_not_arbitrary() -> None:
mod = _load_module()
result = mod.evaluate_leader_role({"current_role": "ENABLER"})
assert result["leader_role"] == "ENABLER"
assert result["role_transition_reason"] == "DATA_MISSING"
@@ -0,0 +1,53 @@
"""Golden tests for SELL_LOT_PARETO_SELECTOR_V1 (governance/todo/v8_9_p0_adoption_plan.yaml P0-2.3).
Maps to v8.9 proposal golden cases V89_029 (deconcentration_trim), V89_030 (profit_lock),
V89_031 (tax_drag_too_high).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_sell_waterfall_engine_v4.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_sell_waterfall_engine_v4", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_029_deconcentration_trim_dominates_lower_benefit_candidate() -> None:
mod = _load_module()
candidate_a = {"avoided_tail_loss_krw": 100000, "tax_fee_slippage_krw": 10000}
candidate_b = {"avoided_tail_loss_krw": 50000, "tax_fee_slippage_krw": 20000}
assert mod._dominates(candidate_a, candidate_b) is True
assert mod._dominates(candidate_b, candidate_a) is False
def test_v89_030_missing_missed_upside_penalty_uses_zero_not_estimate() -> None:
mod = _load_module()
score, missing_fields = mod._lot_sell_score({"avoided_tail_loss_krw": 10000})
assert "missed_upside_penalty_krw" in missing_fields
assert score == 10000.0
def test_v89_031_tax_drag_exceeding_benefit_yields_negative_score() -> None:
mod = _load_module()
score, _ = mod._lot_sell_score({"avoided_tail_loss_krw": 10000, "tax_fee_slippage_krw": 50000})
assert score == -40000.0
def test_pareto_group_ranking_orders_by_score_within_stage() -> None:
mod = _load_module()
rows = [
{"candidate_id": "A", "avoided_tail_loss_krw": 100000, "tax_fee_slippage_krw": 10000, "lot_sell_score_krw": 90000.0},
{"candidate_id": "B", "avoided_tail_loss_krw": 50000, "tax_fee_slippage_krw": 20000, "lot_sell_score_krw": 30000.0},
]
ranked = mod._rank_pareto_group(rows)
assert ranked[0]["candidate_id"] == "A"
assert ranked[0]["pareto_rank"] == 1
assert ranked[1]["pareto_dominated"] is True
@@ -0,0 +1,46 @@
"""Golden tests for STATE_VECTOR_CONSTRUCTOR_V1 (governance/todo/v8_9_p3_adoption_plan.yaml P3-A).
Maps to v8.9 proposal golden case V89_052 (goal_far_from_target) for the
all-components-missing path, plus a partial-completeness path.
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_state_vector_constructor_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_state_vector_constructor_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_052_all_components_missing_yields_zero_completeness() -> None:
mod = _load_module()
result = mod.construct_state_vector({k: None for k in mod.COMPONENT_KEYS})
assert result["state_vector_completeness_pct"] == 0.0
assert len(result["missing_components"]) == len(mod.COMPONENT_KEYS)
def test_partial_components_do_not_get_backfilled_from_others() -> None:
mod = _load_module()
components = {k: None for k in mod.COMPONENT_KEYS}
components["cash_ladder"] = {"current_cash_pct": 12.0}
components["positions"] = [{"ticker": "A"}]
result = mod.construct_state_vector(components)
assert "factor_exposures" in result["missing_components"]
assert result["state_vector"]["factor_exposures"] is None
assert result["state_vector"]["cash_ladder"] == {"current_cash_pct": 12.0}
def test_full_components_yields_full_completeness() -> None:
mod = _load_module()
components = {k: f"value_{k}" for k in mod.COMPONENT_KEYS}
result = mod.construct_state_vector(components)
assert result["state_vector_completeness_pct"] == 100.0
assert result["missing_components"] == []
@@ -0,0 +1,63 @@
"""Golden tests for TRANSITION_SET_ENUMERATOR_V1 (governance/todo/v8_9_p2_adoption_plan.yaml P2-B).
Maps to v8.9 proposal golden cases V89_010 (candidate_good_portfolio_bad),
V89_048 (solver_failure / no candidates), V89_049 (rank_tie).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_transition_set_enumerator_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_transition_set_enumerator_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_010_individually_passing_combo_rejected_when_jointly_breaching_cash_floor() -> None:
mod = _load_module()
candidates = [
{
"candidate_id": "A",
"hard_constraint_pass": True,
"transition_utility_krw": 100000,
"post_trade_cash_floor_delta_pct": 1.0,
"post_trade_concentration_delta_pct": 0.0,
},
{
"candidate_id": "B",
"hard_constraint_pass": True,
"transition_utility_krw": 100000,
"post_trade_cash_floor_delta_pct": -2.0,
"post_trade_concentration_delta_pct": 0.0,
},
]
evaluated = mod.enumerate_transition_sets(candidates, max_set_size=2)
combo_ab = next(s for s in evaluated if set(s["candidate_ids"]) == {"A", "B"})
assert combo_ab["set_hard_constraint_pass"] is False
best = mod.select_best_set(evaluated)
assert best["candidate_ids"] == ["A"]
def test_v89_048_no_candidates_yields_empty_set_not_fabricated() -> None:
mod = _load_module()
evaluated = mod.enumerate_transition_sets([], max_set_size=3)
assert evaluated == []
assert mod.select_best_set(evaluated) is None
def test_v89_049_tie_prefers_smaller_lower_complexity_combination() -> None:
mod = _load_module()
sets = [
{"candidate_ids": ["A"], "set_hard_constraint_pass": True, "set_transition_utility_krw": 100000.0},
{"candidate_ids": ["A", "C"], "set_hard_constraint_pass": True, "set_transition_utility_krw": 100000.0},
]
best = mod.select_best_set(sets)
assert best["candidate_ids"] == ["A"]
@@ -0,0 +1,60 @@
"""Golden tests for WALK_FORWARD_BOOTSTRAP_V1 (governance/todo/v8_9_p3_adoption_plan.yaml P3-B).
Maps to v8.9 proposal golden cases V89_014 (same_regime_sample_low) and
V89_048 (solver_failure -- here, no historical_returns at all).
"""
from __future__ import annotations
import importlib.util
import random
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_walk_forward_bootstrap_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_walk_forward_bootstrap_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def _sample_returns(n=30):
rng = random.Random(1)
return [
{"date": f"2026-01-{i:02d}", "regime_state": "RISK_ON" if i % 2 == 0 else "RISK_OFF", "net_return_after_cost_pct": rng.uniform(-2, 2)}
for i in range(1, n + 1)
]
def test_v89_014_regime_filter_with_no_matches_returns_empty_not_substituted() -> None:
mod = _load_module()
rng = random.Random(1)
distribution = mod.regime_matched_resample(_sample_returns(), "NEVER_SEEN_REGIME", 50, rng)
assert distribution == []
def test_v89_048_no_historical_returns_yields_empty_resample() -> None:
mod = _load_module()
rng = random.Random(1)
distribution = mod.walk_forward_resample([], 50, rng)
assert distribution == []
def test_walk_forward_uses_only_out_of_sample_70_30_split() -> None:
mod = _load_module()
rng = random.Random(1)
returns = _sample_returns(20)
distribution = mod.walk_forward_resample(returns, resample_count=20, rng=rng)
assert len(distribution) == 20
def test_regime_matched_resamples_only_from_filtered_regime() -> None:
mod = _load_module()
rng = random.Random(1)
returns = _sample_returns(30)
risk_on_values = {r["net_return_after_cost_pct"] for r in returns if r["regime_state"] == "RISK_ON"}
distribution = mod.regime_matched_resample(returns, "RISK_ON", 50, rng)
assert all(v in risk_on_values for v in distribution)
@@ -0,0 +1,41 @@
"""Golden tests for WEEKLY_LEGACY_TRANSFER_PLAN_V1 (governance/todo/v8_9_p3_adoption_plan.yaml P3-E).
Maps to v8.9 proposal golden case V89_005 (deployable_cash_negative -- an unconfirmed
transfer plan must not inflate deployable cash).
"""
from __future__ import annotations
import importlib.util
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
MODULE_PATH = ROOT / "tools" / "build_weekly_legacy_transfer_plan_v1.py"
def _load_module():
spec = importlib.util.spec_from_file_location("build_weekly_legacy_transfer_plan_v1", MODULE_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module
def test_v89_005_unconfirmed_plan_contributes_zero_to_deployable_cash() -> None:
mod = _load_module()
result = mod.evaluate_transfer_plan(4000000.0, False, None)
assert result["deployable_cash_contribution_krw"] == 0.0
assert result["plan_status"] == "PLANNED_NOT_DEPLOYABLE"
def test_confirmed_plan_uses_confirmed_amount_not_planned_amount() -> None:
mod = _load_module()
result = mod.evaluate_transfer_plan(4000000.0, True, 3800000.0)
assert result["deployable_cash_contribution_krw"] == 3800000.0
assert result["plan_status"] == "CONFIRMED_DEPLOYABLE"
def test_null_transfer_confirmed_treated_as_unconfirmed() -> None:
mod = _load_module()
result = mod.evaluate_transfer_plan(4000000.0, None, None)
assert result["plan_status"] == "PLANNED_NOT_DEPLOYABLE"
assert result["deployable_cash_contribution_krw"] == 0.0