fix(harness): Codex functional review 修复 — 命名/集成测试/delta_min/promote 消息

- _apply_env_overrides → _apply_env_var_overrides,docstring 明确从 os.environ 读取
- 新增 TestLoadConfigRealYaml:用真实 config/default.yaml 验证嵌套 harness 解析
- 新增 test_delta_min_negative_rejected:覆盖 gate_delta_min >= 0 校验
- 恢复 promote 模式独立错误消息(从合并分支分离回 TRM4 原始提示)
- 77 个单元测试全部通过,radon 全部 Grade B 或更好

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-07 12:23:27 -04:00
parent ce43871828
commit b929a5db6c
2 changed files with 42 additions and 5 deletions
+7 -4
View File
@@ -179,10 +179,12 @@ def _validate_mode_deps(config: RunConfig) -> None:
异常: 异常:
ValueError: 模式依赖字段缺失。 ValueError: 模式依赖字段缺失。
""" """
if config.mode in ("diagnose", "evolve", "promote") and not config.run_id: if config.mode in ("diagnose", "evolve") and not config.run_id:
raise ValueError(f"mode 为 {config.mode!r} 时必须提供 run_id。") raise ValueError(f"mode 为 {config.mode!r} 时必须提供 run_id。")
if config.mode in ("eval", "promote") and not config.version: if config.mode in ("eval", "promote") and not config.version:
raise ValueError(f"mode 为 {config.mode!r} 时必须提供 --version。") raise ValueError(f"mode 为 {config.mode!r} 时必须提供 --version。")
if config.mode == "promote" and not config.run_id:
raise ValueError("promote 必须提供 --run-id(指定 canonical eval run)。")
_validate_train_run_id(config) _validate_train_run_id(config)
@@ -363,9 +365,10 @@ def _validate_gate_ladder(config: RunConfig) -> None:
raise ValueError(f"gate_guard_err 须在 (0,1),实际: {config.gate_guard_err}") raise ValueError(f"gate_guard_err 须在 (0,1),实际: {config.gate_guard_err}")
def _apply_env_overrides(data: dict) -> None: def _apply_env_var_overrides(data: dict) -> None:
"""将 .env 工程配置环境变量覆盖到配置字典中(原地修改)。 """从环境变量覆盖路径字段(原地修改)。
.env 文件由入口脚本 load_dotenv 加载到环境变量,本函数仅从 os.environ 读取。
仅覆盖 _ENV_FIELD_MAP 中声明的工程配置字段(workspace_dir、store_dir)。 仅覆盖 _ENV_FIELD_MAP 中声明的工程配置字段(workspace_dir、store_dir)。
参数: 参数:
@@ -404,7 +407,7 @@ def load_config(
yaml_data: dict = raw.get("harness", raw) yaml_data: dict = raw.get("harness", raw)
# Phase 2: .env 覆盖层(仅工程配置字段) # Phase 2: .env 覆盖层(仅工程配置字段)
_apply_env_overrides(yaml_data) _apply_env_var_overrides(yaml_data)
# Phase 3: CLI 覆盖层(最高优先级) # Phase 3: CLI 覆盖层(最高优先级)
valid_fields = {f.name for f in dataclasses.fields(RunConfig)} valid_fields = {f.name for f in dataclasses.fields(RunConfig)}
+35 -1
View File
@@ -169,7 +169,7 @@ class TestModeValidation:
def test_promote_requires_run_id_and_version(self) -> None: def test_promote_requires_run_id_and_version(self) -> None:
"""promote 模式需同时提供 run_id 和 version。""" """promote 模式需同时提供 run_id 和 version。"""
cfg = _make_config(mode="promote", run_id="", version="v1") cfg = _make_config(mode="promote", run_id="", version="v1")
with pytest.raises(ValueError, match="run.id"): with pytest.raises(ValueError, match="promote.*run-id"):
_validate(cfg) _validate(cfg)
def test_train_mode_requires_run_id_without_resume_fresh(self) -> None: def test_train_mode_requires_run_id_without_resume_fresh(self) -> None:
@@ -359,6 +359,12 @@ class TestGateValidation:
with pytest.raises(ValueError, match="gate_w_net_min"): with pytest.raises(ValueError, match="gate_w_net_min"):
_validate(cfg) _validate(cfg)
def test_delta_min_negative_rejected(self) -> None:
"""gate_delta_min < 0 应抛出 ValueError。"""
cfg = _make_config(gate_delta_min=-0.1)
with pytest.raises(ValueError, match="gate_delta_min"):
_validate(cfg)
def test_lambda_dir_positive_rejected(self) -> None: def test_lambda_dir_positive_rejected(self) -> None:
"""gate_lambda_dir >= 0 应抛出 ValueError。""" """gate_lambda_dir >= 0 应抛出 ValueError。"""
cfg = _make_config(gate_lambda_dir=0.5) cfg = _make_config(gate_lambda_dir=0.5)
@@ -527,6 +533,34 @@ class TestLoadConfigEnvOverrides:
assert cfg.workspace_dir == Path("/cli/workspace") assert cfg.workspace_dir == Path("/cli/workspace")
# ──────────────────── test_load_config_real_yaml ─────────────────────────
class TestLoadConfigRealYaml:
"""用真实 config/default.yaml 验证 load_config 嵌套解析。"""
def test_load_config_real_default_yaml(self) -> None:
"""真实 config/default.yaml 的 harness 段应正确解析并通过校验。"""
cfg = load_config(Path("config/default.yaml"), {})
assert cfg.mode == "infer"
assert cfg.gate_e_confirm == 20.0
assert cfg.batch_size == 15
assert cfg.concurrency == 12
assert cfg.workspace_dir == Path("workspaces/default")
assert cfg.store_dir == Path("store")
assert cfg.skill_mode == "auto"
def test_real_yaml_cli_override(self) -> None:
"""真实 YAML + CLI 覆盖应正确合并。"""
cfg = load_config(
Path("config/default.yaml"),
{"concurrency": 4, "max_steps": 30},
)
assert cfg.concurrency == 4
assert cfg.max_steps == 30
assert cfg.mode == "infer" # 未覆盖字段保持 YAML 值
# ─────────────────────────── test_val_size_floor ───────────────────────── # ─────────────────────────── test_val_size_floor ─────────────────────────