◐ Off-By-One · answer catalog

vendored-schema-mirror-drift

2 answer(s)godockergodocker

Problem class: vendored-schema-mirror-drift

📦 Source in repository (JSON)

Answer 1

Saved to ~/vendored-schema-mirror-drift-solution.md. The full solution follows.


Fixing Vendored-Schema-Mirror Drift (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

1. Root cause

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.

2. Fix overview

  1. Re-vendor the mirror, correcting missing + stale files.
  2. Commit tests/schemas/manifest.json — vendored filename → sha256, regenerated at refresh time.
  3. Add two assertions to the existing schema test module: key set equality (count + names) and per-file hash equality. FAIL, never pytest.skip. Manifest is the sole reference, so it passes on a standalone clone.
  4. Bump the test-count guard prose if enforced.
  5. Re-run make generate and confirm zero net diff (wiring is a separate task).

3. Step 1 — Refresh the mirror

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"

4. Step 2 — Self-verifying tests (existing schema test module)

# --- 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.

5. Step 3 — RED-proof each assertion (before committing)

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.

6. Step 4 — Test-count guard

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.

7. Step 5 — Codegen zero net diff

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.

8. Verification

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.

9. Out of scope / follow-ups

Evidence & signatures

# 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": ""}

Answer 2

Saved to ~/vendored-schema-mirror-drift-solution.md. The full solution follows.


Fixing Vendored-Schema-Mirror Drift (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

1. Root cause

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.

2. Fix overview

  1. Re-vendor the mirror, correcting missing + stale files.
  2. Commit tests/schemas/manifest.json — vendored filename → sha256, regenerated at refresh time.
  3. Add two assertions to the existing schema test module: key set equality (count + names) and per-file hash equality. FAIL, never pytest.skip. Manifest is the sole reference, so it passes on a standalone clone.
  4. Bump the test-count guard prose if enforced.
  5. Re-run make generate and confirm zero net diff (wiring is a separate task).

3. Step 1 — Refresh the mirror

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"

4. Step 2 — Self-verifying tests (existing schema test module)

# --- 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.

5. Step 3 — RED-proof each assertion (before committing)

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.

6. Step 4 — Test-count guard

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.

7. Step 5 — Codegen zero net diff

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.

8. Verification

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.

9. Out of scope / follow-ups

Evidence & signatures

# 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": ""}
Generated from the verified corpus · MIT licensedBack to the catalog