From 86278df08d07ac7c08af339f3afc0b6713ae14a8 Mon Sep 17 00:00:00 2001 From: sprooty Date: Sat, 17 Oct 2026 10:16:00 +0000 Subject: [PATCH 1/2] fix(parity): use a fixed scratch root for the MCP run (WI-1075) The audit payload_digest covers the absolute root_path a project is registered at. The MCP run used a random temp directory, so every digest over a registered project changed from run to run, in both cores. The output already shows the root as ; only the digest saw the path. The MCP run now uses a fixed, cleared-before-and-after scratch path. Runs are sequential, so the path is safe to reuse. With it, Python and Rust produce identical MCP digests (checked line by line, 6 digests). The 21c95f6 MCP golden is not re-recorded here: its digests were taken at a random path and will differ until oversight re-records it. Signed-off-by: sprooty Co-Authored-By: Claude Haiku 5.5 --- scripts/parity.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/scripts/parity.py b/scripts/parity.py index 6fe0d318..5d1b094a 100644 --- a/scripts/parity.py +++ b/scripts/parity.py @@ -20,6 +20,7 @@ from __future__ import annotations import argparse +import contextlib import difflib import json import os @@ -30,6 +31,7 @@ import tempfile import threading import time +from collections.abc import Iterator from datetime import UTC, datetime from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path @@ -168,6 +170,18 @@ def _run( return _run_cli(binary, steps) +@contextlib.contextmanager +def _fixed_scratch(name: str) -> Iterator[Path]: + """A scratch directory at a fixed path, cleared before and after use.""" + path = Path(tempfile.gettempdir()) / name + shutil.rmtree(path, ignore_errors=True) + path.mkdir(parents=True) + try: + yield path + finally: + shutil.rmtree(path, ignore_errors=True) + + def _run_mcp(binary: str, steps: list[dict[str, Any]]) -> list[dict[str, Any]]: """Drive the steps that take parameters over MCP stdio. @@ -183,7 +197,11 @@ def _run_mcp(binary: str, steps: list[dict[str, Any]]) -> list[dict[str, Any]]: the HTTP login mints is random, and nothing in this transport captures it. """ steps = [step for step in steps if "params" in step or "dump" in step] - with tempfile.TemporaryDirectory(prefix="vogt-parity-mcp-") as scratch: + # The scratch root is fixed, not random: the audit payload digest covers the + # absolute root_path a project was registered at, so a random directory + # made every MCP digest differ from run to run. The output still shows it as + # . Runs are sequential, so one fixed path is safe to clear and reuse. + with _fixed_scratch("vogt-parity-mcp-fixed") as scratch: root = Path(scratch) data = root / "instance" env = _child_env() From e0d4300c282b1d6dcb47c6236f7c04ce60d3d5a3 Mon Sep 17 00:00:00 2001 From: sprooty Date: Sat, 17 Oct 2026 11:06:23 +0000 Subject: [PATCH 2/2] docs(port): disposition row for test_engine_image_core.py (WI-1078) #1085 added the test without a ledger row, so every_python_test_has_one_disposition failed on rust-core. Co-Authored-By: Claude Opus 5.5 Signed-off-by: sprooty --- docs/PYTHON_TEST_DISPOSITION.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/PYTHON_TEST_DISPOSITION.md b/docs/PYTHON_TEST_DISPOSITION.md index 3053e99e..2e12219c 100644 --- a/docs/PYTHON_TEST_DISPOSITION.md +++ b/docs/PYTHON_TEST_DISPOSITION.md @@ -58,6 +58,7 @@ gain tests; it does not move down. | test_diagnostics.py | ported | Instance diagnostics service. | | test_dispatch.py | unported | Dispatch profiles as data (WI-1323, migration 0024 path). Owner WI-1058. | | test_drift.py | ported | `application/drift.rs`. | +| test_engine_image_core.py | retired | Static checks on `engine/Dockerfile` and `engine/deploy/entrypoint.sh` (WI-1078). Engine image, not the core crate. | | test_engine_parity.py | retired | Rust engine wire parity. Owned by `engine/server` tests, not `engine/core`. | | test_fake_agent.py | retired | `scripts/fake-agent` test double for the engine. Not product behaviour. | | test_forge_accounts.py | ported | `adapters/forge/accounts.rs` and the forge-account service. |