from pathlib import Path import pytest from glas_harness.profiles import ( AmbiguousProfileError, IncompatibleProfileError, ProfileCatalog, ProfileError, UnknownProfileError, ) from glas_harness.reins.rein_aharness import ReinAharness from glas_harness.reins.rein_openweights import ReinOpenWeights def _write(path: Path, name: str, text: str) -> None: (path / name).write_text(text) def _profile( *, profile_id: str = "harness.test", version: str = "1.0.0", contract: str = "1.0", rein: str = "rein-test", required: str = "session_style: unattended", extra: str = "", ) -> str: return f"""\ id: {profile_id} version: \"{version}\" contract_version: \"{contract}\" status: enabled rein: id: {rein} required_capabilities: {required} sandbox_profile: profile.test tool_profile: green-commit-only model: provider: test model: model-1 model_class: other route: test-route limits: budget_tokens: 100 {extra} """ def _rein(*, rein_id: str = "rein-test", capability: str = "unattended") -> str: return f"""\ id: {rein_id} version: \"1.0.0\" title: Test rein handler: glas_harness.reins.rein_aharness:ReinAharness contract_versions: [\"1.0\"] capabilities: session_style: {capability} status: implemented """ def test_committed_catalog_resolves_both_constellations() -> None: catalog = ProfileCatalog() contexts = catalog.validate_all() assert len(contexts) == 3 assert {context.rein_id for context in contexts} == { "rein-aharness", "rein-openweights", } assert { (context.profile.id, context.operational_readiness.status) for context in contexts } == { ("harness.agent-dev-local", "blocked"), ("harness.agent-dev-openweights-local", "blocked"), ("harness.agent-dev", "unverified"), } profile, descriptor = catalog.resolve( "harness.agent-dev-openweights-local@1.0.0" ) rein = catalog.build_rein(profile, descriptor) assert isinstance(rein, ReinOpenWeights) assert rein.model == "qwen/qwen-2.5-72b-instruct" assert rein.tool_profile == "green-commit-only" assert rein.max_turns == 20 assert rein.budget_tokens == 60000 profile, descriptor = catalog.resolve("harness.agent-dev-local@1.0.0") rein = catalog.build_rein(profile, descriptor) assert isinstance(rein, ReinAharness) assert rein.model == "claude-sonnet-4-6" assert rein.tool_profile == "green-commit-only" assert rein.budget_tokens == 60000 def test_ready_profile_requires_an_evidence_reference(tmp_path) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write( profiles, "profile.yaml", _profile( extra="""operational_readiness: status: ready reason: proof completed owner: tests """ ), ) _write(reins, "rein.yaml", _rein()) with pytest.raises(ProfileError, match="ready operational status requires evidence_ref"): ProfileCatalog(profiles, reins).profiles() def test_undeclared_readiness_defaults_to_unverified(tmp_path) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write(profiles, "profile.yaml", _profile()) _write(reins, "rein.yaml", _rein()) context = ProfileCatalog(profiles, reins).resolve_context("harness.test@1.0.0") assert context.operational_readiness.status == "unverified" assert context.operational_readiness.reason == "no operational proof declared" def test_unknown_profile_fails_closed() -> None: with pytest.raises(UnknownProfileError, match="unknown harness profile"): ProfileCatalog().resolve("harness.missing@1.0.0") def test_unpinned_multi_version_profile_is_ambiguous(tmp_path) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write(profiles, "one.yaml", _profile(version="1.0.0")) _write(profiles, "two.yaml", _profile(version="2.0.0")) _write(reins, "rein.yaml", _rein()) with pytest.raises(AmbiguousProfileError, match="pin one of"): ProfileCatalog(profiles, reins).resolve("harness.test") @pytest.mark.parametrize( ("profile_text", "match"), [ (_profile(version="not-semver"), "semantic versioning"), (_profile(extra="unexpected: true"), "extra_forbidden"), (_profile(extra="api_key: sk-this-is-inline-and-forbidden"), "inline secret"), ], ) def test_malformed_or_sensitive_profiles_are_rejected( tmp_path, profile_text: str, match: str ) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write(profiles, "profile.yaml", profile_text) _write(reins, "rein.yaml", _rein()) with pytest.raises(ProfileError, match=match): ProfileCatalog(profiles, reins).profiles() def test_duplicate_profile_revision_is_rejected(tmp_path) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write(profiles, "one.yaml", _profile()) _write(profiles, "two.yaml", _profile()) _write(reins, "rein.yaml", _rein()) with pytest.raises(ProfileError, match="duplicate harness profile"): ProfileCatalog(profiles, reins).profiles() @pytest.mark.parametrize( ("profile_text", "rein_text", "match"), [ (_profile(contract="2.0"), _rein(), "requires contract 2.0"), (_profile(rein="rein-missing"), _rein(), "unknown rein"), (_profile(required="session_style: interactive"), _rein(), "capability"), ], ) def test_incompatible_profile_or_rein_is_rejected( tmp_path, profile_text: str, rein_text: str, match: str ) -> None: profiles = tmp_path / "profiles" reins = tmp_path / "reins" profiles.mkdir() reins.mkdir() _write(profiles, "profile.yaml", profile_text) _write(reins, "rein.yaml", rein_text) with pytest.raises(IncompatibleProfileError, match=match): ProfileCatalog(profiles, reins).resolve("harness.test@1.0.0")