# ============================================================ # Explore 边界扩展黄金测试(plan.md §5.1 / 矩阵 55 行剩余项) # 覆盖:run_sensitivity 与 run_monte_carlo 经统一 Explore 通道执行, # 主干零污染(readonly 语义保持)。 # ============================================================ from __future__ import annotations import json from pathlib import Path from server.aps_domain.robustness import run_monte_carlo from server.aps_domain.sensitivity import run_sensitivity FIXTURE = Path(__file__).resolve().parents[2] / "server" / "data" / "world.json" def _load_world() -> dict: import json as _json if FIXTURE.exists(): return _json.loads(FIXTURE.read_text(encoding="utf-8")) from server.state.seed import seed_world return seed_world() def test_sensitivity_through_unified_channel_no_mutation(): """run_sensitivity 经 run_explore:主干世界逐字节不变(Explore 铁律)。""" world = _load_world() before = json.dumps(world, ensure_ascii=False, sort_keys=True) report = run_sensitivity(world, strategy="COMPREHENSIVE") assert "rows" in report and "baseline" in report after = json.dumps(world, ensure_ascii=False, sort_keys=True) assert before == after, "sensitivity 不得污染主干" def test_monte_carlo_through_unified_channel_no_mutation(): """run_monte_carlo 经 run_explore:主干零污染,输出含 outcomes。""" world = _load_world() before = json.dumps(world, ensure_ascii=False, sort_keys=True) result = run_monte_carlo(world, strategy="COMPREHENSIVE", engine_type="RULE", trials=3) assert result["method"] == "fixed-seed-monte-carlo" assert len(result["outcomes"]) == 3 after = json.dumps(world, ensure_ascii=False, sort_keys=True) assert before == after, "monte carlo 不得污染主干" def test_sensitivity_readonly_world_blocks_write(): """Explore 工具若尝试写主干(经 readonly_view)必须 fail closed。""" from server.aps_domain.explore_boundary import readonly_view world = _load_world() view = readonly_view(world) try: view["salesOrders"] = [] raise AssertionError("应抛 PermissionError") except PermissionError: pass assert world.get("salesOrders") is not None