Files
qbit-scripting/deploy/snapshot_execution.py
f0d695ec97
QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Failing after 7s
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Failing after 6s
QRun-IO/ci-policy: native / native-result (push) Successful in 6s
chore: preserve paused QBit work and document remaining issues
Save the current implementation and README, status, and known-issue documentation at the user-requested stop. No completed release or deployment is claimed.

Co-Authored-By: Claude <noreply@anthropic.com>

Co-Authored-By: GPT-6 Codex <noreply@openai.com>
2026-11-04 10:45:28 -06:00

182 lines
9.2 KiB
Python

# Copyright (C) 2026 Kingsrook, LLC.
# SPDX-License-Identifier: Apache-2.0
"""Copy a closed, hash-verified local candidate context. Never build or download."""
import argparse
import hashlib
import json
import logging
from pathlib import Path
import shutil
from typing import Any
import zipfile
ROOT = Path(__file__).resolve().parent
WASM_SHA = "4b247288d6cdff6783f8087a2a9039935f50af9099451cc841a3639c9625a18c"
EXTISM_SHA = "44eb7ed56c6b5610b97b9aa62a436e6ff7e3175730e487c42bb67105185d7e01"
JNA_SHA = "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557"
JNA_JNI_SHA = "ca07953d595210082339753d9e818a1fdb40509a17a41914d9a2cb0d2df6b6af"
JSON_SHA = "2a3438fbf9293174ea82bdfa35e83d8b965cfe6bddc034a1ac5d60107174c209"
FILES = {
"supervisor": ("payload/lib/supervisor.jar", None),
"jna": ("payload/lib/jna-5.18.1.jar", JNA_SHA),
"json": ("payload/lib/json-20251224.jar", JSON_SHA),
"extism": ("payload/native/libextism.so", EXTISM_SHA),
"wasm": ("payload/runtime/qqq_javy_runtime.wasm", WASM_SHA),
"license": ("metadata/LICENSE", None),
"notice": ("metadata/NOTICE", None),
"licenseReview": ("metadata/release-license-review.md", None),
"cargoInventory": ("metadata/license-inventory.json", None),
}
def digest(path: Path) -> str:
"""Hash local bytes without loading entire native binaries into memory."""
with path.open("rb") as stream:
return hashlib.file_digest(stream, "sha256").hexdigest()
def snapshot(inputs: dict[str, Any], destination: Path) -> dict[str, Any]:
"""Verify the closed input set, then copy into a new cache directory."""
if set(inputs) != set(FILES):
raise ValueError("Exact named local inputs required")
# Validate everything before creating the previously nonexistent context.
verified = {}
for name, (relative, pinned) in FILES.items():
item = inputs[name]
if not isinstance(item, dict) or set(item) != {"path", "sha256"}:
raise ValueError("Each input needs only path and SHA256")
path = Path(item["path"])
expected = item["sha256"]
if (not path.is_absolute() or not path.is_file() or path.is_symlink()
or path.stat().st_size > 256 * 1024 * 1024
or not isinstance(expected, str) or len(expected) != 64
or any(c not in "0123456789abcdef" for c in expected)
or (pinned is not None and expected != pinned)
or digest(path) != expected):
raise ValueError("Local input verification failed: " + name)
verified[name] = (path, relative, expected)
destination = Path(destination)
cache = (Path.home() / ".cache").resolve()
if (not destination.is_absolute() or destination.exists()
or not destination.resolve().is_relative_to(cache)):
raise ValueError("A new absolute output directory inside the current user's cache is required")
with zipfile.ZipFile(verified["supervisor"][0]) as jar:
names = jar.namelist()
if ("com/kingsrook/scripting/supervisor/SupervisorMain.class" not in names
or any(n.endswith(".class") and not n.startswith("com/kingsrook/scripting/supervisor/") for n in names)):
raise ValueError("Standalone supervisor JAR required; QQQ/QBit classes refused")
with zipfile.ZipFile(verified["jna"][0]) as jar:
jni = jar.read("com/sun/jna/linux-x86-64/libjnidispatch.so")
if (jni[:6] != b"\x7fELF\x02\x01" or jni[18:20] != b"\x3e\x00"
or len(jni) > 4 * 1024 * 1024 or hashlib.sha256(jni).hexdigest() != JNA_JNI_SHA):
raise ValueError("Pinned Linux JNI payload invalid")
with verified["extism"][0].open("rb") as stream:
header = stream.read(20)
if header[:6] != b"\x7fELF\x02\x01" or header[18:20] != b"\x3e\x00":
raise ValueError("Linux x86-64 Extism required")
with verified["wasm"][0].open("rb") as stream:
if stream.read(8) != b"\0asm\x01\0\0\0":
raise ValueError("Fixed Wasm header invalid")
destination.mkdir(parents=True)
records = []
for name, (source, relative, expected) in verified.items():
target = destination / relative
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(source, target)
if digest(target) != expected:
raise ValueError("Snapshot changed during copy: " + name)
records.append({"path": relative, "sha256": expected, "bytes": target.stat().st_size})
jni_path = destination / "payload/native/libjnidispatch.so"
jni_path.write_bytes(jni)
records.append({"path": jni_path.relative_to(destination).as_posix(),
"sha256": digest(jni_path), "bytes": len(jni)})
for filename in ("execution.Containerfile", "NOTICE-GAPS.md"):
relative = "Containerfile" if filename.endswith("Containerfile") else "metadata/NOTICE-GAPS.md"
shutil.copyfile(ROOT / filename, destination / relative)
records.append({"path": relative, "sha256": digest(destination / relative)})
(destination / ".dockerignore").write_text("*\n!Containerfile\n!payload/\n!payload/**\n!metadata/\n!metadata/**\n", encoding="utf-8")
records.append({"path": ".dockerignore", "sha256": digest(destination / ".dockerignore")})
manifest = {"productionQualified": False, "redistributionCleared": False,
"architecture": "linux/amd64", "files": records,
"supervisorClasses": sorted(n for n in names if n.endswith(".class")),
"jnaNativeEntry": "com/sun/jna/linux-x86-64/libjnidispatch.so",
"nativeSha256": EXTISM_SHA, "runtimeSha256": WASM_SHA,
"supervisorSha256": verified["supervisor"][2], "jnaJniSha256": digest(jni_path)}
(destination / "metadata/candidate.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
verify_snapshot(destination)
return manifest
def verify_snapshot(directory: Path) -> None:
"""Refuse unexpected context files or changed bytes immediately before a build."""
directory = directory.resolve(strict=True)
manifest_path = directory / "metadata/candidate.json"
if manifest_path.stat().st_size > 128 * 1024:
raise ValueError("Candidate manifest too large")
manifest = json.loads(manifest_path.read_text(encoding="utf-8"), object_pairs_hook=no_duplicates)
expected = {relative for relative, _ in FILES.values()} | {
"payload/native/libjnidispatch.so", "Containerfile", "metadata/NOTICE-GAPS.md", ".dockerignore",
}
rows = manifest["files"]
if (manifest["productionQualified"] is not False or manifest["redistributionCleared"] is not False
or manifest["architecture"] != "linux/amd64" or manifest["runtimeSha256"] != WASM_SHA
or manifest["nativeSha256"] != EXTISM_SHA or not isinstance(rows, list)
or len(rows) != len(expected) or {row["path"] for row in rows} != expected):
raise ValueError("Invalid candidate inventory")
actual = set()
for path in directory.rglob("*"):
if path.is_symlink() or not path.resolve().is_relative_to(directory):
raise ValueError("Links are not permitted in the build context")
if path.is_file():
actual.add(path.relative_to(directory).as_posix())
if actual != expected | {"metadata/candidate.json"}:
raise ValueError("Unexpected or missing build-context file")
hashes = {row["path"]: row["sha256"] for row in rows}
for relative in expected:
if digest(directory / relative) != hashes[relative]:
raise ValueError("Changed build-context bytes")
for relative, pinned in FILES.values():
if pinned is not None and hashes[relative] != pinned:
raise ValueError("Pinned input identity changed")
if (hashes["payload/lib/supervisor.jar"] != manifest["supervisorSha256"]
or hashes["payload/native/libjnidispatch.so"] != manifest["jnaJniSha256"]
or manifest["jnaJniSha256"] != JNA_JNI_SHA
or hashes["Containerfile"] != digest(ROOT / "execution.Containerfile")
or hashes["metadata/NOTICE-GAPS.md"] != digest(ROOT / "NOTICE-GAPS.md")):
raise ValueError("Candidate linkage mismatch")
def no_duplicates(pairs: list[tuple[str, Any]]) -> dict[str, Any]:
"""Reject ambiguous input descriptors rather than last-key-wins parsing."""
result = {}
for key, value in pairs:
if key in result:
raise ValueError("Duplicate input key")
result[key] = value
return result
def main() -> None:
"""Create local packaging evidence without a build or network operation."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("inputs", type=Path, nargs="?")
parser.add_argument("output", type=Path, nargs="?")
parser.add_argument("--verify", type=Path)
args = parser.parse_args()
if args.verify is not None:
if args.inputs is not None or args.output is not None:
raise ValueError("Verification accepts only the existing context directory")
verify_snapshot(args.verify)
logging.warning("Closed candidate context verified; no build performed")
return
if args.inputs is None or args.output is None:
raise ValueError("Local input descriptor and new cache output are required")
if args.inputs.stat().st_size > 32 * 1024:
raise ValueError("Input descriptor too large")
snapshot(json.loads(args.inputs.read_text(encoding="utf-8"), object_pairs_hook=no_duplicates), args.output)
logging.warning("Local candidate snapshot verified; unqualified; no build performed")
if __name__ == "__main__":
main()