feat(nonlinear-static-newton-raphson): step 0 - cli-output-lease-and-derived-names

This commit is contained in:
KOKO\Mimi
2026-08-24 10:42:14 +09:00
parent 41816c8aef
commit fc16ef6221
61 changed files with 10890 additions and 115 deletions
+125
View File
@@ -6,6 +6,17 @@ import pytest
from scripts import execute
def write_implementation_agent_profile(
root, *, model="gpt-5.6-terra", reasoning="xhigh"
):
profile = root / ".codex" / "agents" / "implementation-agent.toml"
profile.parent.mkdir(parents=True)
profile.write_text(
f'model = "{model}"\nmodel_reasoning_effort = "{reasoning}"\n',
encoding="utf-8",
)
def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "unicode-phase"
phase_dir.mkdir(parents=True)
@@ -20,6 +31,7 @@ def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("Euler–Bernoulli 보", encoding="utf-8")
write_implementation_agent_profile(tmp_path)
invocation = {}
@@ -40,6 +52,44 @@ def test_invoke_codex_uses_utf8_for_unicode_prompt(tmp_path, monkeypatch):
assert invocation["command"][sandbox_index + 1] == "workspace-write"
def test_invoke_codex_uses_implementation_agent_command_contract(
tmp_path, monkeypatch
):
phase_dir = tmp_path / "phases" / "agent-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "agent-phase",
"steps": [{"step": 0, "name": "agent", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("agent routing", encoding="utf-8")
write_implementation_agent_profile(tmp_path)
invocation = {}
def capture_run(command, **kwargs):
invocation["command"] = command
return subprocess.CompletedProcess(command, 0, stdout="", stderr="")
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setattr(execute.subprocess, "run", capture_run)
executor = execute.StepExecutor("agent-phase")
executor._invoke_codex({"step": 0, "name": "agent"}, "")
model_index = invocation["command"].index("--model")
config_index = invocation["command"].index("--config")
assert invocation["command"][model_index + 1] == "gpt-5.6-terra"
assert invocation["command"][config_index + 1] == 'model_reasoning_effort="xhigh"'
adjacent_arguments = list(zip(invocation["command"], invocation["command"][1:]))
assert ("--disable", "unified_exec") in adjacent_arguments
def test_invoke_codex_accepts_explicit_danger_full_access_override(
tmp_path, monkeypatch
):
@@ -56,6 +106,7 @@ def test_invoke_codex_accepts_explicit_danger_full_access_override(
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("sandbox override", encoding="utf-8")
write_implementation_agent_profile(tmp_path)
invocation = {}
@@ -74,6 +125,80 @@ def test_invoke_codex_accepts_explicit_danger_full_access_override(
assert invocation["command"][sandbox_index + 1] == "danger-full-access"
def test_invoke_codex_timeout_writes_structured_failure(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "timeout-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "timeout-phase",
"steps": [{"step": 0, "name": "timeout", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("timeout", encoding="utf-8")
write_implementation_agent_profile(tmp_path)
def timeout_run(command, **kwargs):
raise subprocess.TimeoutExpired(
command, kwargs["timeout"], output="partial stdout", stderr="partial stderr"
)
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setattr(execute.subprocess, "run", timeout_run)
executor = execute.StepExecutor("timeout-phase")
output = executor._invoke_codex({"step": 0, "name": "timeout"}, "")
assert output["exitCode"] == 124
assert output["stdout"] == "partial stdout"
assert "Codex timed out after 1800 seconds." in output["stderr"]
stored = json.loads((phase_dir / "step0-output.json").read_text(encoding="utf-8"))
assert stored == output
def test_execute_single_step_retries_structured_codex_timeout(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "retry-phase"
phase_dir.mkdir(parents=True)
(phase_dir / "index.json").write_text(
json.dumps(
{
"project": "FESA Structural Solver",
"phase": "retry-phase",
"steps": [{"step": 0, "name": "retry", "status": "pending"}],
}
),
encoding="utf-8",
)
(phase_dir / "step0.md").write_text("retry", encoding="utf-8")
write_implementation_agent_profile(tmp_path)
attempts = []
def timeout_run(command, **kwargs):
attempts.append(command)
raise subprocess.TimeoutExpired(command, kwargs["timeout"])
monkeypatch.setattr(execute, "ROOT", tmp_path)
monkeypatch.setattr(execute.subprocess, "run", timeout_run)
executor = execute.StepExecutor("retry-phase")
executor.MAX_RETRIES = 2
monkeypatch.setattr(executor, "_commit_step", lambda *args: None)
monkeypatch.setattr(executor, "_update_top_index", lambda *args: None)
with pytest.raises(SystemExit, match="1"):
executor._execute_single_step(
{"step": 0, "name": "retry", "status": "pending"}, ""
)
assert len(attempts) == 2
index = json.loads((phase_dir / "index.json").read_text(encoding="utf-8"))
assert index["steps"][0]["status"] == "error"
assert "Codex timed out after 1800 seconds." in index["steps"][0]["error_message"]
def test_invoke_codex_rejects_unknown_sandbox_override(tmp_path, monkeypatch):
phase_dir = tmp_path / "phases" / "sandbox-phase"
phase_dir.mkdir(parents=True)