Some checks failed
ci / validate (push) Has been cancelled
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0233b-178d-7162-b92f-31a31ea8ca9b
207 lines
6 KiB
Python
207 lines
6 KiB
Python
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")
|