"""TDD — MPack schema must contain only pack fields. A pack carries commits + snapshots + objects + summary + meta + tags. Nothing else. The fields that were historically embedded in a "bundle" but belong in the HTTP layer must not appear in MPack: branch_heads → POST /push request body (which branch, what tip) pusher_id → Authorization header (MSign identity) declared_objects_count → POST /push request body (advisory integrity hint) These fields cannot live in the pack because the pack is content-addressed: pack_id = sha256(pack_bytes) Any push-specific metadata embedded in the bytes would make two identical content pushes produce different pack IDs — defeating content-addressing. Tests in this file are schema-level (TypedDict annotation checks) plus a round-trip assertion that build_mpack never emits the forbidden fields. """ from __future__ import annotations import json import pathlib import pytest from muse.core.mpack import MPack, build_mpack from muse.core.object_store import write_object from muse.core.paths import muse_dir from muse.core.ids import hash_commit as compute_commit_id, hash_snapshot as compute_snapshot_id from muse.core.refs import write_branch_ref from muse.core.commits import ( CommitRecord, write_commit, ) from muse.core.snapshots import ( SnapshotRecord, write_snapshot, ) from muse.core.types import blob_id # --------------------------------------------------------------------------- # Minimal repo fixture # --------------------------------------------------------------------------- @pytest.fixture() def repo(tmp_path: pathlib.Path) -> tuple[pathlib.Path, str]: """One-commit repo. Returns (root, commit_id).""" dot = muse_dir(tmp_path) dot.mkdir() (dot / "repo.json").write_text(json.dumps({"repo_id": "schema-test"})) for d in ("commits", "snapshots", "objects"): (dot / d).mkdir() (dot / "refs" / "heads").mkdir(parents=True) (dot / "HEAD").write_text("ref: refs/heads/main\n") (dot / "config.toml").write_text("") content = b"hello schema test" oid = blob_id(content) write_object(tmp_path, oid, content) manifest = {"src/hello.py": oid} sid = compute_snapshot_id(manifest) write_snapshot(tmp_path, SnapshotRecord(snapshot_id=sid, manifest=manifest)) import datetime ts = datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) cid = compute_commit_id( parent_ids=[], snapshot_id=sid, message="init", committed_at_iso=ts.isoformat(), author="gabriel", ) write_commit(tmp_path, CommitRecord( commit_id=cid, branch="main", snapshot_id=sid, message="init", committed_at=ts, parent_commit_id=None, parent2_commit_id=None, author="gabriel", metadata={}, structured_delta=None, sem_ver_bump="none", breaking_changes=[], agent_id="", model_id="", toolchain_id="", prompt_hash="", signature="", signer_key_id="", )) write_branch_ref(tmp_path, "main", cid) return tmp_path, cid # --------------------------------------------------------------------------- # Schema-level: forbidden fields must not be declared on MPack # --------------------------------------------------------------------------- _FORBIDDEN = {"branch_heads", "pusher_id", "declared_objects_count"} @pytest.mark.parametrize("field", sorted(_FORBIDDEN)) def test_mpack_bundle_type_does_not_declare_push_metadata(field: str) -> None: """MPack.__annotations__ must not contain push-layer metadata fields. These fields belong in the HTTP request body or Authorization header, not in the content-addressed pack bytes. """ assert field not in MPack.__annotations__, ( f"MPack declares '{field}' but that field belongs in the HTTP " f"layer, not the pack. Remove it from the TypedDict." ) # --------------------------------------------------------------------------- # Naming: BundleMeta must not exist — it is MPackMeta # --------------------------------------------------------------------------- def test_bundle_meta_name_does_not_exist() -> None: """BundleMeta is the old bundle-era name — it must not exist in muse.core.mpack.""" import importlib, muse.core.mpack as _mod assert not hasattr(_mod, "BundleMeta"), ( "BundleMeta still exists in muse.core.mpack — rename it to MPackMeta." ) def test_mpack_meta_name_exists() -> None: """MPackMeta is the canonical name for the pack metadata TypedDict.""" from muse.core.mpack import MPackMeta # noqa: F401 # --------------------------------------------------------------------------- # Naming: MPack must not exist — the type is MPack # --------------------------------------------------------------------------- def test_mpack_type_exists() -> None: """MPack is the canonical TypedDict for the wire artifact.""" from muse.core.mpack import MPack # noqa: F401 # --------------------------------------------------------------------------- # Runtime: build_mpack must never emit the forbidden fields # --------------------------------------------------------------------------- def test_build_mpack_does_not_emit_push_metadata( repo: tuple[pathlib.Path, str], ) -> None: """build_mpack() must return a dict free of push-layer metadata fields.""" root, head = repo pack = build_mpack(root, [head], have=[]) for field in _FORBIDDEN: assert field not in pack, ( f"build_mpack() emitted '{field}' — that field belongs in the " f"HTTP layer, not in the pack bytes." ) # --------------------------------------------------------------------------- # Positive: expected fields are present # --------------------------------------------------------------------------- def test_build_mpack_contains_required_fields( repo: tuple[pathlib.Path, str], ) -> None: """build_mpack() must emit exactly the core pack fields.""" root, head = repo pack = build_mpack(root, [head], have=[]) for field in ("commits", "snapshots", "blobs", "summary", "meta"): assert field in pack, f"build_mpack() missing required field '{field}'"