autonomy-smoke-tests Exact governed tree; evidence 7dbba7ff168e72af
autonomy-unit-tests Exact governed tree; evidence 7dbba7ff168e72af
campaign-approval-gate Exact governed tree; evidence 7dbba7ff168e72af
git-diff-check Exact governed tree; evidence 7dbba7ff168e72af
py-compile Exact governed tree; evidence 7dbba7ff168e72af
reconciliation-contract Exact governed tree; evidence 7dbba7ff168e72af
release-state-machine Exact governed tree; evidence 7dbba7ff168e72af
secret-scan Exact governed tree; evidence 7029b3eafb209066
signer-validator-contract Exact governed tree; evidence 7dbba7ff168e72af
575 lines
23 KiB
Python
575 lines
23 KiB
Python
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import importlib.util
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import sqlite3
|
|
import sys
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
APP = ROOT / "active-runtime" / "app"
|
|
if str(APP) not in sys.path:
|
|
sys.path.insert(0, str(APP))
|
|
|
|
import c5_governed_principal_scope as scope # noqa: E402
|
|
|
|
|
|
NOW = 2_000_000_000
|
|
OWNER_KEY = "SHA256:" + "A" * 43
|
|
TRUST = {
|
|
"schema": "aios.task-principal-assertion.v1",
|
|
"issuer_id": "issuer",
|
|
"key_id": "key",
|
|
"public_key": "public",
|
|
"purpose": "TASK_PRINCIPAL",
|
|
"bridge_id": "bridge",
|
|
"scope_manifest_sha256": "f" * 64,
|
|
}
|
|
|
|
|
|
class StubSignatureVerifier:
|
|
key_id = OWNER_KEY
|
|
identity = "aios-task-grant-signer"
|
|
|
|
def __init__(self):
|
|
self.calls = 0
|
|
|
|
def verify(self, payload, signature):
|
|
self.calls += 1
|
|
return signature == b"valid-signature"
|
|
|
|
|
|
class StubAdapter:
|
|
def resolve_row(self, *, task, execution, trust, now):
|
|
if task["status"] not in {"CLAIMED", "RUNNING"}:
|
|
raise RuntimeError("TASK_NOT_CLAIMED")
|
|
return {
|
|
"scope_id": "source-scope",
|
|
"task_id": scope.TASK_ID,
|
|
"external_job_id": execution["external_job_id"],
|
|
"repository": scope.REPOSITORY,
|
|
"target_branch": scope.TARGET_BRANCH,
|
|
"generation": scope.GENERATION,
|
|
"execution_digest": scope.EXECUTION_DIGEST,
|
|
"capabilities_json": scope.canonical_json(list(scope.SOURCE_CAPABILITIES)).decode(),
|
|
"audiences_json": scope.canonical_json([
|
|
"aios.gitops.bridge.v2/bridge/acquireWriterLease",
|
|
"aios.gitops.bridge.v2/bridge/commitFilesGoverned",
|
|
]).decode(),
|
|
"trust_manifest_sha256": scope.sha256_json(dict(trust)),
|
|
"grant_id": "grant-c5",
|
|
"grant_expires_at": NOW + 3000,
|
|
}
|
|
|
|
|
|
def _canonical_payload(value):
|
|
result = dict(value)
|
|
result["canonical_payload_digest"] = scope.sha256_json(result)
|
|
return result
|
|
|
|
|
|
def _write(path: Path, value: bytes):
|
|
path.write_bytes(value)
|
|
if os.name == "posix":
|
|
path.chmod(0o600)
|
|
|
|
|
|
def _owner_material(tmp_path: Path, signatures: StubSignatureVerifier):
|
|
policy = _canonical_payload({
|
|
"schema": scope.POLICY_SCHEMA,
|
|
"policy_id": "C5_SOURCE_PUBLICATION_ONLY",
|
|
"owner_identity": "aios-task-grant-signer",
|
|
"repository": scope.REPOSITORY,
|
|
"trust_domain": "aios.owner",
|
|
"policy_digest": "1" * 64,
|
|
"authority_base_oid": "2" * 40,
|
|
"source_oid": "3" * 40,
|
|
"source_tree_oid": "4" * 40,
|
|
"target_agent": "agent/codex-c5-release",
|
|
"target_branch": scope.TARGET_BRANCH,
|
|
"generation": scope.GENERATION,
|
|
"execution_digest": scope.EXECUTION_DIGEST,
|
|
"exact_files": ["active-runtime/app/example.py"],
|
|
"capabilities": list(scope.SOURCE_CAPABILITIES),
|
|
"risk": "engineering",
|
|
"production_impact": "none",
|
|
"renewal": "none",
|
|
"nonce": "nonce-c5",
|
|
"issued_at": NOW - 10,
|
|
"not_before": NOW - 10,
|
|
"expires_at": NOW + 1000,
|
|
"status": "ACTIVE",
|
|
"signature_namespace": scope.OWNER_NAMESPACE,
|
|
"signature_key_id": OWNER_KEY,
|
|
})
|
|
epoch = _canonical_payload({
|
|
"epoch_id": "epoch-c5",
|
|
"owner_identity": "aios-task-grant-signer",
|
|
"trust_domain": "aios.owner",
|
|
"repository": scope.REPOSITORY,
|
|
"allowed_branch_prefixes": [scope.TARGET_BRANCH],
|
|
"allowed_capabilities": list(scope.SOURCE_CAPABILITIES),
|
|
"allowed_file_prefixes": ["active-runtime/app/"],
|
|
"risk_ceiling": "engineering",
|
|
"issued_at": NOW - 10,
|
|
"not_before": NOW - 10,
|
|
"expires_at": NOW + 1000,
|
|
"revocation_epoch": 0,
|
|
"policy_digest": "1" * 64,
|
|
"schema": scope.EPOCH_SCHEMA,
|
|
"business_goal": "publish C5 source",
|
|
"production_scope": "none",
|
|
"destructive_policy": "forbidden",
|
|
"signature_namespace": scope.OWNER_NAMESPACE,
|
|
"signature_key_id": OWNER_KEY,
|
|
"status": "ACTIVE",
|
|
})
|
|
epoch_revocations = {
|
|
"schema": "aios.owner-delegation-revocations.v1",
|
|
"revoked_epoch_ids": [],
|
|
}
|
|
policy_revocations = {
|
|
"schema": "aios.source-publication-revocations.v1",
|
|
"revoked_nonces": [],
|
|
}
|
|
epoch_root = tmp_path / "epoch"
|
|
epoch_root.mkdir()
|
|
paths = {
|
|
"policy": tmp_path / "policy.json",
|
|
"policy_revocations": tmp_path / "policy-revocations.json",
|
|
"epoch_root": epoch_root,
|
|
"epoch_revocations": tmp_path / "epoch-revocations.json",
|
|
}
|
|
_write(paths["policy"], scope.canonical_json({
|
|
"payload": policy, "signature": "valid-signature",
|
|
"key_id": OWNER_KEY, "namespace": scope.OWNER_NAMESPACE,
|
|
}))
|
|
_write(
|
|
epoch_root / "owner-delegation-epoch.canonical.json",
|
|
scope.canonical_json(epoch),
|
|
)
|
|
_write(epoch_root / "owner-delegation-epoch.sig", b"valid-signature")
|
|
_write(epoch_root / "owner-delegation-epoch.key-id", (OWNER_KEY + "\n").encode())
|
|
_write(paths["epoch_revocations"], scope.canonical_json(epoch_revocations))
|
|
_write(paths["policy_revocations"], scope.canonical_json(policy_revocations))
|
|
verifier = scope.FreshOwnerMaterialVerifier(
|
|
signature_verifier=signatures,
|
|
policy_artifact=paths["policy"],
|
|
policy_revocation_file=paths["policy_revocations"],
|
|
epoch_root=paths["epoch_root"],
|
|
epoch_revocation_file=paths["epoch_revocations"],
|
|
)
|
|
return verifier, paths
|
|
|
|
|
|
def _service(tmp_path: Path):
|
|
signatures = StubSignatureVerifier()
|
|
owner, paths = _owner_material(tmp_path, signatures)
|
|
store = scope.AppendOnlyScopeEnrollmentStore(tmp_path / "enrollments.sqlite3")
|
|
store.initialize()
|
|
service = scope.C5ScopeEnrollmentService(
|
|
deriver=scope.GovernedScopeDeriver(StubAdapter()),
|
|
owner=owner,
|
|
store=store,
|
|
enrollment_signature_verifier=signatures,
|
|
)
|
|
return service, signatures, paths, store
|
|
|
|
|
|
def _task(claimed_by="agent/codex-c5-release"):
|
|
return {"task_id": scope.TASK_ID, "status": "CLAIMED", "claimed_by": claimed_by}
|
|
|
|
|
|
def _execution():
|
|
return {
|
|
"external_job_id": "job-c5-real",
|
|
"repository": scope.REPOSITORY,
|
|
"target_branch": scope.TARGET_BRANCH,
|
|
"generation": scope.GENERATION,
|
|
"execution_digest": scope.EXECUTION_DIGEST,
|
|
}
|
|
|
|
|
|
def test_claim_then_signed_enrollment_then_runtime_resolution(tmp_path):
|
|
service, signatures, _paths, store = _service(tmp_path)
|
|
contract = service.prepare(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
assert contract["claimed_by"] == "agent/codex-c5-release"
|
|
assert contract["capability_derivation"] == {
|
|
"governed.write.files": "governed.write.file",
|
|
"writer.lease": "governed.write.branch",
|
|
}
|
|
assert contract["audiences"] == [
|
|
"aios.gitops.bridge.v2/bridge/acquireWriterLease",
|
|
"aios.gitops.bridge.v2/bridge/commitFilesGoverned",
|
|
]
|
|
assert service.enroll(
|
|
contract=contract, signature=b"valid-signature", task=_task(),
|
|
execution=_execution(), trust=TRUST, now=NOW,
|
|
) is False
|
|
assert service.enroll(
|
|
contract=contract, signature=b"valid-signature", task=_task(),
|
|
execution=_execution(), trust=TRUST, now=NOW,
|
|
) is True
|
|
resolved = service.resolve(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW,
|
|
)
|
|
assert json.loads(resolved["capabilities_json"]) == list(scope.PRINCIPAL_CAPABILITIES)
|
|
assert resolved["scope_id"] == contract["scope_id"]
|
|
assert signatures.calls >= 9 # policy + epoch + contract are rechecked per use
|
|
assert store.get(scope.TASK_ID)[0] == contract
|
|
|
|
|
|
def test_enrollment_requires_claimed_agent_bound_by_owner_policy(tmp_path):
|
|
service, _signatures, _paths, _store = _service(tmp_path)
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_TASK_CLAIM_IDENTITY_MISMATCH"):
|
|
service.prepare(
|
|
task=_task("governed-writer-random"), execution=_execution(),
|
|
trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
|
|
|
|
def test_execution_job_alias_is_canonical_and_conflicts_are_denied(tmp_path):
|
|
service, _signatures, _paths, _store = _service(tmp_path)
|
|
aliased = dict(_execution())
|
|
aliased["job_id"] = aliased.pop("external_job_id")
|
|
contract = service.prepare(
|
|
task=_task(), execution=aliased, trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
assert contract["external_job_id"] == "job-c5-real"
|
|
conflicted = dict(aliased, external_job_id="job-other")
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_EXECUTION_JOB_ID_INVALID"):
|
|
service.prepare(
|
|
task=_task(), execution=conflicted, trust=TRUST,
|
|
now=NOW, ttl_seconds=600,
|
|
)
|
|
|
|
|
|
def test_revocation_is_rechecked_after_append(tmp_path):
|
|
service, _signatures, paths, _store = _service(tmp_path)
|
|
contract = service.prepare(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
service.enroll(
|
|
contract=contract, signature=b"valid-signature", task=_task(),
|
|
execution=_execution(), trust=TRUST, now=NOW,
|
|
)
|
|
revoked = {
|
|
"schema": "aios.owner-delegation-revocations.v1",
|
|
"revoked_epoch_ids": ["epoch-c5"],
|
|
}
|
|
_write(paths["epoch_revocations"], scope.canonical_json(revoked))
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_OWNER_EPOCH_REVOKED"):
|
|
service.resolve(task=_task(), execution=_execution(), trust=TRUST, now=NOW)
|
|
|
|
|
|
def test_trust_or_execution_drift_cannot_reuse_enrollment(tmp_path):
|
|
service, _signatures, _paths, _store = _service(tmp_path)
|
|
contract = service.prepare(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
service.enroll(
|
|
contract=contract, signature=b"valid-signature", task=_task(),
|
|
execution=_execution(), trust=TRUST, now=NOW,
|
|
)
|
|
drifted = dict(TRUST, key_id="other")
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_ENROLLMENT_SCOPE_INVALID"):
|
|
service.resolve(task=_task(), execution=_execution(), trust=drifted, now=NOW)
|
|
bad_execution = dict(_execution(), external_job_id="job-other")
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_ENROLLMENT_BINDING_MISMATCH"):
|
|
service.resolve(task=_task(), execution=bad_execution, trust=TRUST, now=NOW)
|
|
|
|
|
|
def test_append_only_store_rejects_update_and_conflict(tmp_path):
|
|
service, _signatures, _paths, store = _service(tmp_path)
|
|
contract = service.prepare(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW, ttl_seconds=600,
|
|
)
|
|
service.enroll(
|
|
contract=contract, signature=b"valid-signature", task=_task(),
|
|
execution=_execution(), trust=TRUST, now=NOW,
|
|
)
|
|
with sqlite3.connect(store.path) as con:
|
|
with pytest.raises(sqlite3.IntegrityError, match="C5_PRINCIPAL_SCOPE_APPEND_ONLY"):
|
|
con.execute(
|
|
"UPDATE c5_principal_scope_enrollments SET scope_id='other' WHERE task_id=?",
|
|
(scope.TASK_ID,),
|
|
)
|
|
changed = dict(contract, external_job_id="job-other")
|
|
changed_without_digest = dict(changed)
|
|
changed_without_digest.pop("canonical_payload_digest")
|
|
changed["canonical_payload_digest"] = scope.sha256_json(changed_without_digest)
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_ENROLLMENT_CONFLICT"):
|
|
store.append(changed, b"valid-signature", NOW)
|
|
|
|
|
|
def test_not_yet_enrolled_does_not_break_base_readiness(monkeypatch):
|
|
class Base:
|
|
trust = TRUST
|
|
|
|
def readiness(self):
|
|
return {"ready": True, "schema_ready": True}
|
|
|
|
def activation_scope_task_ids(self):
|
|
return ("task-c4",)
|
|
|
|
class Runtime:
|
|
def readiness(self, trust, now):
|
|
return {"ready": False, "c5_scope_enrolled": False, "error": "C5_ENROLLMENT_REQUIRED"}
|
|
|
|
monkeypatch.setattr(
|
|
scope.RuntimeConfig, "from_environment",
|
|
classmethod(lambda cls: SimpleNamespace()),
|
|
)
|
|
monkeypatch.setattr(scope, "_runtime_service", lambda: Runtime())
|
|
composite = scope.wrap_principal_runtime_from_environment(Base(), role="verifier")
|
|
readiness = composite.readiness()
|
|
assert readiness["ready"] is True
|
|
assert readiness["c5_scope_enrolled"] is False
|
|
assert readiness["c5_scope_error"] == "C5_ENROLLMENT_REQUIRED"
|
|
# The upstream Bridge storage readiness contract is the original static
|
|
# C4 singleton. C5 is admitted later through the exact signed enrollment.
|
|
assert composite.activation_scope_task_ids() == ("task-c4",)
|
|
|
|
|
|
def test_issuer_readiness_reports_actual_loaded_server_source(monkeypatch, tmp_path):
|
|
source = tmp_path / "aios_task_principal_issuer_server.py"
|
|
source.write_bytes(b"# exact issuer fixture\n")
|
|
|
|
class Base:
|
|
def readiness(self):
|
|
return {"ready": True}
|
|
|
|
monkeypatch.setitem(
|
|
sys.modules, "aios_task_principal_issuer_server",
|
|
SimpleNamespace(__file__=str(source)),
|
|
)
|
|
monkeypatch.setattr(
|
|
scope.RuntimeConfig, "from_environment", classmethod(lambda cls: None),
|
|
)
|
|
status = scope.wrap_principal_runtime_from_environment(
|
|
Base(), role="issuer",
|
|
).readiness()
|
|
assert status["ready"] is True
|
|
assert status["source_module_path"] == str(source.resolve())
|
|
assert status["source_module_sha256"] == hashlib.sha256(
|
|
source.read_bytes()
|
|
).hexdigest()
|
|
|
|
|
|
def test_issuer_readiness_accepts_only_exact_python_m_main_module(monkeypatch, tmp_path):
|
|
source = tmp_path / "aios_task_principal_issuer_server.py"
|
|
source.write_bytes(b"# python -m issuer fixture\n")
|
|
|
|
class Base:
|
|
def readiness(self):
|
|
return {"ready": True}
|
|
|
|
monkeypatch.delitem(sys.modules, "aios_task_principal_issuer_server", raising=False)
|
|
main = SimpleNamespace(
|
|
__file__=str(source),
|
|
__spec__=SimpleNamespace(name="aios_task_principal_issuer_server"),
|
|
)
|
|
monkeypatch.setitem(sys.modules, "__main__", main)
|
|
monkeypatch.setattr(
|
|
scope.RuntimeConfig, "from_environment", classmethod(lambda cls: None),
|
|
)
|
|
composite = scope.wrap_principal_runtime_from_environment(Base(), role="issuer")
|
|
status = composite.readiness()
|
|
assert status["ready"] is True
|
|
assert status["source_module_path"] == str(source.resolve())
|
|
|
|
main.__spec__ = SimpleNamespace(name="untrusted_other_module")
|
|
status = composite.readiness()
|
|
assert status["ready"] is False
|
|
assert status["error"] == "C5_ISSUER_SOURCE_MODULE_MISSING"
|
|
|
|
|
|
def test_single_activation_config_is_exact_and_old_env_does_not_enable(monkeypatch, tmp_path):
|
|
monkeypatch.delenv("AIOS_C5_PRINCIPAL_SCOPE_CONFIG", raising=False)
|
|
monkeypatch.setenv("AIOS_C5_PRINCIPAL_SCOPE_ENABLED", "true")
|
|
assert scope.RuntimeConfig.from_environment() is None
|
|
config = {
|
|
"schema": "aios.c5-task-principal-activation.v1",
|
|
"task_id": scope.TASK_ID,
|
|
"agent_id": scope.AGENT_ID,
|
|
"execution_digest": scope.EXECUTION_DIGEST,
|
|
"store_path": "/var/lib/aios-task-principal-c5/scope-enrollment.sqlite3",
|
|
"grant_db": "/var/lib/aios-gitops/bridge-v2-staging/task-admission.sqlite3",
|
|
"plan_dir": "/var/lib/aios-gitops/bridge-v2-staging/releases/c5/plans",
|
|
"producer_state_root": "/var/lib/aios-gitops/bridge-v2-staging",
|
|
"policy_artifact": "/var/lib/aios-gitops/bridge-v2-staging/releases/c5/policy.json",
|
|
"policy_revocations": "/var/lib/aios-gitops/bridge-v2-staging/releases/c5/policy-revocations.json",
|
|
"epoch_root": "/var/lib/aios-gitops/bridge-v2-staging/releases/c5/epoch",
|
|
"epoch_revocations": "/var/lib/aios-gitops/bridge-v2-staging/releases/c5/epoch-revocations.json",
|
|
"owner_registry": "/etc/aios/single-host-signer-registry.json",
|
|
"owner_signer_id": "local-owner-authority",
|
|
"registered_signer_command": "/usr/local/libexec/aios-grant-signer-adapter",
|
|
"require_root_plan_owner": True,
|
|
"grant_db_allowed_group_gid": None,
|
|
}
|
|
path = tmp_path / "principal-activation.json"
|
|
_write(path, scope.canonical_json(config))
|
|
monkeypatch.setenv("AIOS_C5_PRINCIPAL_SCOPE_CONFIG", str(path.resolve()))
|
|
parsed = scope.RuntimeConfig.from_environment()
|
|
assert parsed is not None
|
|
assert str(parsed.owner_registry).replace("\\", "/") == "/etc/aios/single-host-signer-registry.json"
|
|
config["unexpected"] = True
|
|
_write(path, scope.canonical_json(config))
|
|
with pytest.raises(scope.C5PrincipalScopeError, match="C5_CONFIG_FIELDS_INVALID"):
|
|
scope.RuntimeConfig.from_environment()
|
|
|
|
|
|
def test_typed_issuer_signs_enrolls_and_replays_without_raw_artifact(monkeypatch, tmp_path):
|
|
service, _signatures, _paths, _store = _service(tmp_path)
|
|
calls = []
|
|
|
|
class RegistryVerifier:
|
|
def __init__(self, *args, **kwargs):
|
|
calls.append(("verifier", args, kwargs))
|
|
|
|
class Signer:
|
|
def __init__(self, *args, **kwargs):
|
|
calls.append(("signer", args, kwargs))
|
|
|
|
def _sign_canonical_payload(self, namespace, payload):
|
|
calls.append(("sign", namespace, payload))
|
|
return "valid-signature"
|
|
|
|
monkeypatch.setitem(
|
|
sys.modules, "aios_single_host_authority",
|
|
SimpleNamespace(RegistryOwnerApprovalVerifier=RegistryVerifier),
|
|
)
|
|
monkeypatch.setitem(
|
|
sys.modules, "registered_owner_signer_adapter",
|
|
SimpleNamespace(RegisteredOwnerSignerAdapter=Signer),
|
|
)
|
|
config = scope.RuntimeConfig(
|
|
store_path=tmp_path / "enrollments.sqlite3",
|
|
grant_db=tmp_path / "grant.sqlite3", plan_dir=tmp_path / "plans",
|
|
producer_state_root=tmp_path, policy_artifact=tmp_path / "policy.json",
|
|
policy_revocation_file=tmp_path / "policy-revocations.json",
|
|
epoch_root=tmp_path / "epoch",
|
|
epoch_revocation_file=tmp_path / "epoch-revocations.json",
|
|
owner_registry=Path("/etc/aios/single-host-signer-registry.json"),
|
|
owner_signer_id="local-owner-authority",
|
|
registered_signer_command=Path("/usr/local/libexec/aios-grant-signer-adapter"),
|
|
require_root_plan_owner=True, allowed_group_gid=None,
|
|
)
|
|
issuer = scope.C5ScopeEnrollmentIssuer(service, config)
|
|
receipt = issuer.issue(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW,
|
|
ttl_seconds=600,
|
|
)
|
|
assert receipt["status"] == "ENROLLED"
|
|
assert receipt["task_id"] == scope.TASK_ID
|
|
assert receipt["agent_id"] == scope.AGENT_ID
|
|
assert receipt["job_id"] == "job-c5-real"
|
|
assert "signature" not in receipt and "contract" not in receipt
|
|
replay = issuer.issue(
|
|
task=_task(), execution=_execution(), trust=TRUST, now=NOW,
|
|
ttl_seconds=600,
|
|
)
|
|
assert replay["replayed"] is True
|
|
assert len([item for item in calls if item[0] == "sign"]) == 1
|
|
|
|
|
|
def test_overlay_builder_patches_one_shared_admission_module(tmp_path, monkeypatch):
|
|
builder_path = ROOT / "scripts" / "build_c5_live_principal_overlay.py"
|
|
spec = importlib.util.spec_from_file_location("c5_overlay_builder_test", builder_path)
|
|
assert spec is not None and spec.loader is not None
|
|
builder = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(builder)
|
|
principal = tmp_path / "principal"
|
|
adapter = tmp_path / "adapter"
|
|
principal.mkdir()
|
|
adapter.mkdir()
|
|
admission_payload = b"# effective governed admission fixture\n"
|
|
(principal / "aios_task_principal_admission.py").write_bytes(admission_payload)
|
|
issuer_payload = (
|
|
b"class Base:\n"
|
|
b" _read_public_manifest = staticmethod(lambda path: path)\n"
|
|
b"_BASE = Base()\n"
|
|
b"MAX_BODY = 4 * 1024 * 1024\n"
|
|
b"def main():\n"
|
|
b" return None\n"
|
|
+ builder.ISSUER_MAIN_ANCHOR.encode()
|
|
)
|
|
(principal / "aios_task_principal_issuer_server.py").write_bytes(issuer_payload)
|
|
adapter_payloads = {
|
|
"aios_task_principal_governed_adapter.py": b"# governed adapter fixture\n",
|
|
"governed_runtime_scope.py": b"# governed scope fixture\n",
|
|
}
|
|
for name, payload in adapter_payloads.items():
|
|
(adapter / name).write_bytes(payload)
|
|
builder.PINNED = {
|
|
"aios_task_principal_admission.py": hashlib.sha256(
|
|
admission_payload
|
|
).hexdigest(),
|
|
"aios_task_principal_issuer_server.py": hashlib.sha256(
|
|
issuer_payload
|
|
).hexdigest(),
|
|
**{
|
|
name: hashlib.sha256(payload).hexdigest()
|
|
for name, payload in adapter_payloads.items()
|
|
},
|
|
}
|
|
output = tmp_path / "overlay"
|
|
monkeypatch.setattr(sys, "argv", [
|
|
str(builder_path), "--principal-source-root", str(principal),
|
|
"--adapter-source-root", str(adapter), "--output-root", str(output),
|
|
"--task-id", "fixture-governed-task", "--agent-id", "agent/fixture-c5",
|
|
])
|
|
assert builder.main() == 0
|
|
manifest = json.loads((output / "overlay-manifest.json").read_text())
|
|
assert manifest["activation"]["same_admission_overlay_for_both_units"] is True
|
|
assert manifest["entrypoints"]["issuer"] == "python3 -B -m aios_task_principal_issuer_server"
|
|
issuer_output = output / "app" / "aios_task_principal_issuer_server.py"
|
|
issuer_result = issuer_output.read_text()
|
|
assert issuer_result.startswith(issuer_payload.decode().split(
|
|
builder.ISSUER_MAIN_ANCHOR, 1
|
|
)[0])
|
|
assert "_read_public_manifest = _BASE._read_public_manifest" in issuer_result
|
|
assert issuer_result.count(builder.ISSUER_MAIN_ANCHOR) == 1
|
|
namespace = {"__name__": "issuer_fixture_import"}
|
|
exec(compile(issuer_result, str(issuer_output), "exec"), namespace)
|
|
assert namespace["_read_public_manifest"]("manifest.json") == "manifest.json"
|
|
assert namespace["MAX_BODY"] == 4 * 1024 * 1024
|
|
assert manifest["files"][issuer_output.name]["base_sha256"] == hashlib.sha256(
|
|
issuer_payload
|
|
).hexdigest()
|
|
assert manifest["files"][issuer_output.name]["result_sha256"] == hashlib.sha256(
|
|
issuer_output.read_bytes()
|
|
).hexdigest()
|
|
assert manifest["files"][issuer_output.name]["bridge_private_helper"] == (
|
|
"_read_public_manifest"
|
|
)
|
|
patched = (output / "app" / "aios_task_principal_admission.py").read_text()
|
|
assert builder.PINNED["aios_task_principal_admission.py"] == hashlib.sha256(
|
|
admission_payload
|
|
).hexdigest()
|
|
assert "_ORIGINAL_SCOPE_AND_TRUST = _legacy._scope_and_trust" in patched
|
|
assert 'if str(task["task_id"]) != C5_TASK_ID:' in patched
|
|
assert "return _ORIGINAL_SCOPE_AND_TRUST(" in patched
|
|
assert "active_digest, active_scope = _legacy._active_scope_chain(con)" in patched
|
|
assert "if active_digest != digest:" in patched
|
|
assert 'event["scope_id"] != active_scope["scope_id"]' in patched
|
|
assert "_legacy._check_revocations(con, task, active_scope, trust, None)" in patched
|
|
assert "wrap_principal_runtime_from_environment" in patched
|
|
assert manifest["files"]["aios_task_principal_admission.py"][
|
|
"runtime_base_source"
|
|
] == builder.EFFECTIVE_ADMISSION_SOURCE
|
|
assert hashlib.sha256(
|
|
(output / "app" / "aios_task_principal_governed_adapter.py").read_bytes()
|
|
).hexdigest() == scope.sha256_bytes((adapter / "aios_task_principal_governed_adapter.py").read_bytes())
|
|
assert "sys.dont_write_bytecode = True" in (
|
|
output / "bin" / "aios-c5-principal-scope"
|
|
).read_text()
|