from __future__ import annotations import json import sys from datetime import datetime from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] sys.path.insert(0, str(ROOT)) sys.path.insert(0, str(ROOT / "backend/src")) from scripts.portfolio_gitea_snapshot import ( EXECUTABLE_LOCAL_MODEL_REPOSITORIES, build_snapshot, load_offline_heads, load_repository_ids, main, request_digest, ) from modelforge_api.domain.portfolio import PortfolioReconcileRequest from modelforge_api.services.portfolio_registry import snapshot_digest REQUEST_PATH = ROOT / "docs/product/PORTFOLIO_RECONCILE_REQUEST_2026-09-25.json" HEADS_PATH = ROOT / "docs/product/PORTFOLIO_DEFAULT_HEADS_2026-09-25.json" RUNTIME_STATUS_PATH = ROOT / "docs/product/PORTFOLIO_RUNTIME_STATUS_2026-09-25.json" COMPLETE_REQUEST_PATH = ROOT / "docs/product/PORTFOLIO_RECONCILE_REQUEST_COMPLETE_2026-09-25.json" def test_review_request_is_partial_secret_free_and_identity_stable() -> None: request = json.loads(REQUEST_PATH.read_text(encoding="utf-8")) manifest = json.loads(HEADS_PATH.read_text(encoding="utf-8")) runtime_status = json.loads(RUNTIME_STATUS_PATH.read_text(encoding="utf-8")) validated = PortfolioReconcileRequest.model_validate(request) assert validated.complete is False assert manifest["owner_inventory_verified"] is False assert manifest["default_heads_stable_across_two_reads"] is True assert len(validated.repositories) == manifest["repository_count"] == 69 assert len({row.external_repository_id for row in validated.repositories}) == 69 heads = load_offline_heads(HEADS_PATH) for row in validated.repositories: current = heads[row.slug.split("/", 1)[1]] assert row.default_branch == current["default_branch"] assert row.head_sha == current["head_sha"] assert row.accept_head_update is False assert row.runtime_evidence == [] assert all(not item.capabilities for item in row.code_evidence) local_model_rows = [row for row in validated.repositories if row.classification == "local_model"] assert {row.slug.split("/", 1)[1] for row in local_model_rows} == set( EXECUTABLE_LOCAL_MODEL_REPOSITORIES ) project_keys = [row.project_key for row in local_model_rows] assert len(project_keys) == len(set(project_keys)) == 12 config_marker_rows = [ row for row in validated.repositories if row.classification == "unknown" and row.code_evidence ] assert {row.slug.split("/", 1)[1] for row in config_marker_rows} == { "codex-router", "ITWorx_OpenChamber_MCP", } assert all(row.project_key is None for row in config_marker_rows) assert runtime_status["source_snapshot_id"] == validated.snapshot_id runtime_rows = runtime_status["repositories"] assert {row["external_repository_id"] for row in runtime_rows} == { row.external_repository_id for row in local_model_rows } assert all(row["runtime_status"] == "UNKNOWN" for row in runtime_rows) assert all(row["reason"] == "no_live_request_evidence_collected" for row in runtime_rows) observed_at = datetime.fromisoformat(request["observed_at"]) rebuilt = build_snapshot( [row.model_dump(mode="json") for row in validated.repositories], observed_at, complete=False, expected_count=manifest["repository_count"], repository_ids=load_repository_ids(), ) assert rebuilt == request assert request_digest(request) == snapshot_digest(validated) encoded = json.dumps(request, sort_keys=True) assert "MODELFORGE_GITEA_TOKEN" not in encoded assert "Authorization" not in encoded assert "OLLAMA_BASE_URL" not in encoded def test_unverified_owner_inventory_cannot_be_emitted_as_complete(tmp_path: Path) -> None: with pytest.raises(SystemExit) as error: main( [ "--offline-heads", str(HEADS_PATH), "--checkout-root", str(ROOT), "--output", str(tmp_path / "must-not-exist.json"), ] ) assert error.value.code == 2 assert not (tmp_path / "must-not-exist.json").exists() def test_authenticated_complete_request_has_exact_inventory_without_runtime_claims() -> None: partial = PortfolioReconcileRequest.model_validate_json(REQUEST_PATH.read_text(encoding="utf-8")) complete = PortfolioReconcileRequest.model_validate_json( COMPLETE_REQUEST_PATH.read_text(encoding="utf-8") ) assert complete.complete is True assert complete.source_system == "gitea" assert len(complete.repositories) == 69 assert {row.external_repository_id for row in complete.repositories} == { row.external_repository_id for row in partial.repositories } assert {row.slug: row.head_sha for row in complete.repositories} == { row.slug: row.head_sha for row in partial.repositories } assert sum(row.classification == "local_model" for row in complete.repositories) == 12 assert all(not row.accept_head_update for row in complete.repositories) assert all(not row.runtime_evidence for row in complete.repositories) assert all(not evidence.capabilities for row in complete.repositories for evidence in row.code_evidence) assert request_digest(json.loads(COMPLETE_REQUEST_PATH.read_text(encoding="utf-8"))) == snapshot_digest(complete)