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:
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Git source/generated dirty classification for benchmark release locks."""
|
||||
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
SCRIPT_INTERFACE = "internal-module"
|
||||
SCRIPT_INTERFACE_REASON = "Imported by render_benchmark_reproducibility.py to keep release-lock git status classification out of the report renderer."
|
||||
|
||||
|
||||
GENERATED_DIRTY_PREFIXES = (
|
||||
"dist/",
|
||||
"registry/index.json",
|
||||
"registry/packages/",
|
||||
"reports/",
|
||||
"skill_atlas/",
|
||||
"skill-ir/examples/",
|
||||
)
|
||||
|
||||
|
||||
def status_path(line: str) -> str:
|
||||
path = line[3:].strip() if len(line) > 3 else line.strip()
|
||||
if " -> " in path:
|
||||
path = path.rsplit(" -> ", 1)[-1].strip()
|
||||
return path
|
||||
|
||||
|
||||
def is_generated_dirty_path(path: str) -> bool:
|
||||
return any(path == prefix.rstrip("/") or path.startswith(prefix) for prefix in GENERATED_DIRTY_PREFIXES)
|
||||
|
||||
|
||||
def git_status(skill_dir: Path) -> dict[str, Any]:
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
["git", "status", "--short", "--untracked-files=all"],
|
||||
cwd=skill_dir,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
return {
|
||||
"available": False,
|
||||
"dirty": None,
|
||||
"changed_file_count": None,
|
||||
"source_dirty": None,
|
||||
"source_changed_file_count": None,
|
||||
"generated_dirty": None,
|
||||
"generated_changed_file_count": None,
|
||||
}
|
||||
lines = [line for line in proc.stdout.splitlines() if line.strip()]
|
||||
paths = [status_path(line) for line in lines]
|
||||
generated_lines = [line for line, path in zip(lines, paths) if is_generated_dirty_path(path)]
|
||||
source_lines = [line for line, path in zip(lines, paths) if not is_generated_dirty_path(path)]
|
||||
return {
|
||||
"available": True,
|
||||
"dirty": bool(lines),
|
||||
"changed_file_count": len(lines),
|
||||
"generated_dirty": bool(generated_lines),
|
||||
"generated_changed_file_count": len(generated_lines),
|
||||
"source_dirty": bool(source_lines),
|
||||
"source_changed_file_count": len(source_lines),
|
||||
"sample": lines[:12],
|
||||
"source_sample": source_lines[:12],
|
||||
"generated_sample": generated_lines[:12],
|
||||
"generated_dirty_prefixes": list(GENERATED_DIRTY_PREFIXES),
|
||||
"scope": "generation-time status before this report is written",
|
||||
}
|
||||
|
||||
|
||||
def release_lock_status(status: dict[str, Any], commit: str) -> dict[str, Any]:
|
||||
available = status.get("available") is True
|
||||
source_clean = status.get("source_dirty") is False
|
||||
known_commit = bool(commit and commit != "unknown")
|
||||
ready = available and source_clean and known_commit
|
||||
reasons = []
|
||||
if not available:
|
||||
reasons.append("git status unavailable")
|
||||
if not known_commit:
|
||||
reasons.append("git commit unavailable")
|
||||
if status.get("source_dirty") is True:
|
||||
reasons.append("source files were dirty at generation time")
|
||||
if status.get("source_dirty") is None:
|
||||
reasons.append("working tree cleanliness unknown")
|
||||
if status.get("generated_dirty") is True and status.get("source_dirty") is False:
|
||||
reasons.append("only generated evidence artifacts were dirty at generation time")
|
||||
if not reasons:
|
||||
reasons.append("clean source tree at generation-time HEAD")
|
||||
return {
|
||||
"ready": ready,
|
||||
"commit": commit,
|
||||
"status_scope": status.get("scope", "generation-time status"),
|
||||
"source_changed_file_count": status.get("source_changed_file_count"),
|
||||
"generated_changed_file_count": status.get("generated_changed_file_count"),
|
||||
"reason": "; ".join(reasons),
|
||||
}
|
||||
Reference in New Issue
Block a user