Files
opensquilla--opensquilla/tests/test_skills_provenance_contract.py
2026-07-13 13:12:33 +08:00

132 lines
5.1 KiB
Python

from __future__ import annotations
from pathlib import Path
from opensquilla.skills.loader import SkillLoader
ROOT = Path(__file__).resolve().parents[1]
SKILLS_DIR = ROOT / "src" / "opensquilla" / "skills"
BUNDLED = SKILLS_DIR / "bundled"
EXP = SKILLS_DIR / "exp"
DEFAULTS = {"skill-creator", "pptx", "memory", "cron", "github"}
def test_default_bundled_skills_have_release_provenance(tmp_path: Path) -> None:
loader = SkillLoader(bundled_dir=BUNDLED, snapshot_path=tmp_path / "snapshot.json")
skills = {skill.name: skill for skill in loader.load_all()}
for name in DEFAULTS:
provenance = skills[name].provenance
assert provenance.origin in {
"opensquilla-original",
"bundled-derived",
"openclaw-derived",
"clawhub-mit",
"clawhub-mit0",
}
assert provenance.maintained_by == "OpenSquilla"
if provenance.origin == "bundled-derived":
assert provenance.upstream_url.startswith("https://")
assert provenance.license == "MIT"
elif provenance.origin == "openclaw-derived":
assert provenance.upstream_url == "https://github.com/openclaw/openclaw"
assert provenance.license == "MIT"
elif provenance.origin == "clawhub-mit0":
assert provenance.upstream_url.startswith("https://clawhub.ai/")
assert provenance.license == "MIT-0"
elif provenance.origin == "clawhub-mit":
assert provenance.upstream_url.startswith("https://clawhub.ai/")
assert provenance.license == "MIT"
else:
assert provenance.license == "Apache-2.0"
def test_provenance_survives_snapshot_roundtrip(tmp_path: Path) -> None:
snapshot = tmp_path / "snapshot.json"
loader = SkillLoader(bundled_dir=BUNDLED, extra_dirs=[EXP], snapshot_path=snapshot)
first = {skill.name: skill.provenance for skill in loader.load_all()}
loader.save_snapshot()
reloaded = SkillLoader(bundled_dir=BUNDLED, extra_dirs=[EXP], snapshot_path=snapshot)
second = {skill.name: skill.provenance for skill in reloaded.load_all()}
for name in DEFAULTS:
assert second[name] == first[name]
def test_entrypoint_manifest_survives_snapshot_roundtrip(tmp_path: Path) -> None:
"""skill_exec depends on the entrypoint manifest surviving the snapshot
cache — a gateway cold-start that loads from snapshot must see the same
entrypoint dict as a fresh frontmatter parse."""
snapshot = tmp_path / "snapshot.json"
loader = SkillLoader(bundled_dir=BUNDLED, snapshot_path=snapshot)
fresh = {skill.name: skill.entrypoint for skill in loader.load_all()}
loader.save_snapshot()
reloaded = SkillLoader(bundled_dir=BUNDLED, snapshot_path=snapshot)
from_snapshot = {skill.name: skill.entrypoint for skill in reloaded.load_all()}
# multi-search-engine is the canonical skill_exec target — its entrypoint
# must round-trip intact.
assert fresh["multi-search-engine"] is not None
assert fresh["multi-search-engine"] == from_snapshot["multi-search-engine"]
assert "command" in fresh["multi-search-engine"]
# Skills without an entrypoint manifest should still round-trip as None.
for name, ep in fresh.items():
assert from_snapshot[name] == ep, f"entrypoint mismatch for {name}"
def test_meta_final_text_mode_survives_snapshot_roundtrip(tmp_path: Path) -> None:
"""Gateway cold-starts often load skills from snapshot; meta final output
controls must not degrade back to auto-summary mode."""
snapshot = tmp_path / "snapshot.json"
loader = SkillLoader(bundled_dir=BUNDLED, extra_dirs=[EXP], snapshot_path=snapshot)
fresh = {skill.name: skill.final_text_mode for skill in loader.load_all()}
loader.save_snapshot()
reloaded = SkillLoader(bundled_dir=BUNDLED, extra_dirs=[EXP], snapshot_path=snapshot)
from_snapshot = {
skill.name: skill.final_text_mode for skill in reloaded.load_all()
}
assert fresh["meta-travel-planner"] == "step:final_plan"
assert from_snapshot["meta-travel-planner"] == fresh["meta-travel-planner"]
def test_capability_risk_metadata_survives_snapshot_roundtrip(tmp_path: Path) -> None:
"""Auto-enable decisions must see the same risk manifest after cold-start."""
skill_root = tmp_path / "skills"
skill_dir = skill_root / "writes-files"
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text(
"""---
name: writes-files
description: Synthetic skill with manifest risk metadata.
metadata:
opensquilla:
risk: medium
capabilities: [filesystem-write]
---
# body
""",
encoding="utf-8",
)
snapshot = tmp_path / "snapshot.json"
loader = SkillLoader(bundled_dir=skill_root, snapshot_path=snapshot)
fresh = loader.get_by_name("writes-files")
assert fresh is not None
loader.save_snapshot()
reloaded = SkillLoader(bundled_dir=skill_root, snapshot_path=snapshot)
from_snapshot = reloaded.get_by_name("writes-files")
assert from_snapshot is not None
assert from_snapshot.metadata is not None
assert from_snapshot.metadata.risk_level == "medium"
assert from_snapshot.metadata.capabilities == ["filesystem-write"]