Problem class: vendored-schema-mirror-drift
Saved to ~/vendored-schema-mirror-drift-solution.md. The full solution follows.
get-h3/sdk-python)Problem class: vendored-schema-mirror-drift
Verified commit: ea25da5 (2026-09-19) — pytest 193 passed / 1 skipped, diff -r empty, gitreins Tier2 PASS (verdict 7a88d91b)
Scope: tests/schemas/v1 mirror vs. pinned get-h3/protocol/schemas/v1
tests/schemas/v1 is a vendored copy of the protocol repo's schemas/v1. It was byte-identical when first written, but nothing in this repo ever asserted that (a) the set of vendored files was complete, or (b) the bytes of each vendored file matched the source.
The only refresh path was a CI step tied to protocol-release events:
cp protocol-src/schemas/v1/*.json tests/schemas/v1/
cp never removes stale files and the step never runs between releases. Silent drift resulted:
| Fact | Value |
|---|---|
Vendored *.json files |
15 |
Upstream *.json files |
17 |
| Missing from mirror | cancel-response.json, session-terminate-response.json |
| Stale content | test-report.json |
No test looked at completeness, so the suite stayed green. Downstream: codegen had no response models for the two missing schemas (the follow-up contract-violation row), and conformance tests structurally skipped absent schemas — a skip masks exactly this class of bug. The mirror's correctness was hopeful, not verified.
tests/schemas/manifest.json — vendored filename → sha256, regenerated at refresh time.pytest.skip. Manifest is the sole reference, so it passes on a standalone clone.make generate and confirm zero net diff (wiring is a separate task).scripts/refresh_schemas.py:
#!/usr/bin/env python3
"""Refresh tests/schemas/v1 from the pinned protocol source and regenerate
tests/schemas/manifest.json."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DEST = REPO_ROOT / "tests" / "schemas" / "v1"
MANIFEST = REPO_ROOT / "tests" / "schemas" / "manifest.json"
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def refresh(source: Path) -> int:
if not source.is_dir():
sys.exit(f"ERROR: protocol schema source not found: {source}")
src_files = {p.name: p for p in source.glob("*.json")}
if not src_files:
sys.exit(f"ERROR: no *.json files found in: {source}")
DEST.mkdir(parents=True, exist_ok=True)
expected = set(src_files)
for existing in DEST.glob("*.json"):
if existing.name not in expected:
existing.unlink()
for name, src in sorted(src_files.items()):
shutil.copy2(src, DEST / name)
manifest = {name: sha256(DEST / name) for name in sorted(src_files)}
MANIFEST.write_text(
json.dumps(manifest, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)
print(f"refreshed {len(manifest)} schema files -> {DEST.relative_to(REPO_ROOT)}")
print(f"wrote manifest -> {MANIFEST.relative_to(REPO_ROOT)}")
return len(manifest)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("source", nargs="?", default=None,
help="path to protocol schemas/v1 directory")
args = parser.parse_args()
if args.source:
source = Path(args.source).expanduser().resolve()
else:
env = os.environ.get("PROTOCOL_SCHEMA_SRC")
source = (Path(env).expanduser().resolve() if env
else (REPO_ROOT.parent / "protocol" / "schemas" / "v1").resolve())
refresh(source)
if __name__ == "__main__":
main()
Run + prove:
python scripts/refresh_schemas.py ../protocol/schemas/v1
PROTOCOL_SCHEMA_SRC="$PWD/protocol-src/schemas/v1" python scripts/refresh_schemas.py
SRC=../protocol/schemas/v1
diff -r tests/schemas/v1 "$SRC" # must print nothing
echo "vendored=$(find tests/schemas/v1 -name '*.json' | wc -l)"
echo "source =$(find "$SRC" -name '*.json' | wc -l)" # equal, 17 == 17
git add tests/schemas/v1 tests/schemas/manifest.json scripts/refresh_schemas.py
git commit -m "Refresh vendored protocol schema mirror and add sha256 manifest"
# --- schema mirror integrity -------------------------------------------------
import hashlib
import json
from pathlib import Path
SCHEMA_DIR = Path(__file__).resolve().parent / "schemas" / "v1"
MANIFEST_PATH = Path(__file__).resolve().parent / "schemas" / "manifest.json"
def _sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def _load_manifest() -> dict[str, str]:
return json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))
def test_schema_mirror_keyset_matches_manifest() -> None:
"""Vendored *.json names must equal the manifest key set (count + names)."""
manifest = _load_manifest()
vendored = {p.name for p in SCHEMA_DIR.glob("*.json")}
expected = set(manifest)
missing = sorted(expected - vendored)
extra = sorted(vendored - expected)
assert not missing, (
f"vendored schema dir is missing {len(missing)} manifest file(s): {missing}"
)
assert not extra, (
f"vendored schema dir has {len(extra)} file(s) absent from manifest: {extra}"
)
assert len(vendored) == len(expected), (
f"schema count mismatch: {len(vendored)} vendored vs {len(expected)} manifest"
)
def test_schema_mirror_hashes_match_manifest() -> None:
"""Every vendored file's sha256 must equal its manifest entry."""
manifest = _load_manifest()
vendored = {p.name: p for p in SCHEMA_DIR.glob("*.json")}
missing = sorted(set(manifest) - set(vendored))
assert not missing, f"cannot hash missing manifest file(s): {missing}"
mismatches = [
f"{name}: manifest={expected} vendored={_sha256(vendored[name])}"
for name, expected in sorted(manifest.items())
if _sha256(vendored[name]) != expected
]
assert not mismatches, "schema hash mismatch:\n" + "\n".join(mismatches)
No pytest.skip, no importorskip, no swallowing FileNotFoundError. Reuse the module's existing schema-dir constant if present.
python -m pytest tests/test_schemas.py -q
# (a) Remove a file -> key-set FAIL, not skip.
mv tests/schemas/v1/cancel-response.json /tmp/cancel-response.json
python -m pytest tests/test_schemas.py -q # EXPECT FAIL (missing)
mv /tmp/cancel-response.json tests/schemas/v1/cancel-response.json
# (b) Flip a hash -> FAIL printing BOTH digests.
cp tests/schemas/manifest.json /tmp/manifest.bak
python - <<'PY'
import json, pathlib
p = pathlib.Path("tests/schemas/manifest.json")
m = json.loads(p.read_text()); k = sorted(m)[0]; m[k] = "0" * 64
p.write_text(json.dumps(m, indent=2, sort_keys=True) + "\n")
PY
python -m pytest tests/test_schemas.py -q # EXPECT FAIL, both digests
cp /tmp/manifest.bak tests/schemas/manifest.json
# (c) Extra file -> key-set count/name FAIL.
echo '{}' > tests/schemas/v1/__rogue__.json
python -m pytest tests/test_schemas.py -q # EXPECT FAIL (extra)
rm tests/schemas/v1/__rogue__.json
python -m pytest tests/test_schemas.py -q # back to green
Confirm step (a) reports a failure with no skip for the schema tests.
pytest --collect-only -q | tail -n 1
grep -rn "OLD_COUNT" README.md CONTRIBUTING.md test-count.txt .github/ 2>/dev/null
bash scripts/check-test-count.sh
Bump every prose occurrence to the newly derived count. At the verified commit this is 193 passed / 1 skipped.
make generate
git status --porcelain # no generated-type changes
git diff --exit-code # exits 0
If generated files changed, that is out of scope — revert and treat wiring as follow-up.
diff -r tests/schemas/v1 ../protocol/schemas/v1 && \
[ "$(find tests/schemas/v1 -name '*.json' | wc -l)" = \
"$(find ../protocol/schemas/v1 -name '*.json' | wc -l)" ]
python -m pytest -q
ruff check .
ruff format --check .
bash scripts/check-test-count.sh
make generate && git diff --exit-code
Expected: diff -r empty, 17 == 17, 193 passed / 1 skipped, ruff clean, guard PASS, zero net diff.
Standalone-clone proof (no sibling):
rm -rf /tmp/sdk-verify && git clone . /tmp/sdk-verify && cd /tmp/sdk-verify
ls ../protocol 2>/dev/null && echo "UNEXPECTED sibling" || echo "no sibling present"
python -m pytest -q # green, manifest-only reference
RED-proof transcript:
| Mutation | Expected | Observed |
|---|---|---|
Remove cancel-response.json |
key-set FAIL, no skip | FAIL, not skip |
| Flip a manifest hash | hash FAIL, both digests | FAIL, both digests |
Add __rogue__.json |
key-set FAIL | FAIL |
| Restore all | green | PASS |
Recorded outcome: commit ea25da5; 193 passed / 1 skipped; diff -r empty 17=17; gitreins Tier2 PASS (verdict 7a88d91b), including the no-sibling clone run.
cancel-response.json and session-terminate-response.json into codegen/response models — the mirror fix intentionally yields zero generated diff; that downstream contract row is separate.protocol-release.# Evidence - Problem class: vendored-schema-mirror-drift - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T14:46:23.669Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "FIX (verified end-to-end, judge verdict 7a88d91b tier1+tier2 PASS): (1) Refresh the mirror from the pinned protocol source (cp missing + stale files; prove with `diff -r <vendored> <source>` empty and equal file counts). (2) Commit a manifest (tests/schemas/manifest.json) mapping every vendored filename to its sha256, regenerated at refresh time by a small refresh script. (3) Add tests in the EXISTING schema test module that assert (a) the vendored *.json key set equals the manifest key set (count + names) and (b) every file's sha256 equals the manifest entry \u2014 FAIL, never pytest.skip, on missing/mismatched files; the manifest is the reference so the suite runs on a standalone clone with no sibling checkout (proved by copying the repo to /tmp without the sibling and running the tests: passed). RED-proof each assertion before committing: remove a file -> fail not skip; flip a hash -> fail printing both digests; add an extra file -> key-set fail. (4) If the repo enforces a test-count guard (check-test-count.sh deriving suite size from live pytest collection and comparing against prose in README/CONTRIBUTING/test-count.txt), bump every prose occurrence of the old count or CI goes red. (5) Re-run codegen (make generate) and confirm zero net diff \u2014 a mirror refresh alone must not change generated types unless the new schemas are wired in (that is a separate task). Gates: full pytest green, ruff check+format clean, count guard PASS.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "vendored-schema-mirror-drift", "provider": "openrouter", "solved_at": "2026-09-19T14:46:23.669Z", "version": ""}Saved to ~/vendored-schema-mirror-drift-solution.md. The full solution follows.
get-h3/sdk-python)Problem class: vendored-schema-mirror-drift
Verified commit: ea25da5 (2026-09-19) — pytest 193 passed / 1 skipped, diff -r empty, gitreins Tier2 PASS (verdict 7a88d91b)
Scope: tests/schemas/v1 mirror vs. pinned get-h3/protocol/schemas/v1
tests/schemas/v1 is a vendored copy of the protocol repo's schemas/v1. It was byte-identical when first written, but nothing in this repo ever asserted that (a) the set of vendored files was complete, or (b) the bytes of each vendored file matched the source.
The only refresh path was a CI step tied to protocol-release events:
cp protocol-src/schemas/v1/*.json tests/schemas/v1/
cp never removes stale files and the step never runs between releases. Silent drift resulted:
| Fact | Value |
|---|---|
Vendored *.json files |
15 |
Upstream *.json files |
17 |
| Missing from mirror | cancel-response.json, session-terminate-response.json |
| Stale content | test-report.json |
No test looked at completeness, so the suite stayed green. Downstream: codegen had no response models for the two missing schemas (the follow-up contract-violation row), and conformance tests structurally skipped absent schemas — a skip masks exactly this class of bug. The mirror's correctness was hopeful, not verified.
tests/schemas/manifest.json — vendored filename → sha256, regenerated at refresh time.pytest.skip. Manifest is the sole reference, so it passes on a standalone clone.make generate and confirm zero net diff (wiring is a separate task).scripts/refresh_schemas.py:
#!/usr/bin/env python3
"""Refresh tests/schemas/v1 from the pinned protocol source and regenerate
tests/schemas/manifest.json."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import shutil
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[1]
DEST = REPO_ROOT / "tests" / "schemas" / "v1"
MANIFEST = REPO_ROOT / "tests" / "schemas" / "manifest.json"
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def refresh(source: Path) -> int:
if not source.is_dir():
sys.exit(f"ERROR: protocol schema source not found: {source}")
src_files = {p.name: p for p in source.glob("*.json")}
if not src_files:
sys.exit(f"ERROR: no *.json files found in: {source}")
DEST.mkdir(parents=True, exist_ok=True)
expected = set(src_files)
for existing in DEST.glob("*.json"):
if existing.name not in expected:
existing.unlink()
for name, src in sorted(src_files.items()):
shutil.copy2(src, DEST / name)
manifest = {name: sha256(DEST / name) for name in sorted(src_files)}
MANIFEST.write_text(
json.dumps(manifest, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)
print(f"refreshed {len(manifest)} schema files -> {DEST.relative_to(REPO_ROOT)}")
print(f"wrote manifest -> {MANIFEST.relative_to(REPO_ROOT)}")
return len(manifest)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("source", nargs="?", default=None,
help="path to protocol schemas/v1 directory")
args = parser.parse_args()
if args.source:
source = Path(args.source).expanduser().resolve()
else:
env = os.environ.get("PROTOCOL_SCHEMA_SRC")
source = (Path(env).expanduser().resolve() if env
else (REPO_ROOT.parent / "protocol" / "schemas" / "v1").resolve())
refresh(source)
if __name__ == "__main__":
main()
Run + prove:
python scripts/refresh_schemas.py ../protocol/schemas/v1
PROTOCOL_SCHEMA_SRC="$PWD/protocol-src/schemas/v1" python scripts/refresh_schemas.py
SRC=../protocol/schemas/v1
diff -r tests/schemas/v1 "$SRC" # must print nothing
echo "vendored=$(find tests/schemas/v1 -name '*.json' | wc -l)"
echo "source =$(find "$SRC" -name '*.json' | wc -l)" # equal, 17 == 17
git add tests/schemas/v1 tests/schemas/manifest.json scripts/refresh_schemas.py
git commit -m "Refresh vendored protocol schema mirror and add sha256 manifest"
# --- schema mirror integrity -------------------------------------------------
import hashlib
import json
from pathlib import Path
SCHEMA_DIR = Path(__file__).resolve().parent / "schemas" / "v1"
MANIFEST_PATH = Path(__file__).resolve().parent / "schemas" / "manifest.json"
def _sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def _load_manifest() -> dict[str, str]:
return json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))
def test_schema_mirror_keyset_matches_manifest() -> None:
"""Vendored *.json names must equal the manifest key set (count + names)."""
manifest = _load_manifest()
vendored = {p.name for p in SCHEMA_DIR.glob("*.json")}
expected = set(manifest)
missing = sorted(expected - vendored)
extra = sorted(vendored - expected)
assert not missing, (
f"vendored schema dir is missing {len(missing)} manifest file(s): {missing}"
)
assert not extra, (
f"vendored schema dir has {len(extra)} file(s) absent from manifest: {extra}"
)
assert len(vendored) == len(expected), (
f"schema count mismatch: {len(vendored)} vendored vs {len(expected)} manifest"
)
def test_schema_mirror_hashes_match_manifest() -> None:
"""Every vendored file's sha256 must equal its manifest entry."""
manifest = _load_manifest()
vendored = {p.name: p for p in SCHEMA_DIR.glob("*.json")}
missing = sorted(set(manifest) - set(vendored))
assert not missing, f"cannot hash missing manifest file(s): {missing}"
mismatches = [
f"{name}: manifest={expected} vendored={_sha256(vendored[name])}"
for name, expected in sorted(manifest.items())
if _sha256(vendored[name]) != expected
]
assert not mismatches, "schema hash mismatch:\n" + "\n".join(mismatches)
No pytest.skip, no importorskip, no swallowing FileNotFoundError. Reuse the module's existing schema-dir constant if present.
python -m pytest tests/test_schemas.py -q
# (a) Remove a file -> key-set FAIL, not skip.
mv tests/schemas/v1/cancel-response.json /tmp/cancel-response.json
python -m pytest tests/test_schemas.py -q # EXPECT FAIL (missing)
mv /tmp/cancel-response.json tests/schemas/v1/cancel-response.json
# (b) Flip a hash -> FAIL printing BOTH digests.
cp tests/schemas/manifest.json /tmp/manifest.bak
python - <<'PY'
import json, pathlib
p = pathlib.Path("tests/schemas/manifest.json")
m = json.loads(p.read_text()); k = sorted(m)[0]; m[k] = "0" * 64
p.write_text(json.dumps(m, indent=2, sort_keys=True) + "\n")
PY
python -m pytest tests/test_schemas.py -q # EXPECT FAIL, both digests
cp /tmp/manifest.bak tests/schemas/manifest.json
# (c) Extra file -> key-set count/name FAIL.
echo '{}' > tests/schemas/v1/__rogue__.json
python -m pytest tests/test_schemas.py -q # EXPECT FAIL (extra)
rm tests/schemas/v1/__rogue__.json
python -m pytest tests/test_schemas.py -q # back to green
Confirm step (a) reports a failure with no skip for the schema tests.
pytest --collect-only -q | tail -n 1
grep -rn "OLD_COUNT" README.md CONTRIBUTING.md test-count.txt .github/ 2>/dev/null
bash scripts/check-test-count.sh
Bump every prose occurrence to the newly derived count. At the verified commit this is 193 passed / 1 skipped.
make generate
git status --porcelain # no generated-type changes
git diff --exit-code # exits 0
If generated files changed, that is out of scope — revert and treat wiring as follow-up.
diff -r tests/schemas/v1 ../protocol/schemas/v1 && \
[ "$(find tests/schemas/v1 -name '*.json' | wc -l)" = \
"$(find ../protocol/schemas/v1 -name '*.json' | wc -l)" ]
python -m pytest -q
ruff check .
ruff format --check .
bash scripts/check-test-count.sh
make generate && git diff --exit-code
Expected: diff -r empty, 17 == 17, 193 passed / 1 skipped, ruff clean, guard PASS, zero net diff.
Standalone-clone proof (no sibling):
rm -rf /tmp/sdk-verify && git clone . /tmp/sdk-verify && cd /tmp/sdk-verify
ls ../protocol 2>/dev/null && echo "UNEXPECTED sibling" || echo "no sibling present"
python -m pytest -q # green, manifest-only reference
RED-proof transcript:
| Mutation | Expected | Observed |
|---|---|---|
Remove cancel-response.json |
key-set FAIL, no skip | FAIL, not skip |
| Flip a manifest hash | hash FAIL, both digests | FAIL, both digests |
Add __rogue__.json |
key-set FAIL | FAIL |
| Restore all | green | PASS |
Recorded outcome: commit ea25da5; 193 passed / 1 skipped; diff -r empty 17=17; gitreins Tier2 PASS (verdict 7a88d91b), including the no-sibling clone run.
cancel-response.json and session-terminate-response.json into codegen/response models — the mirror fix intentionally yields zero generated diff; that downstream contract row is separate.protocol-release.# Evidence - Problem class: vendored-schema-mirror-drift - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-09-19T14:46:23.669Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "FIX (verified end-to-end, judge verdict 7a88d91b tier1+tier2 PASS): (1) Refresh the mirror from the pinned protocol source (cp missing + stale files; prove with `diff -r <vendored> <source>` empty and equal file counts). (2) Commit a manifest (tests/schemas/manifest.json) mapping every vendored filename to its sha256, regenerated at refresh time by a small refresh script. (3) Add tests in the EXISTING schema test module that assert (a) the vendored *.json key set equals the manifest key set (count + names) and (b) every file's sha256 equals the manifest entry \u2014 FAIL, never pytest.skip, on missing/mismatched files; the manifest is the reference so the suite runs on a standalone clone with no sibling checkout (proved by copying the repo to /tmp without the sibling and running the tests: passed). RED-proof each assertion before committing: remove a file -> fail not skip; flip a hash -> fail printing both digests; add an extra file -> key-set fail. (4) If the repo enforces a test-count guard (check-test-count.sh deriving suite size from live pytest collection and comparing against prose in README/CONTRIBUTING/test-count.txt), bump every prose occurrence of the old count or CI goes red. (5) Re-run codegen (make generate) and confirm zero net diff \u2014 a mirror refresh alone must not change generated types unless the new schemas are wired in (that is a separate task). Gates: full pytest green, ruff check+format clean, count guard PASS.", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "vendored-schema-mirror-drift", "provider": "openrouter", "solved_at": "2026-09-19T14:46:23.669Z", "version": ""}