|
| 1 | +"""System agent template: versioned, hashed, shaped like the agent-studio blueprint payload.""" |
| 2 | +from __future__ import annotations |
| 3 | + |
| 4 | +import hashlib |
| 5 | +import json |
| 6 | +import re |
| 7 | +from importlib import resources |
| 8 | + |
| 9 | +from githubbot_core import __version__, cli |
| 10 | + |
| 11 | +# Rules of the consuming agent-studio save/materialize path (blueprint service). |
| 12 | +NAME = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,79}$") |
| 13 | +KINDS = {"agent", "role", "skill", "workflow", "service", "contractus"} |
| 14 | +ANIMUS = {"api", "cli", "subscription", "local"} |
| 15 | +EXECUTABLE_MODUS = {"casualis", "usus"} |
| 16 | + |
| 17 | + |
| 18 | +def _system_agent(capsys, *extra: str) -> dict: |
| 19 | + assert cli.main([*extra, "--json", "system-agent"]) == 0 |
| 20 | + envelope = json.loads(capsys.readouterr().out) |
| 21 | + assert envelope["ok"] is True and envelope["mode"] == "read" |
| 22 | + return envelope["data"] |
| 23 | + |
| 24 | + |
| 25 | +def test_template_identity_is_version_plus_canonical_hash(capsys): |
| 26 | + data = _system_agent(capsys) |
| 27 | + template = json.loads(resources.files("githubbot_core").joinpath("system_agent.json").read_text(encoding="utf-8")) |
| 28 | + canonical = json.dumps(template, sort_keys=True, separators=(",", ":"), ensure_ascii=False) |
| 29 | + assert data["schema"] == "githubbot-core.system-agent/v1" |
| 30 | + assert data["id"] == "githubbot" and data["version"] == __version__ |
| 31 | + assert data["sha256"] == hashlib.sha256(canonical.encode("utf-8")).hexdigest() |
| 32 | + assert data["capability"] == {"package": "githubbot-core", "version": __version__, "spi_version": 1} |
| 33 | + |
| 34 | + |
| 35 | +def test_blueprint_is_accepted_by_the_agent_studio_payload_rules(capsys): |
| 36 | + bp = _system_agent(capsys)["blueprint"] |
| 37 | + assert NAME.fullmatch(bp["name"]) and bp["name"] == bp["name"].lower() |
| 38 | + assert bp["kind"] in KINDS and bp["kind"] == "agent" |
| 39 | + assert bp["persona_prompt"].strip() and len(bp["title"]) <= 120 |
| 40 | + assert bp["animus_type"] in ANIMUS and bp["modus"] in EXECUTABLE_MODUS |
| 41 | + assert isinstance(bp["skills"], list) and all(NAME.fullmatch(s) for s in bp["skills"]) |
| 42 | + assert isinstance(bp["contractus"], dict) and isinstance(bp["governance"], dict) |
| 43 | + assert "is_template" not in bp # system templates are registered by the consumer, never self-declared |
| 44 | + |
| 45 | + |
| 46 | +def test_permissions_are_the_effective_narrowed_configuration(capsys, tmp_path): |
| 47 | + layer = tmp_path / "narrow.json" |
| 48 | + layer.write_text(json.dumps({"permissions": {"enabled": []}}), encoding="utf-8") |
| 49 | + assert _system_agent(capsys)["permissions"]["enabled"] == ["issue.add_labels", "issue.comment"] |
| 50 | + assert _system_agent(capsys, "--config", str(layer))["permissions"]["enabled"] == [] |
0 commit comments