personal memory agent
0

Configure Feed

Select the types of activity you want to include in your feed.

fix(native-sol): re-anchor Python deletion manifest to a reachable commit

The d777abe baseline is not reachable from main, so the deletion manifest fails in a fresh clone before it can validate blob drift.

Re-anchor to dd04f55c8, an ancestor that yields byte-identical blobs. EXPECTED_BLOBS and EXPECTED_SHA256 remain unchanged at 1bc5bbc3….

+111 -1
+1 -1
scripts/check_native_sol_python_manifest.py
··· 9 9 from pathlib import Path 10 10 11 11 REPO_ROOT = Path(__file__).resolve().parents[1] 12 - PRE_CUTOVER_COMMIT = "d777abeba213e167b18e9c7a646d112aa4b04ccd" 12 + PRE_CUTOVER_COMMIT = "dd04f55c8" 13 13 SURVIVING_SOL_CLI = "solstone/think/sol_cli.py" 14 14 15 15 # Pre-cutover deletion-owner manifest. `convey_client.py` is intentionally
+110
tests/test_native_sol_python_manifest.py
··· 1 + # SPDX-License-Identifier: AGPL-3.0-only 2 + # Copyright (c) 2026 sol pbc 3 + from __future__ import annotations 4 + 5 + import hashlib 6 + import subprocess 7 + import sys 8 + from pathlib import Path 9 + 10 + import pytest 11 + 12 + import scripts.check_native_sol_python_manifest as manifest 13 + 14 + 15 + def _git(repo: Path, *args: str) -> str: 16 + result = subprocess.run( 17 + ["git", *args], 18 + cwd=repo, 19 + check=True, 20 + capture_output=True, 21 + text=True, 22 + ) 23 + return result.stdout.strip() 24 + 25 + 26 + def _fixture_tree(repo: Path, files: dict[str, str]) -> tuple[str, dict[str, str]]: 27 + repo.mkdir() 28 + _git(repo, "init") 29 + blobs: dict[str, str] = {} 30 + for rel_path, text in files.items(): 31 + path = repo / rel_path 32 + path.parent.mkdir(parents=True, exist_ok=True) 33 + path.write_text(text, encoding="utf-8") 34 + blobs[rel_path] = _git(repo, "hash-object", str(path)) 35 + _git(repo, "add", *sorted(files)) 36 + tree = _git(repo, "write-tree") 37 + return tree, blobs 38 + 39 + 40 + def _digest(blobs: dict[str, str]) -> str: 41 + return hashlib.sha256( 42 + "".join(f"{path}\t{blob}\n" for path, blob in sorted(blobs.items())).encode( 43 + "utf-8" 44 + ) 45 + ).hexdigest() 46 + 47 + 48 + def _patch_manifest( 49 + monkeypatch: pytest.MonkeyPatch, 50 + *, 51 + repo: Path, 52 + tree: str, 53 + expected_blobs: dict[str, str], 54 + ) -> None: 55 + monkeypatch.setattr(manifest, "REPO_ROOT", repo) 56 + monkeypatch.setattr(manifest, "PRE_CUTOVER_COMMIT", tree) 57 + monkeypatch.setattr(manifest, "EXPECTED_BLOBS", dict(expected_blobs)) 58 + monkeypatch.setattr(manifest, "EXPECTED_SHA256", _digest(expected_blobs)) 59 + 60 + 61 + def _run_manifest_main() -> int: 62 + try: 63 + return manifest.main() 64 + except Exception as error: 65 + print(error, file=sys.stderr) 66 + return 1 67 + 68 + 69 + def test_manifest_main_fails_visibly_when_baseline_path_is_missing( 70 + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] 71 + ) -> None: 72 + repo = tmp_path / "repo" 73 + tree, blobs = _fixture_tree(repo, {"present.py": "print('present')\n"}) 74 + expected_blobs = {**blobs, "missing.py": "0" * 40} 75 + _patch_manifest( 76 + monkeypatch, 77 + repo=repo, 78 + tree=tree, 79 + expected_blobs=expected_blobs, 80 + ) 81 + 82 + exit_code = _run_manifest_main() 83 + 84 + captured = capsys.readouterr() 85 + assert exit_code == 1 86 + assert "git ls-tree returned 1 entries; missing: missing.py" in captured.err 87 + 88 + 89 + def test_manifest_main_fails_visibly_when_expected_blob_drifts( 90 + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] 91 + ) -> None: 92 + repo = tmp_path / "repo" 93 + tree, blobs = _fixture_tree(repo, {"present.py": "print('present')\n"}) 94 + expected_blobs = dict(blobs) 95 + expected_blobs["present.py"] = "0" * 40 96 + _patch_manifest( 97 + monkeypatch, 98 + repo=repo, 99 + tree=tree, 100 + expected_blobs=expected_blobs, 101 + ) 102 + 103 + exit_code = _run_manifest_main() 104 + 105 + captured = capsys.readouterr() 106 + assert exit_code == 1 107 + assert "native sol Python manifest blob drifted" in captured.err 108 + assert ( 109 + "present.py: expected 0000000000000000000000000000000000000000" in captured.err 110 + )