fix(task-25): page_setup_truth and settings_pdf_mediabox_a3 move the sheet to ANSI B before proving A3

A fresh Layout1 is already ISO A3 landscape (ezdxf R2018 default: 420 x 297,
plot_rotation 0), so an A3-only /MediaBox read-back passed with
page_setup_apply stubbed to a no-op: the A/B gate row and the v4 matrix task
could not fail on the setter. Both now apply ANSI B (432 x 279, a size no
fresh document has; spec section 9 names it) and read that PDF first, then
apply ISO A3, read its PDF, and require the setter's changed.size_mm to have
moved from B to A3. The stub fails at the first PDF.

The moved-sheet comparison is +/-0.5 mm, the spec's tolerance, not exact:
measured live on AutoCAD 2026 (scratch Documents.Add(), closed unsaved), the
COM engine reports ANSI B as 431.8 x 279.4 and the DWG To PDF.pc3 file's
MediaBox as 431.8 x 279.4 then 420.158 x 297.039 for A3; the task passes
there with changed.size_mm [[431.8, 279.4], [420.0, 297.0]]. Headless it is
[[432.0, 279.0], [420.0, 297.0]].

tests/test_benchmark_v4.py gains the mutation test the finding describes
(setter stubbed -> both rows must fail; both passed on the old code) and a
run of the gate row itself; the headless task test asserts the B stage.
README rows and the tasks_v4 docstring say what the task now does; the README
collected-tests figure follows the two new tests (3282 -> 3284). The
regenerated A/B report against v1.5.1 is byte-identical (26 -> 32/32).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-22 13:27:17 +03:00
co-authored by Claude Opus 5
parent c2942d3c94
commit 18c7c69da6
6 changed files with 134 additions and 14 deletions
+55
View File
@@ -67,3 +67,58 @@ async def test_page_setup_truth_passes_headlessly(tmp_path):
assert passed, metrics
assert abs(metrics["mediabox_mm"][0] - 420.0) < 0.5
assert abs(metrics["mediabox_mm"][1] - 297.0) < 0.5
# The stage that makes the task falsifiable: the sheet was ANSI B first.
assert abs(metrics["mediabox_mm_before"][0] - 432.0) < 0.5
assert abs(metrics["mediabox_mm_before"][1] - 279.0) < 0.5
assert metrics["size_mm_changed"] == [[432.0, 279.0], [420.0, 297.0]]
async def _noop_page_setup_apply(self, layout, setup):
"""A setter that writes nothing and claims success."""
return {
"ok": True,
"layout": layout,
"applied": dict(setup),
"changed": {},
"warnings": [],
"plot_style_known": True,
"viewports_kept": True,
"backend": "ezdxf",
}
@pytest.mark.asyncio
async def test_page_setup_truth_fails_when_the_setter_writes_nothing(tmp_path, monkeypatch):
"""A fresh Layout1 is already ISO A3 landscape (ezdxf's R2018 default: 420 x 297,
rotation 0), so a task that only reads A3 back from the PDF cannot tell a
working setter from a stub. Both gate rows must fail with the stub."""
pytest.importorskip("matplotlib", reason="rendering needs the [pdf] extra")
from backends.ezdxf_backend import EzdxfBackend
from benchmarks import correctness_suite
from benchmarks.adapters.autocad_mcp_pro import AutoCADMCPProAdapter
monkeypatch.setattr(EzdxfBackend, "page_setup_apply", _noop_page_setup_apply)
assert await correctness_suite.settings_pdf_mediabox_a3() is False
adapter = AutoCADMCPProAdapter(backend="ezdxf")
await adapter.setup(tmp_path)
try:
await adapter._reset()
passed, metrics, _artifacts = await adapter._task_page_setup_truth()
finally:
await adapter.cleanup()
assert passed is False, metrics
# The stub's own evidence: the "ANSI B" PDF is still the default A3 sheet.
assert abs(metrics["mediabox_mm_before"][0] - 420.0) < 0.5
assert metrics["size_mm_changed"] is None
@pytest.mark.asyncio
async def test_correctness_check_settings_pdf_mediabox_a3_passes():
"""The A/B gate row itself, run once here: ANSI B plotted at 432 x 279,
then ISO A3 at 420 x 297, each read from its own PDF."""
pytest.importorskip("matplotlib", reason="rendering needs the [pdf] extra")
from benchmarks import correctness_suite
assert await correctness_suite.settings_pdf_mediabox_a3() is True