Alpino-playground / prepare_bundle.py
cyberandy's picture
Deploy Alpino v0.2 with live AOOE runtime snapshot
acced71 verified
Raw
History Blame Contribute Delete
6.7 kB
#!/usr/bin/env python3
"""Build the bounded fallback/runtime contract for the Alpino operator Space.
The Space reads the published alpina.travel KG live and reads editorial Markdown
from current GitHub main. This bundle supplies the exact ontology, tool contract,
entity/path index and a deterministic fallback graph needed to construct the
runtime safely; it is not the primary operator evidence source.
"""
from __future__ import annotations
import hashlib
import json
import os
import shutil
import subprocess
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path
from rdflib import Graph
SPACE_DIR = Path(__file__).resolve().parent
REPO_ROOT = SPACE_DIR.parents[1]
SNAPSHOT_DIR = SPACE_DIR / "runtime_snapshot"
ADAPTER_ID = "cyberandy/Alpino-e4b-v02"
ADAPTER_REVISION = "d5f49f6a85b0c7788f4afbfea4f53d470d2673a3"
LIVE_GRAPH_URL = "https://alpina.travel/lungau/data/graph.rdf"
def sha256_file(path: Path) -> str:
h = hashlib.sha256()
with path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
def sha256_tree(path: Path) -> tuple[str, int]:
h = hashlib.sha256()
count = 0
if not path.exists():
return h.hexdigest(), count
for file_path in sorted(p for p in path.rglob("*") if p.is_file()):
relative = file_path.relative_to(path).as_posix().encode("utf-8")
h.update(relative)
h.update(b"\0")
with file_path.open("rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
h.update(chunk)
h.update(b"\0")
count += 1
return h.hexdigest(), count
def git_sha() -> str:
override = (os.getenv("ALPINO_SOURCE_COMMIT") or "").strip()
if override:
return override
return subprocess.check_output(
["git", "rev-parse", "HEAD"],
cwd=REPO_ROOT,
text=True,
).strip()
def copy_file(relative: str, destination_root: Path) -> None:
source = REPO_ROOT / relative
if not source.exists():
raise FileNotFoundError(f"required Space runtime source is missing: {relative}")
destination = destination_root / relative
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, destination)
def copy_optional(relative: str, destination_root: Path) -> None:
source = REPO_ROOT / relative
if not source.exists():
return
destination = destination_root / relative
destination.parent.mkdir(parents=True, exist_ok=True)
if source.is_dir():
shutil.copytree(source, destination, dirs_exist_ok=True)
else:
shutil.copy2(source, destination)
def main() -> None:
source_commit = git_sha()
with tempfile.TemporaryDirectory(prefix="alpino-space-snapshot-") as temp_dir:
temp = Path(temp_dir)
staged = temp / "runtime_snapshot"
graph_path = staged / "data/lungau/kg-candidate.ttl"
records_path = staged / "build/content-records.json"
graph_path.parent.mkdir(parents=True, exist_ok=True)
records_path.parent.mkdir(parents=True, exist_ok=True)
# Materialize a deterministic governed fallback without publication credentials.
env = os.environ.copy()
env.pop("WORDLIFT_API_KEY", None)
command = [
sys.executable,
str(REPO_ROOT / "scripts/wordlift/sync_to_wordlift.py"),
"--validate-only",
"--status",
"proposed",
"--source-commit",
source_commit,
"--output",
str(graph_path),
"--records-output",
str(records_path),
]
subprocess.run(command, cwd=REPO_ROOT, env=env, check=True)
required = [
"tools/aooe_training_runtime.py",
"tools/aooe_trace_protocol.py",
"tools/compile_webmaster_traces.py",
"tools/aooe_content_observer.py",
"bcs/webmaster-operations/tool-affordances.json",
"data/lungau/entities.yaml",
"ontology/core.ttl",
"ontology/axioms.ttl",
"ontology/shapes.ttl",
"scripts/wordlift/sync_to_wordlift.py",
]
for relative in required:
copy_file(relative, staged)
for relative in [
"ontology/imports.ttl",
"evidence/reconciliation",
"data/lungau/campaigns.yaml",
"data/lungau/campaigns.yml",
"data/lungau/campaigns.json",
"content/campaigns",
"content/lungau",
]:
copy_optional(relative, staged)
graph = Graph().parse(graph_path, format="turtle")
contract_path = staged / "bcs/webmaster-operations/tool-affordances.json"
entities_path = staged / "data/lungau/entities.yaml"
content_path = staged / "content/lungau"
content_sha, content_files = sha256_tree(content_path)
manifest = {
"bundleVersion": "0.5",
"runtime": "WebmasterOpenBookRuntime",
"modelAdapter": ADAPTER_ID,
"modelAdapterRevision": ADAPTER_REVISION,
"baseModel": "google/gemma-4-E4B-it",
"sourceCommit": source_commit,
"generatedAt": datetime.now(timezone.utc).isoformat(),
"graphSha256": sha256_file(graph_path),
"graphTriples": len(graph),
"contractSha256": sha256_file(contract_path),
"entitiesSha256": sha256_file(entities_path),
"contentSha256": content_sha,
"contentFiles": content_files,
"operatorEvidence": {
"kgReads": "live-published-graph",
"liveGraphUrl": LIVE_GRAPH_URL,
"contentReads": "github-main-live",
"bundleRole": "contract-path-index-and-fallback",
},
"mutationBoundary": {
"kgMaterialization": "validate-only-fallback",
"wordliftCredentialInjected": False,
"runtimeActs": "brokered-bounded-draft-pr",
"liveKgWrites": False,
"mergeAllowed": False,
"publishAllowed": False,
},
}
(staged / "manifest.json").write_text(
json.dumps(manifest, indent=2, sort_keys=True) + "\n",
encoding="utf-8",
)
if SNAPSHOT_DIR.exists():
shutil.rmtree(SNAPSHOT_DIR)
shutil.copytree(staged, SNAPSHOT_DIR)
print(json.dumps(manifest, indent=2))
print(f"Prepared HF Space runtime contract at {SNAPSHOT_DIR}")
if __name__ == "__main__":
main()