Split meta skill CLI and review gates
Merge the beta-ready Yao Meta Skill architecture, report, evidence gate, and release-boundary updates.\n\nRelease boundary: beta/public testing is allowed; formal world-class, fully reviewed, or superiority claims remain blocked until the pending evidence gates are accepted.
This commit is contained in:
+118
-12
@@ -4,7 +4,7 @@ import json
|
||||
import shutil
|
||||
import tempfile
|
||||
import zipfile
|
||||
from datetime import date
|
||||
from datetime import date, datetime
|
||||
from pathlib import Path, PurePosixPath
|
||||
from typing import Any
|
||||
|
||||
@@ -91,22 +91,111 @@ def add_check(checks: list[dict[str, str]], failures: list[str], check_id: str,
|
||||
failures.append(detail)
|
||||
|
||||
|
||||
def adapter_targets(package_dir: Path) -> list[str]:
|
||||
targets_dir = package_dir / "targets"
|
||||
def package_name(package_manifest: dict[str, Any], skill_dir: Path) -> str:
|
||||
return str(package_manifest.get("name") or skill_dir.name)
|
||||
|
||||
|
||||
def adapter_targets(adapter_root: Path) -> list[str]:
|
||||
targets_dir = adapter_root / "targets"
|
||||
if not targets_dir.exists():
|
||||
return []
|
||||
return sorted(path.name for path in targets_dir.iterdir() if path.is_dir())
|
||||
|
||||
|
||||
def sorted_strings(value: Any) -> list[str]:
|
||||
return sorted(str(item) for item in value) if isinstance(value, list) else []
|
||||
|
||||
|
||||
def parse_date(value: str) -> date | None:
|
||||
try:
|
||||
return datetime.strptime(value, "%Y-%m-%d").date()
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def permission_policy_checks(
|
||||
installed_dir: Path | None,
|
||||
adapter_root: Path,
|
||||
targets: list[str],
|
||||
generated_at: str,
|
||||
checks: list[dict[str, str]],
|
||||
failures: list[str],
|
||||
) -> dict[str, int]:
|
||||
installed = installed_dir is not None and installed_dir.exists() and installed_dir.is_dir()
|
||||
policy = load_json(installed_dir / "security" / "permission_policy.json") if installed else {}
|
||||
capabilities = policy.get("capabilities", {}) if isinstance(policy.get("capabilities"), dict) else {}
|
||||
generated_date = parse_date(generated_at[:10])
|
||||
enforced_count = 0
|
||||
permission_failure_start = len(failures)
|
||||
declared_capabilities: set[str] = set()
|
||||
|
||||
add_check(checks, failures, "permission-policy-load", bool(capabilities), "Installed permission policy is readable")
|
||||
for target in targets:
|
||||
adapter = load_json(adapter_root / "targets" / target / "adapter.json")
|
||||
target_contract = adapter.get("target_permission_contract", {}) if isinstance(adapter, dict) else {}
|
||||
target_capabilities = sorted_strings(target_contract.get("declared_capabilities"))
|
||||
declared_capabilities.update(target_capabilities)
|
||||
add_check(
|
||||
checks,
|
||||
failures,
|
||||
f"permission-{target}-contract",
|
||||
bool(target_contract),
|
||||
f"{target} adapter exposes target permission contract for installer enforcement",
|
||||
)
|
||||
if not target_capabilities:
|
||||
continue
|
||||
for capability in target_capabilities:
|
||||
approval = capabilities.get(capability, {}) if isinstance(capabilities, dict) else {}
|
||||
enforcement = approval.get("target_enforcement", {}) if isinstance(approval.get("target_enforcement"), dict) else {}
|
||||
expires_at = str(approval.get("expires_at", "")).strip()
|
||||
expiry_date = parse_date(expires_at) if expires_at else None
|
||||
common_ok = (
|
||||
approval.get("decision") == "approved"
|
||||
and bool(str(approval.get("reviewer", "")).strip())
|
||||
and bool(str(approval.get("scope", "")).strip())
|
||||
and bool(str(approval.get("reason", "")).strip())
|
||||
and isinstance(approval.get("evidence"), list)
|
||||
and bool(approval.get("evidence"))
|
||||
and bool(enforcement)
|
||||
and expiry_date is not None
|
||||
and (generated_date is None or expiry_date >= generated_date)
|
||||
)
|
||||
add_check(
|
||||
checks,
|
||||
failures,
|
||||
f"permission-{target}-{capability}-approved",
|
||||
bool(common_ok),
|
||||
f"{target} capability {capability} has active reviewer approval",
|
||||
)
|
||||
target_enforcement_ok = bool(str(enforcement.get(target, "")).strip())
|
||||
add_check(
|
||||
checks,
|
||||
failures,
|
||||
f"permission-{target}-{capability}-target-enforcement",
|
||||
target_enforcement_ok,
|
||||
f"{target} capability {capability} has target enforcement note",
|
||||
)
|
||||
if common_ok and target_enforcement_ok:
|
||||
enforced_count += 1
|
||||
|
||||
return {
|
||||
"installer_permission_enforced_count": enforced_count,
|
||||
"installer_permission_failure_count": len(failures) - permission_failure_start,
|
||||
"permission_target_count": len(targets),
|
||||
"permission_capability_count": len(declared_capabilities),
|
||||
}
|
||||
|
||||
|
||||
def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | None, generated_at: str) -> dict[str, Any]:
|
||||
skill_dir = skill_dir.resolve()
|
||||
package_dir = package_dir.resolve()
|
||||
checks: list[dict[str, str]] = []
|
||||
failures: list[str] = []
|
||||
warnings: list[str] = []
|
||||
archive_path = package_dir / f"{skill_dir.name}.zip"
|
||||
package_manifest = load_json(package_dir / "manifest.json")
|
||||
installed_dir = Path("")
|
||||
package_root = package_name(package_manifest, skill_dir)
|
||||
archive_path = package_dir / f"{package_root}.zip"
|
||||
installed_dir: Path | None = None
|
||||
archive_entries: list[str] = []
|
||||
|
||||
temp_dir: tempfile.TemporaryDirectory[str] | None = None
|
||||
@@ -117,7 +206,7 @@ def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | No
|
||||
else:
|
||||
requested_root = install_root.resolve()
|
||||
requested_root.mkdir(parents=True, exist_ok=True)
|
||||
install_base = requested_root / f"simulate-{skill_dir.name}"
|
||||
install_base = requested_root / f"simulate-{package_root}"
|
||||
if install_base.exists():
|
||||
shutil.rmtree(install_base)
|
||||
install_base.mkdir(parents=True, exist_ok=True)
|
||||
@@ -134,7 +223,7 @@ def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | No
|
||||
unsafe_entries = unsafe_zip_entries(archive_entries)
|
||||
add_check(checks, failures, "archive-safe-paths", not unsafe_entries, "Archive has no absolute or parent-traversal entries")
|
||||
roots = top_level_dirs(archive_entries)
|
||||
add_check(checks, failures, "single-top-level", roots == [skill_dir.name], f"Archive top-level directory is {skill_dir.name}")
|
||||
add_check(checks, failures, "single-top-level", roots == [package_root], f"Archive top-level directory is {package_root}")
|
||||
if not unsafe_entries and roots:
|
||||
with zipfile.ZipFile(archive_path) as archive:
|
||||
archive.extractall(install_base)
|
||||
@@ -144,18 +233,31 @@ def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | No
|
||||
source_manifest = load_json(installed_dir / "manifest.json") if installed_dir else {}
|
||||
interface_doc = load_yaml(installed_dir / "agents" / "interface.yaml") if installed_dir else {}
|
||||
add_check(checks, failures, "entrypoint-load", bool(frontmatter), "Installed SKILL.md frontmatter is readable")
|
||||
add_check(checks, failures, "entrypoint-name", frontmatter.get("name") == skill_dir.name, "Installed SKILL.md name matches package directory")
|
||||
add_check(checks, failures, "entrypoint-name", frontmatter.get("name") == package_root, "Installed SKILL.md name matches package directory")
|
||||
add_check(checks, failures, "entrypoint-description", bool(frontmatter.get("description")), "Installed SKILL.md description is present")
|
||||
add_check(checks, failures, "manifest-load", bool(source_manifest), "Installed manifest.json is readable")
|
||||
add_check(checks, failures, "manifest-name", source_manifest.get("name") == package_manifest.get("name"), "Installed manifest name matches package manifest")
|
||||
add_check(checks, failures, "manifest-version", source_manifest.get("version") == package_manifest.get("version"), "Installed manifest version matches package manifest")
|
||||
add_check(checks, failures, "interface-load", bool(interface_doc.get("interface")), "Installed agents/interface.yaml is readable")
|
||||
add_check(checks, failures, "overview-report", (installed_dir / "reports" / "skill-overview.html").exists(), "Installed overview report is present")
|
||||
add_check(checks, failures, "review-studio-report", (installed_dir / "reports" / "review-studio.html").exists(), "Installed Review Studio report is present")
|
||||
add_check(
|
||||
checks,
|
||||
failures,
|
||||
"overview-report",
|
||||
installed_dir is not None and (installed_dir / "reports" / "skill-overview.html").exists(),
|
||||
"Installed overview report is present",
|
||||
)
|
||||
add_check(
|
||||
checks,
|
||||
failures,
|
||||
"review-studio-report",
|
||||
installed_dir is not None and (installed_dir / "reports" / "review-studio.html").exists(),
|
||||
"Installed Review Studio report is present",
|
||||
)
|
||||
|
||||
adapters = adapter_targets(package_dir)
|
||||
adapter_root = package_dir
|
||||
adapters = adapter_targets(adapter_root)
|
||||
for target in adapters:
|
||||
adapter = load_json(package_dir / "targets" / target / "adapter.json")
|
||||
adapter = load_json(adapter_root / "targets" / target / "adapter.json")
|
||||
add_check(checks, failures, f"adapter-{target}", bool(adapter), f"{target} adapter is readable after package install simulation")
|
||||
add_check(
|
||||
checks,
|
||||
@@ -165,6 +267,7 @@ def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | No
|
||||
f"{target} adapter name matches package manifest",
|
||||
)
|
||||
|
||||
permission_summary = permission_policy_checks(installed_dir, adapter_root, adapters, generated_at, checks, failures)
|
||||
if not adapters:
|
||||
warnings.append("No target adapters found in package directory.")
|
||||
|
||||
@@ -191,6 +294,7 @@ def simulate_install(skill_dir: Path, package_dir: Path, install_root: Path | No
|
||||
"manifest_loaded": bool(source_manifest),
|
||||
"interface_loaded": bool(interface_doc.get("interface")),
|
||||
"adapter_count": len(adapters),
|
||||
**permission_summary,
|
||||
"install_root_is_temp": install_root_is_temp,
|
||||
"failure_count": len(failures),
|
||||
"warning_count": len(warnings),
|
||||
@@ -221,6 +325,8 @@ def render_markdown(report: dict[str, Any]) -> str:
|
||||
f"- Manifest loaded: `{summary['manifest_loaded']}`",
|
||||
f"- Interface loaded: `{summary['interface_loaded']}`",
|
||||
f"- Adapters readable: `{summary['adapter_count']}`",
|
||||
f"- Installer permissions enforced: `{summary.get('installer_permission_enforced_count', 0)}`",
|
||||
f"- Installer permission failures: `{summary.get('installer_permission_failure_count', 0)}`",
|
||||
f"- Failures: `{summary['failure_count']}`",
|
||||
f"- Warnings: `{summary['warning_count']}`",
|
||||
"",
|
||||
|
||||
Reference in New Issue
Block a user