"""Tests for verify_attestation + ``muse verify-commit --attest`` — Phase 7.5. Rule #0 tier coverage: * unit — tier output mapping, four-tier glyph rendering, exit codes. * integration — full round-trip commit → attest → verify, all four tiers. * security — forged HMAC → tier 2 (signed) not tier 3; missing anchor → explicit ICP_NOT_ANCHORED; network-unreachable canister → explicit ICP_UNREACHABLE (not silent degrade); partial verifications surface clearly. """ from __future__ import annotations import argparse import json import os import pathlib from dataclasses import dataclass, field from typing import Any from unittest.mock import patch import pytest from muse.cli.commands import verify_commit as verify_commit_cmd from muse.core.attestation import ( AttestationVerifyError, register_attestation_provider, unregister_attestation_provider, ) from muse.core.errors import ExitCode from muse.core.verify import ( AttestationVerifyResult, TIER_HMAC_ATTESTED, TIER_ICP_ANCHORED, TIER_SIGNED_ONLY, TIER_UNSIGNED, verify_attestation, ) # --------------------------------------------------------------------------- # Fake commit + provider scaffolding # --------------------------------------------------------------------------- @dataclass class _FakeCommit: """Minimal CommitRecord shape used by the verify engine.""" commit_id: str = "c" * 64 signature: str = "" signer_public_key: str = "" format_version: int = 7 author: str = "" agent_id: str = "" model_id: str = "" toolchain_id: str = "" prompt_hash: str = "" @property def committed_at(self) -> Any: import datetime return datetime.datetime(2026, 1, 1, tzinfo=datetime.timezone.utc) metadata: dict[str, str] = field(default_factory=dict) def _make_signed_commit(metadata: dict[str, str] | None = None) -> _FakeCommit: """Forge a real Ed25519 signature so the engine treats the commit as signed.""" from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from muse.core.provenance import ( encode_public_key, provenance_payload, sign_commit_ed25519, ) pk = Ed25519PrivateKey.generate() commit = _FakeCommit(metadata=dict(metadata or {})) payload = provenance_payload( commit.commit_id, author=commit.author, agent_id=commit.agent_id, model_id=commit.model_id, toolchain_id=commit.toolchain_id, prompt_hash=commit.prompt_hash, committed_at=commit.committed_at.isoformat(), ) sig = sign_commit_ed25519(payload, pk) _, pub_b64 = encode_public_key(pk) commit.signature = sig commit.signer_public_key = pub_b64 return commit class _AlwaysValidProvider: """Stub provider whose verify always returns valid=True.""" def compute_attestation(self, snapshot_id: str, commit_meta: dict[str, object]) -> Any: return {} def anchor(self, record: Any) -> Any: return {} def verify(self, record: Any, receipt: Any) -> Any: return {"valid": True, "reason": "", "depth": 0, "provider_id": "knowtation"} class _AlwaysInvalidProvider(_AlwaysValidProvider): """Stub provider whose verify returns valid=False (provably bad).""" def verify(self, record: Any, receipt: Any) -> Any: return { "valid": False, "reason": "HMAC signature mismatch (forged)", "depth": 0, "provider_id": "knowtation", } class _RaisingProvider(_AlwaysValidProvider): """Stub provider whose verify raises (partial verification).""" def verify(self, record: Any, receipt: Any) -> Any: raise AttestationVerifyError("simulated key missing", code="KEY_MISSING") @pytest.fixture(autouse=True) def _registry_cleanup() -> None: """Ensure each test starts/ends with no provider registered.""" unregister_attestation_provider("knowtation") yield unregister_attestation_provider("knowtation") # =========================================================================== # UNIT TIER — tier mapping # =========================================================================== class TestTierLabels: """Tier label map exposes stable strings for JSON consumers.""" def test_all_tiers_have_labels(self) -> None: """Every defined tier has a non-empty label.""" labels = verify_commit_cmd.TIER_LABELS assert labels[TIER_UNSIGNED] == "unsigned" assert labels[TIER_SIGNED_ONLY] == "signed" assert labels[TIER_HMAC_ATTESTED] == "hmac-attested" assert labels[TIER_ICP_ANCHORED] == "icp-anchored" # =========================================================================== # INTEGRATION TIER — verify_attestation engine # =========================================================================== class TestEngineTier0: """Unsigned commit → tier 0.""" def test_unsigned_returns_tier_0(self) -> None: """No signature → tier 0, valid=False, reason populated.""" commit = _FakeCommit() result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert result["tier"] == TIER_UNSIGNED assert result["valid"] is False assert result["reason"] class TestEngineTier1: """Signed commit, no attestation → tier 1.""" def test_signed_only_returns_tier_1(self) -> None: """Real signature, no metadata → tier 1, valid=True.""" commit = _make_signed_commit() result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert result["tier"] == TIER_SIGNED_ONLY assert result["valid"] is True assert result["partial"] is False class TestEngineTier2: """Signed + HMAC attestation valid → tier 2.""" def test_hmac_valid_no_icp_check_returns_tier_2(self) -> None: """HMAC OK, ICP check disabled → tier 2.""" register_attestation_provider("knowtation", _AlwaysValidProvider()) commit = _make_signed_commit({ "attestation": json.dumps({ "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", }), }) result = verify_attestation( commit, pathlib.Path("/tmp/fake"), {"check_icp": False} ) assert result["tier"] == TIER_HMAC_ATTESTED assert result["hmac_valid"] is True assert result["valid"] is True class TestEngineTier3: """Signed + HMAC + ICP anchored → tier 3.""" def test_icp_anchored_returns_tier_3(self, monkeypatch: pytest.MonkeyPatch) -> None: """Mock anchor fetch returning matching record → tier 3.""" register_attestation_provider("knowtation", _AlwaysValidProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) def _fake_fetch(canister_id: str, rid: str, *, timeout: float = 5.0) -> Any: return {**attestation, "seq": 42} monkeypatch.setattr( "muse.plugins.knowtation.icp_push_hook.fetch_attestation_via_http", _fake_fetch, ) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert result["tier"] == TIER_ICP_ANCHORED assert result["icp_anchored"] is True assert "icp-seq-42" in result["anchor_tx_id"] # =========================================================================== # SECURITY TIER (mandatory) # =========================================================================== class TestSecurity: """Phase 7.5 security contracts — partial verifications must surface.""" def test_forged_hmac_returns_valid_false_at_tier_above_signed( self, ) -> None: """Provably-bad HMAC → valid=False, partial=False, NOT tier 1 fallthrough.""" register_attestation_provider("knowtation", _AlwaysInvalidProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "forged-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) # Critical: HMAC_INVALID surfaces explicitly, not silent tier-1. assert "HMAC_INVALID" in result["reason"] assert result["valid"] is False assert result["partial"] is False def test_icp_unreachable_surfaces_partial_not_silent_degrade( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Network failure → partial=True, ICP_UNREACHABLE in reason.""" register_attestation_provider("knowtation", _AlwaysValidProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) def _fail(canister_id: str, rid: str, *, timeout: float = 5.0) -> Any: raise OSError("connection refused") monkeypatch.setattr( "muse.plugins.knowtation.icp_push_hook.fetch_attestation_via_http", _fail, ) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert result["partial"] is True assert "ICP_UNREACHABLE" in result["reason"] # The HMAC was still valid → tier capped at HMAC_ATTESTED. assert result["tier"] == TIER_HMAC_ATTESTED assert result["icp_anchored"] is False def test_icp_404_returns_explicit_not_anchored( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Canister returns 404 → ICP_NOT_ANCHORED, partial=False.""" register_attestation_provider("knowtation", _AlwaysValidProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) monkeypatch.setattr( "muse.plugins.knowtation.icp_push_hook.fetch_attestation_via_http", lambda *a, **kw: None, ) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert "ICP_NOT_ANCHORED" in result["reason"] assert result["icp_anchored"] is False # NOT partial — verifier completed the check and got a definitive 404. assert result["partial"] is False def test_icp_content_hash_mismatch_caught( self, monkeypatch: pytest.MonkeyPatch ) -> None: """Anchored copy has different content_hash → ICP_NOT_ANCHORED.""" register_attestation_provider("knowtation", _AlwaysValidProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) def _fake_mismatch(canister_id: str, rid: str, *, timeout: float = 5.0) -> Any: return {**attestation, "content_hash": "TAMPERED", "seq": 1} monkeypatch.setattr( "muse.plugins.knowtation.icp_push_hook.fetch_attestation_via_http", _fake_mismatch, ) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert "content_hash" in result["reason"] assert result["icp_anchored"] is False def test_provider_raise_is_partial_not_invalid(self) -> None: """Provider raises → partial=True (verifier could not complete).""" register_attestation_provider("knowtation", _RaisingProvider()) attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "knowtation", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) result = verify_attestation( commit, pathlib.Path("/tmp/fake"), {"check_icp": False} ) assert result["partial"] is True assert "KEY_MISSING" in result["reason"] def test_no_provider_registered_is_partial(self) -> None: """No provider for the record's domain → partial=True, NO_PROVIDER.""" attestation = { "id": "a" * 64, "action": "write", "path": "x.md", "content_hash": "abc", "timestamp": "2026-01-01T00:00:00Z", "sig": "real-sig", "algorithm": "hmac-sha256", "provider_id": "nonexistent-domain", } commit = _make_signed_commit({"attestation": json.dumps(attestation)}) result = verify_attestation(commit, pathlib.Path("/tmp/fake")) assert result["partial"] is True assert "NO_PROVIDER" in result["reason"] # =========================================================================== # CLI tier — argparse / exit codes # =========================================================================== class TestCLI: """muse verify-commit subcommand exits cleanly per tier.""" def _init_repo_with_commit(self, tmp_path: pathlib.Path) -> str: """Init a knowtation repo, commit one note, return the commit ID.""" os.chdir(tmp_path) from muse.cli.commands.init import run as init_run init_args = argparse.Namespace( bare=False, template=None, default_branch="main", force=False, domain="knowtation", as_json=False, ) init_run(init_args) (tmp_path / "notes").mkdir() (tmp_path / "notes" / "seed.md").write_text("seed\n", encoding="utf-8") from muse.cli.commands import commit as commit_cmd captured: list[str] = [] import builtins real_print = builtins.print try: builtins.print = lambda *a, **kw: captured.append(" ".join(str(x) for x in a)) # type: ignore[assignment] commit_args = argparse.Namespace( message="seed", allow_empty=False, dry_run=False, section=None, track=None, emotion=None, author=None, agent_id=None, model_id=None, toolchain_id=None, event_type=None, meta=None, sign=False, attest=False, attest_config=None, fmt="json", ) commit_cmd.run(commit_args) finally: builtins.print = real_print payload = json.loads([c for c in captured if c.startswith("{")][0]) return str(payload["commit_id"]) def test_unsigned_commit_exits_user_error(self, tmp_path: pathlib.Path) -> None: """Real unsigned commit → CLI exits USER_ERROR for tier 0.""" commit_id = self._init_repo_with_commit(tmp_path) args = argparse.Namespace( commit_id=commit_id, attest=False, no_icp=True, icp_canister=None, icp_timeout=5.0, json_out=True, ) with pytest.raises(SystemExit) as exc: verify_commit_cmd.run(args) assert exc.value.code == ExitCode.USER_ERROR def test_unknown_commit_exits_not_found(self, tmp_path: pathlib.Path) -> None: """Bogus commit ID → exits NOT_FOUND.""" self._init_repo_with_commit(tmp_path) args = argparse.Namespace( commit_id="0" * 64, attest=False, no_icp=True, icp_canister=None, icp_timeout=5.0, json_out=True, ) with pytest.raises(SystemExit) as exc: verify_commit_cmd.run(args) assert exc.value.code == ExitCode.NOT_FOUND