Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0

This commit is contained in:
Public Source Publisher committed 2026-09-30 09:23:17 +00:00
1 parent 7082ab955a
commit 848f0d8f8a
434 files changed
+67298 -4315

No files matched your search

@@ -0,0 +1,617 @@
from __future__ import annotations
import hashlib
import importlib.util
import json
from datetime import UTC, datetime, timedelta
from pathlib import Path
from types import ModuleType
import pytest
from alembic.migration import MigrationContext
from alembic.operations import Operations
from fastapi.testclient import TestClient
from pydantic import SecretStr, ValidationError
from sqlalchemy import create_engine, inspect, select, text
from sqlalchemy.orm import Session
from sqlalchemy.pool import StaticPool
from modelforge_api.api.authorization import AccessBoundary, access_boundary_for_request
from modelforge_api.db import get_session
from modelforge_api.domain.portfolio import PortfolioReconcileRequest
from modelforge_api.main import app
from modelforge_api.persistence.models import (
AuditEvent,
Base,
PortfolioReconciliationRun,
PortfolioRepositoryObservation,
Project,
ProjectBinding,
)
from modelforge_api.services.audit import AuditContext
from modelforge_api.services.portfolio_registry import (
PortfolioRegistryError,
PortfolioRegistryService,
)
from modelforge_api.settings import Settings, get_settings
ROOT = Path(__file__).resolve().parents[1]
MIGRATION_PATH = (
ROOT / "alembic" / "versions" / "20260923_0036_portfolio_repository_reconciliation.py"
)
def _migration() -> ModuleType:
spec = importlib.util.spec_from_file_location("portfolio_reconciliation_0036", MIGRATION_PATH)
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
@pytest.fixture
def session() -> Session:
engine = create_engine(
"sqlite+pysqlite:///:memory:",
connect_args={"check_same_thread": False},
poolclass=StaticPool,
)
Base.metadata.create_all(engine)
with Session(engine) as value:
yield value
engine.dispose()
def observation(
*,
repository_id: str = "all-examplerag",
project_key: str = "examplerag",
classification: str = "gateway",
slug: str = "ITWorx/ExampleRAG",
head_sha: str = "a" * 40,
branch: str = "master",
accept_head_update: bool = False,
runtime_evidence: list[dict[str, object]] | None = None,
) -> dict[str, object]:
return {
"external_repository_id": repository_id,
"project_key": project_key,
"slug": slug,
"default_branch": branch,
"head_sha": head_sha,
"classification": classification,
"accept_head_update": accept_head_update,
"code_evidence": [
{
"path": "backend/src/client.py",
"signal": "capability_client",
"capabilities": ["rag.embedding@1"],
}
],
"runtime_evidence": runtime_evidence or [],
}
def request(
*,
snapshot_id: str = "gitea-001",
observed_at: datetime | None = None,
repositories: list[dict[str, object]] | None = None,
complete: bool = False,
) -> PortfolioReconcileRequest:
return PortfolioReconcileRequest.model_validate(
{
"source_system": "gitea",
"snapshot_id": snapshot_id,
"observed_at": (observed_at or datetime(2026, 9, 23, 12, tzinfo=UTC)).isoformat(),
"complete": complete,
"repositories": [observation()] if repositories is None else repositories,
}
)
def reconcile(
session: Session, item: PortfolioReconcileRequest
):
return PortfolioRegistryService(session).reconcile(
item, AuditContext("operator", "portfolio-test", "portfolio-correlation")
)
def test_reconciliation_reuses_project_and_exact_replay_is_a_noop(session: Session) -> None:
project = Project(
key="examplerag", name="ExampleRAG legacy", description="operator description", active=False
)
session.add(project)
session.commit()
item = request()
first = reconcile(session, item)
second = reconcile(session, item)
assert first.projects_created == 0
assert first.repositories_created == 1
assert first.replayed is False
assert second.replayed is True
assert second.snapshot_digest == first.snapshot_digest
assert session.query(Project).count() == 1
assert session.query(ProjectBinding).count() == 0
assert session.query(PortfolioRepositoryObservation).count() == 1
session.refresh(project)
assert (project.name, project.description, project.active) == (
"ExampleRAG legacy",
"operator description",
False,
)
assert session.query(PortfolioReconciliationRun).count() == 1
assert session.scalar(
select(AuditEvent).where(AuditEvent.action == "PORTFOLIO_RECONCILED")
) is not None
assert session.query(AuditEvent).filter_by(action="PORTFOLIO_RECONCILED").count() == 1
def test_authenticated_portfolio_artifact_creates_only_source_confirmed_projects(
session: Session,
) -> None:
artifact = ROOT.parent / "docs/product/PORTFOLIO_RECONCILE_REQUEST_COMPLETE_2026-09-25.json"
item = PortfolioReconcileRequest.model_validate_json(artifact.read_text(encoding="utf-8"))
first = reconcile(session, item)
second = reconcile(session, item)
assert item.complete is True
assert first.repositories_created == 69
assert first.projects_created == 12
assert second.replayed is True
assert second.snapshot_digest == first.snapshot_digest
assert session.query(PortfolioRepositoryObservation).count() == 69
assert session.query(Project).count() == 12
assert session.query(ProjectBinding).count() == 0
inventory = PortfolioRegistryService(session).inventory()
assert len(inventory.repositories) == 69
assert sum(row.project_id is not None for row in inventory.repositories) == 12
def test_non_consumer_repositories_are_recorded_without_creating_projects(
session: Session,
) -> None:
item = request(
repositories=[
observation(
repository_id="all-docs-tool",
project_key="docs-tool",
classification="non_ai",
slug="ITWorx/Docs-Tool",
)
]
)
reconcile(session, item)
row = session.scalar(select(PortfolioRepositoryObservation))
view = PortfolioRegistryService(session).inventory().repositories[0]
assert row and row.project_id is None and row.project_key == "docs-tool"
assert view.project_key == "docs-tool" and view.project_id is None and view.project_name is None
assert session.query(Project).count() == 0
def test_operator_classification_links_an_existing_observation_only_when_relevant(
session: Session,
) -> None:
reconcile(
session,
request(
repositories=[
observation(classification="hosted_model", project_key="examplerag")
]
),
)
row = session.scalar(select(PortfolioRepositoryObservation))
assert row and row.project_id is None
assert session.query(Project).count() == 0
reconcile(
session,
request(
snapshot_id="reviewed-local-consumer",
observed_at=datetime(2026, 9, 23, 12, 5, tzinfo=UTC),
repositories=[observation(classification="gateway", project_key="examplerag")],
),
)
session.refresh(row)
assert row.project_id is not None
assert session.query(Project).count() == 1
def test_nonlocal_to_local_head_change_stays_unlinked_until_exact_candidate_is_accepted(
session: Session,
) -> None:
start = datetime(2026, 9, 23, 12, tzinfo=UTC)
reconcile(
session,
request(
observed_at=start,
repositories=[observation(classification="hosted_model")],
),
)
pending = reconcile(
session,
request(
snapshot_id="local-candidate",
observed_at=start + timedelta(minutes=5),
repositories=[
observation(classification="gateway", head_sha="b" * 40)
],
),
)
row = session.scalar(select(PortfolioRepositoryObservation))
view = PortfolioRegistryService(session).inventory().repositories[0]
assert pending.head_changes_review_required == 1
assert row and row.project_id is None and row.head_sha == "a" * 40
assert row.classification == "hosted_model"
assert row.pending_head_sha == "b" * 40
assert row.pending_classification == "gateway"
assert row.pending_project_key == "examplerag"
assert view.project_id is None and view.pending_project_key == "examplerag"
assert session.query(Project).count() == 0
with pytest.raises(PortfolioRegistryError) as error:
reconcile(
session,
request(
snapshot_id="accept-unreviewed-head",
observed_at=start + timedelta(minutes=7),
repositories=[
observation(
classification="gateway",
head_sha="c" * 40,
accept_head_update=True,
)
],
),
)
assert error.value.code == "PORTFOLIO_PENDING_HEAD_CONFLICT"
session.refresh(row)
assert row.project_id is None and row.pending_head_sha == "b" * 40
assert session.query(Project).count() == 0
accepted = reconcile(
session,
request(
snapshot_id="accept-local-candidate",
observed_at=start + timedelta(minutes=10),
repositories=[
observation(
classification="gateway",
head_sha="b" * 40,
accept_head_update=True,
)
],
),
)
session.refresh(row)
assert accepted.head_changes_accepted == 1
assert row.project_id is not None and row.head_sha == "b" * 40
assert row.classification == "gateway" and row.pending_head_sha is None
assert row.pending_project_key is None
assert session.query(Project).count() == 1
def test_duplicate_project_key_across_repositories_is_an_explicit_conflict(
session: Session,
) -> None:
documents = observation(
repository_id="all-docs-tool",
project_key="shared-key",
classification="non_ai",
slug="ITWorx/Docs-Tool",
)
dashboard = observation(
repository_id="all-dashboard",
project_key="shared-key",
classification="runtime_observer",
slug="ITWorx/Dashboard",
)
with pytest.raises(PortfolioRegistryError) as error:
reconcile(session, request(repositories=[documents, dashboard]))
assert error.value.status_code == 409
assert error.value.code == "PORTFOLIO_PROJECT_KEY_CONFLICT"
assert session.query(PortfolioRepositoryObservation).count() == 0
assert session.query(Project).count() == 0
assert session.query(PortfolioReconciliationRun).count() == 0
def test_snapshot_identity_conflict_does_not_change_portfolio(session: Session) -> None:
first = request()
reconcile(session, first)
changed = request(
snapshot_id=first.snapshot_id,
observed_at=first.observed_at + timedelta(minutes=1),
repositories=[observation(head_sha="b" * 40)],
)
with pytest.raises(PortfolioRegistryError) as error:
reconcile(session, changed)
assert error.value.status_code == 409
row = session.scalar(select(PortfolioRepositoryObservation))
assert row and row.head_sha == "a" * 40
assert session.query(PortfolioReconciliationRun).count() == 1
def test_head_change_requires_explicit_operator_snapshot_acceptance(session: Session) -> None:
first_time = datetime(2026, 9, 23, 12, tzinfo=UTC)
reconcile(session, request(observed_at=first_time, complete=True))
pending = reconcile(
session,
request(
snapshot_id="gitea-002",
observed_at=first_time + timedelta(minutes=5),
repositories=[observation(head_sha="b" * 40)],
),
)
row = session.scalar(select(PortfolioRepositoryObservation))
assert row and row.head_sha == "a" * 40
assert row.pending_head_sha == "b" * 40
assert pending.head_changes_review_required == 1
assert row.source_observed_at.replace(tzinfo=UTC) == first_time
stale = reconcile(
session,
request(
snapshot_id="gitea-old",
observed_at=first_time + timedelta(minutes=3),
repositories=[observation(head_sha="c" * 40)],
),
)
assert stale.stale_snapshot is False
assert stale.stale_observations == 1
session.refresh(row)
assert row.head_sha == "a" * 40
assert row.pending_head_sha == "b" * 40
accepted = reconcile(
session,
request(
snapshot_id="gitea-003",
observed_at=first_time + timedelta(minutes=7),
repositories=[observation(head_sha="b" * 40, accept_head_update=True)],
),
)
session.refresh(row)
assert accepted.head_changes_accepted == 1
assert row.head_sha == "b" * 40
assert row.pending_head_sha is None
def test_incomplete_snapshot_never_marks_absent_repository_stale(session: Session) -> None:
start = datetime(2026, 9, 23, 12, tzinfo=UTC)
second = observation(
repository_id="all-examplevision", project_key="examplevision", slug="ITWorx/ExampleVision"
)
reconcile(session, request(observed_at=start, repositories=[observation(), second], complete=True))
partial = reconcile(
session,
request(
snapshot_id="partial",
observed_at=start + timedelta(minutes=1),
repositories=[observation()],
complete=False,
),
)
examplevision = session.scalar(
select(PortfolioRepositoryObservation).where(
PortfolioRepositoryObservation.external_repository_id == "all-examplevision"
)
)
assert partial.repositories_marked_stale == 0
assert examplevision and examplevision.stale_at is None
def test_newer_complete_snapshot_marks_only_missing_rows_stale_without_deleting(session: Session) -> None:
start = datetime(2026, 9, 23, 12, tzinfo=UTC)
second = observation(
repository_id="all-examplevision", project_key="examplevision", slug="ITWorx/ExampleVision"
)
reconcile(session, request(observed_at=start, repositories=[observation(), second], complete=True))
result = reconcile(
session,
request(
snapshot_id="complete-newer",
observed_at=start + timedelta(minutes=2),
repositories=[observation()],
complete=True,
),
)
examplevision = session.scalar(
select(PortfolioRepositoryObservation).where(
PortfolioRepositoryObservation.external_repository_id == "all-examplevision"
)
)
pokevault_project = session.scalar(select(Project).where(Project.key == "examplevision"))
assert result.repositories_marked_stale == 1
assert examplevision and examplevision.stale_at == (start + timedelta(minutes=2)).replace(tzinfo=None)
assert pokevault_project and pokevault_project.active is True
assert session.query(PortfolioRepositoryObservation).count() == 2
assert session.query(ProjectBinding).count() == 0
def test_runtime_observations_are_separate_and_monotone(session: Session) -> None:
start = datetime(2026, 9, 23, 12, tzinfo=UTC)
running = {
"component": "backend",
"state": "running",
"observed_at": (start + timedelta(minutes=2)).isoformat(),
"observation_source": "container_inventory",
"git_revision": "1234567890ab",
}
reconcile(
session,
request(observed_at=start, repositories=[observation(runtime_evidence=[running])]),
)
# A later source-only snapshot must not erase runtime evidence.
reconcile(
session,
request(
snapshot_id="source-only",
observed_at=start + timedelta(minutes=3),
repositories=[observation()],
),
)
row = session.scalar(select(PortfolioRepositoryObservation))
assert row and row.classification == "gateway"
assert row.runtime_evidence[0]["state"] == "running"
from modelforge_api.domain.portfolio import PortfolioRuntimeEvidence
runtime = PortfolioRuntimeEvidence.model_validate(row.runtime_evidence[0])
assert runtime.observed_at == start + timedelta(minutes=2)
def test_payload_contract_rejects_secrets_and_unsafe_evidence_paths() -> None:
body = request().model_dump(mode="json")
body["api_key"] = "this-value-must-not-be-accepted"
with pytest.raises(ValidationError):
PortfolioReconcileRequest.model_validate(body)
unsafe = request().model_dump(mode="json")
unsafe["repositories"][0]["code_evidence"][0]["path"] = "../private-key.env"
with pytest.raises(ValidationError):
PortfolioReconcileRequest.model_validate(unsafe)
windows = request().model_dump(mode="json")
windows["repositories"][0]["code_evidence"][0]["path"] = "C:/private-key.env"
with pytest.raises(ValidationError):
PortfolioReconcileRequest.model_validate(windows)
def test_inventory_and_reconcile_roles_and_validation_responses_are_safe(
session: Session,
) -> None:
tokens = {role: f"mfop_{role[0] * 43}" for role in ("viewer", "operator", "admin")}
settings = Settings(
_env_file=None,
env="test",
operator_identities=SecretStr(
json.dumps(
[
{
"subject": role,
"role": role,
"credential_id": role,
"token_sha256": hashlib.sha256(token.encode()).hexdigest(),
"expires_at": (datetime.now(UTC) + timedelta(days=1)).isoformat(),
}
for role, token in tokens.items()
]
)
),
)
app.dependency_overrides[get_settings] = lambda: settings
app.dependency_overrides[get_session] = lambda: session
try:
client = TestClient(app)
assert access_boundary_for_request("GET", "/api/v1/portfolio") is AccessBoundary.CONTROL_PLANE
assert client.get("/api/v1/portfolio").status_code == 401
assert client.get(
"/api/v1/portfolio", headers={"X-ModelForge-Admin-Token": tokens["viewer"]}
).status_code == 200
body = request().model_dump(mode="json")
assert client.post("/api/v1/portfolio/reconcile", json=body).status_code == 401
assert client.post(
"/api/v1/portfolio/reconcile",
headers={"X-ModelForge-Admin-Token": tokens["viewer"]},
json=body,
).status_code == 403
invalid = dict(body)
invalid["clone_url"] = "https://private-user:private-password@example.invalid/repo.git"
invalid["api-key-secret-value-must-not-echo"] = "untrusted"
rejected = client.post(
"/api/v1/portfolio/reconcile",
headers={"X-ModelForge-Admin-Token": tokens["operator"]},
json=invalid,
)
assert rejected.status_code == 422
assert "private-password" not in rejected.text
assert "example.invalid" not in rejected.text
assert "api-key-secret-value-must-not-echo" not in rejected.text
accepted = client.post(
"/api/v1/portfolio/reconcile",
headers={
"X-ModelForge-Admin-Token": tokens["operator"],
"X-Correlation-ID": "portfolio-reconcile-test",
},
json=body,
)
assert accepted.status_code == 200
assert accepted.json()["repositories_created"] == 1
audit = session.scalar(
select(AuditEvent).where(AuditEvent.action == "PORTFOLIO_RECONCILED")
)
assert audit and audit.actor_id == "operator"
assert audit.correlation_id == "portfolio-reconcile-test"
finally:
app.dependency_overrides.clear()
def test_portfolio_migration_upgrades_and_downgrades_empty_history() -> None:
engine = create_engine("sqlite+pysqlite:///:memory:")
with engine.begin() as connection:
connection.execute(text("CREATE TABLE projects (id VARCHAR(36) PRIMARY KEY)"))
migration = _migration()
migration.op = Operations(MigrationContext.configure(connection))
migration.upgrade()
assert inspect(connection).has_table("portfolio_repository_observations")
assert inspect(connection).has_table("portfolio_reconciliation_runs")
foreign_keys = inspect(connection).get_foreign_keys("portfolio_repository_observations")
assert any(item["referred_table"] == "projects" for item in foreign_keys)
repository_unique_constraints = {
item["name"]
for item in inspect(connection).get_unique_constraints(
"portfolio_repository_observations"
)
}
assert "uq_portfolio_source_project_key" in repository_unique_constraints
assert "uq_portfolio_repository_project_id" in repository_unique_constraints
migration.downgrade()
assert not inspect(connection).has_table("portfolio_repository_observations")
assert not inspect(connection).has_table("portfolio_reconciliation_runs")
engine.dispose()
def test_portfolio_migration_refuses_downgrade_after_a_snapshot_is_saved() -> None:
engine = create_engine("sqlite+pysqlite:///:memory:")
with engine.begin() as connection:
connection.execute(text("CREATE TABLE projects (id VARCHAR(36) PRIMARY KEY)"))
migration = _migration()
migration.op = Operations(MigrationContext.configure(connection))
migration.upgrade()
connection.execute(
text(
"INSERT INTO portfolio_reconciliation_runs "
"(id, source_system, snapshot_id, payload_digest, observed_at, complete, "
"stale_snapshot, projects_created, repositories_created, repositories_updated, "
"stale_observations, repositories_marked_stale, runtime_observations_updated, "
"head_changes_review_required, head_changes_accepted) "
"VALUES ('00000000-0000-0000-0000-000000000001', 'gitea', 'snapshot-1', :digest, "
"'2026-09-23 12:00:00', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)"
),
{"digest": "a" * 64},
)
with pytest.raises(RuntimeError, match="portfolio reconciliation history exists"):
migration.downgrade()
assert inspect(connection).has_table("portfolio_reconciliation_runs")
assert inspect(connection).has_table("portfolio_repository_observations")
engine.dispose()