mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
8ab7c3d5f1
* feat(standalone): add shell-neutral exact lifecycle * feat(terminal): add native exact cold-start carrier * test(terminal): exercise mutable exact channel heads * feat(standalone): model synced blobs and Shell updates * feat(terminal): exercise the complete Shell lifecycle * feat(release): add the independent exact Terminal line * test(exact): run the full local Terminal release line * feat(terminal): harden exact Sidecar lifecycle * feat(standalone): prove exact update transactions * refactor(standalone): separate shell lifecycle dimensions * refactor(e2e): decouple terminal exact drivers * refactor(terminal): isolate exact sidecar fixture host * feat(terminal): gate handoff on physical retirement * refactor(release): gate exact activation on public acceptance * test(terminal): formalize guarded lifecycle algebra * fix(terminal): guard shell installer handoff * feat(terminal): add exact bootloader handoff * feat(terminal): integrate exact sidecar lifecycle * refactor(exact): rename validation channels * test(terminal): harden exact release acceptance * fix(postinstall): build standalone dependencies first Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix(ci): build the native Terminal scene Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * test(ci): cover exact convergence handoff routing Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix(exact): isolate terminal validation from main CI * fix(terminal): complete shell update confirmation Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix(exact): bind acceptance to installed manifest Generated-By: looper 0.11.2 (runner=fixer, agent=codex) * fix(standalone): block occupied shell installs Generated-By: looper 0.11.2 (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com>
349 lines
18 KiB
Python
349 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
"""Publish immutable exact objects and activate accepted channel heads."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import re
|
|
import urllib.error
|
|
import urllib.request
|
|
from typing import Any
|
|
|
|
IDENTIFIER = re.compile(r"^[a-z][a-z0-9-]{0,31}$")
|
|
|
|
|
|
def read_json(path: Path) -> dict[str, Any]:
|
|
value = json.loads(path.read_text(encoding="utf-8"))
|
|
if not isinstance(value, dict):
|
|
raise SystemExit(f"JSON document must be an object: {path}")
|
|
return value
|
|
|
|
|
|
def write_json(path: Path, value: dict[str, Any]) -> None:
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
path.write_text(json.dumps(value, sort_keys=True, separators=(",", ":")) + "\n", encoding="utf-8")
|
|
|
|
|
|
def http(url: str, method: str = "GET", body: bytes | None = None, headers: dict[str, str] | None = None):
|
|
request_headers = dict(headers or {})
|
|
token = os.environ.get("OD_EXACT_RELEASE_TOKEN")
|
|
if token:
|
|
request_headers["Authorization"] = f"Bearer {token}"
|
|
value = urllib.request.Request(url, data=body, headers=request_headers, method=method)
|
|
try:
|
|
return urllib.request.urlopen(value, timeout=30)
|
|
except urllib.error.HTTPError as error:
|
|
return error
|
|
|
|
|
|
def put_immutable(url: str, body: bytes, content_type: str) -> tuple[str, bool]:
|
|
response = http(url, "PUT", body, {"If-None-Match": "*", "Content-Type": content_type,
|
|
"Cache-Control": "public, max-age=31536000, immutable"})
|
|
if response.status == 412:
|
|
current = http(url)
|
|
if current.status != 200 or current.read() != body:
|
|
raise SystemExit(f"immutable object collision: {url}")
|
|
return current.headers.get("ETag", ""), True
|
|
if response.status not in {200, 201}:
|
|
raise SystemExit(f"immutable upload failed ({response.status}): {url}")
|
|
return response.headers.get("ETag", ""), False
|
|
|
|
|
|
def release_number(version: str, channel: str) -> tuple[int, int, int, int]:
|
|
match = re.fullmatch(rf"(\d+)\.(\d+)\.(\d+)-{re.escape(channel)}\.(\d+)", version)
|
|
if match is None:
|
|
raise SystemExit("invalid counted release version")
|
|
return tuple(int(match[index]) for index in range(1, 5))
|
|
|
|
|
|
def validate_lane_transition(current_lanes: dict[str, Any], incoming_lanes: dict[str, Any], channel: str) -> None:
|
|
removed = set(current_lanes) - set(incoming_lanes)
|
|
if removed:
|
|
raise SystemExit(f"channel head would remove lanes: {sorted(removed)}")
|
|
advanced = bool(set(incoming_lanes) - set(current_lanes))
|
|
for lane in sorted(current_lanes):
|
|
old, new = current_lanes[lane]["releaseVersion"], incoming_lanes[lane]["releaseVersion"]
|
|
if release_number(new, channel) < release_number(old, channel):
|
|
raise SystemExit(f"{lane} lane would move backward: {old} -> {new}")
|
|
advanced = advanced or release_number(new, channel) > release_number(old, channel)
|
|
if not advanced:
|
|
raise SystemExit("channel head CAS would not advance or add any lane")
|
|
|
|
|
|
def verified_file(value: dict[str, Any], label: str) -> Path:
|
|
path = Path(str(value.get("file", ""))).resolve()
|
|
body = path.read_bytes()
|
|
if hashlib.sha256(body).hexdigest() != value.get("sha256") or len(body) != value.get("size"):
|
|
raise SystemExit(f"{label} receipt verification failed: {path}")
|
|
return path
|
|
|
|
|
|
def storage(request: dict[str, Any]) -> tuple[str, str]:
|
|
endpoint = str(request.get("endpointUrl", "")).rstrip("/")
|
|
bucket = str(request.get("bucket", "")).strip("/")
|
|
if not re.fullmatch(r"https?://[^\s]+", endpoint) or not bucket or "/" in bucket:
|
|
raise SystemExit("invalid exact release storage endpoint or bucket")
|
|
return endpoint, bucket
|
|
|
|
|
|
def publish(request: dict[str, Any], receipt_path: Path) -> None:
|
|
pack = read_json(Path(str(request.get("packReceipt", ""))).resolve())
|
|
if pack.get("schemaVersion") != 2 or pack.get("operation") != "exact.pack":
|
|
raise SystemExit("invalid exact pack receipt")
|
|
channel, version = str(pack.get("channel", "")), str(pack.get("releaseVersion", ""))
|
|
if not IDENTIFIER.fullmatch(channel):
|
|
raise SystemExit("invalid release channel")
|
|
release_number(version, channel)
|
|
endpoint, bucket = storage(request)
|
|
prefix = f"{endpoint}/{bucket}/{channel}/{version}"
|
|
objects: list[dict[str, Any]] = []
|
|
names: set[str] = set()
|
|
all_replayed = True
|
|
for kind in ("artifacts", "documents"):
|
|
for value in pack[kind]:
|
|
path = verified_file(value, kind[:-1])
|
|
if path.name in names:
|
|
raise SystemExit(f"duplicate exact object name: {path.name}")
|
|
names.add(path.name)
|
|
body = path.read_bytes()
|
|
url = f"{prefix}/{path.name}"
|
|
content_type = value.get("mediaType", "application/octet-stream") if kind == "artifacts" else "application/json; charset=utf-8"
|
|
etag, replayed = put_immutable(url, body, content_type)
|
|
all_replayed = all_replayed and replayed
|
|
if kind == "documents":
|
|
readback = http(url)
|
|
if readback.status != 200 or readback.read() != body:
|
|
raise SystemExit(f"exact document readback failed: {url}")
|
|
objects.append({"kind": kind[:-1], "name": path.name, "url": url, "etag": etag,
|
|
"sha256": value["sha256"], "size": value["size"]})
|
|
public_by_name = {item["name"]: item for item in objects}
|
|
required = []
|
|
for acceptance in pack["requiredAcceptances"]:
|
|
archive_name = Path(acceptance["artifact"]["url"]).name
|
|
metadata_name = Path(acceptance["shellMetadata"]["url"]).name
|
|
archive, metadata = public_by_name.get(archive_name), public_by_name.get(metadata_name)
|
|
if archive is None or metadata is None:
|
|
raise SystemExit("required acceptance is not backed by published objects")
|
|
required.append({**acceptance, "artifact": {**acceptance["artifact"], "url": archive["url"]},
|
|
"shellMetadata": {**acceptance["shellMetadata"], "url": metadata["url"]}})
|
|
head_path = verified_file(next(value for value in pack["documents"] if Path(value["file"]).resolve() == Path(pack["channelHeadFile"]).resolve()), "channel head")
|
|
write_json(receipt_path, {
|
|
"schemaVersion": 1, "operation": "exact.publish", "channel": channel, "releaseVersion": version,
|
|
"sourceCommit": pack["sourceCommit"], "latestChannelHeadUrl": f"{endpoint}/{bucket}/{channel}/latest/channel-head.json",
|
|
"channelHead": {**next(item for item in objects if item["name"] == head_path.name), "file": str(head_path)},
|
|
"objects": objects, "requiredAcceptances": required, "replayed": all_replayed,
|
|
})
|
|
|
|
|
|
def validate_acceptances(published: dict[str, Any], paths: Any) -> list[dict[str, Any]]:
|
|
if not isinstance(paths, list):
|
|
raise SystemExit("exact.activate requires acceptanceCredentials")
|
|
credentials = [read_json(Path(str(path)).resolve()) for path in paths]
|
|
by_key: dict[tuple[str, str], dict[str, Any]] = {}
|
|
for credential in credentials:
|
|
shell = credential.get("shell", {})
|
|
key = (str(shell.get("type", "")), str(credential.get("target", "")))
|
|
if credential.get("schemaVersion") != 1 or credential.get("operation") != "exact.acceptance" or credential.get("status") != "accepted" or key in by_key:
|
|
raise SystemExit(f"invalid or duplicate acceptance credential: {key[0]}/{key[1]}")
|
|
by_key[key] = credential
|
|
required_keys = {(item["shell"]["type"], item["target"]) for item in published["requiredAcceptances"]}
|
|
if set(by_key) != required_keys:
|
|
raise SystemExit(f"acceptance topology mismatch: required={sorted(required_keys)} actual={sorted(by_key)}")
|
|
for expected in published["requiredAcceptances"]:
|
|
credential = by_key[(expected["shell"]["type"], expected["target"])]
|
|
for field in ("channel", "releaseVersion", "sourceCommit"):
|
|
if credential.get(field) != published[field]:
|
|
raise SystemExit(f"acceptance {field} binding mismatch")
|
|
if credential.get("shell") != expected["shell"] or credential.get("artifact") != expected["artifact"] or credential.get("shellMetadata") != expected["shellMetadata"]:
|
|
raise SystemExit("acceptance artifact or Shell binding mismatch")
|
|
installed = credential.get("installed")
|
|
if not isinstance(installed, dict) or installed.get("shell") != expected["shell"] or installed.get("target") != expected["target"]:
|
|
raise SystemExit("acceptance lacks installed Shell proof")
|
|
return credentials
|
|
|
|
|
|
def activate(request: dict[str, Any], receipt_path: Path) -> None:
|
|
published = read_json(Path(str(request.get("publishReceipt", ""))).resolve())
|
|
if published.get("schemaVersion") != 1 or published.get("operation") != "exact.publish":
|
|
raise SystemExit("invalid exact.publish receipt")
|
|
validate_acceptances(published, request.get("acceptanceCredentials"))
|
|
head = published["channelHead"]
|
|
head_path = verified_file(head, "published channel head")
|
|
head_body = head_path.read_bytes()
|
|
incoming_head = json.loads(head_body)["head"]
|
|
channel = published["channel"]
|
|
latest_url = published["latestChannelHeadUrl"]
|
|
current = http(latest_url)
|
|
headers = {"Content-Type": "application/json; charset=utf-8", "Cache-Control": "public, max-age=60"}
|
|
replayed = False
|
|
if current.status == 404:
|
|
headers["If-None-Match"] = "*"
|
|
elif current.status == 200:
|
|
current_body = current.read()
|
|
if current_body == head_body:
|
|
replayed = True
|
|
else:
|
|
current_head = json.loads(current_body)["head"]
|
|
current_lanes, incoming_lanes = current_head.get("lanes", {}), incoming_head.get("lanes", {})
|
|
validate_lane_transition(current_lanes, incoming_lanes, channel)
|
|
etag = current.headers.get("ETag", "")
|
|
if not etag:
|
|
raise SystemExit("latest channel head lacks an ETag for CAS")
|
|
headers["If-Match"] = etag
|
|
else:
|
|
raise SystemExit(f"latest inspection failed ({current.status})")
|
|
if replayed:
|
|
latest_etag = current.headers.get("ETag", "")
|
|
else:
|
|
promoted = http(latest_url, "PUT", head_body, headers)
|
|
if promoted.status not in {200, 201}:
|
|
raise SystemExit(f"latest CAS failed ({promoted.status})")
|
|
latest_etag = promoted.headers.get("ETag", "")
|
|
write_json(receipt_path, {"schemaVersion": 1, "operation": "exact.activate", "channel": channel,
|
|
"releaseVersion": published["releaseVersion"], "sourceCommit": published["sourceCommit"],
|
|
"latestChannelHeadUrl": latest_url, "latestChannelHeadEtag": latest_etag, "replayed": replayed})
|
|
|
|
|
|
def legacy_release(request: dict[str, Any], receipt_path: Path) -> None:
|
|
"""Keep the pre-split local harness working; trusted workflows must not use this operation."""
|
|
pack = read_json(Path(str(request.get("packReceipt", ""))).resolve())
|
|
if pack.get("schemaVersion") != 2 or pack.get("operation") != "exact.pack":
|
|
legacy_release_v1(request, pack, receipt_path)
|
|
return
|
|
scratch = receipt_path.parent / f".{receipt_path.stem}-compat"
|
|
publish_receipt = scratch / "publish.json"
|
|
publish({**request, "operation": "exact.publish"}, publish_receipt)
|
|
published = read_json(publish_receipt)
|
|
credentials: list[str] = []
|
|
for index, required in enumerate(published["requiredAcceptances"]):
|
|
path = scratch / f"acceptance-{index}.json"
|
|
write_json(path, {"schemaVersion": 1, "operation": "exact.acceptance", "status": "accepted",
|
|
"channel": published["channel"], "releaseVersion": published["releaseVersion"], "sourceCommit": published["sourceCommit"],
|
|
"shell": required["shell"], "target": required["target"], "artifact": required["artifact"],
|
|
"shellMetadata": required["shellMetadata"], "installed": {"shell": required["shell"], "target": required["target"]}})
|
|
credentials.append(str(path))
|
|
activation_receipt = scratch / "activation.json"
|
|
activate({"publishReceipt": str(publish_receipt), "acceptanceCredentials": credentials}, activation_receipt)
|
|
result = read_json(activation_receipt)
|
|
result["operation"] = "exact.release"
|
|
result["artifacts"] = [item for item in published["objects"] if item["kind"] == "artifact"]
|
|
result["documents"] = [item for item in published["objects"] if item["kind"] == "document"]
|
|
write_json(receipt_path, result)
|
|
|
|
|
|
def legacy_release_v1(request: dict[str, Any], pack: dict[str, Any], receipt_path: Path) -> None:
|
|
"""Publish the old monolithic receipt without teaching the new protocol about it."""
|
|
channel, version = str(pack.get("channel", "")), str(pack.get("releaseVersion", ""))
|
|
if not IDENTIFIER.fullmatch(channel):
|
|
raise SystemExit("invalid release channel")
|
|
release_number(version, channel)
|
|
endpoint, bucket = storage(request)
|
|
prefix = f"{endpoint}/{bucket}/{channel}"
|
|
uploaded: list[dict[str, Any]] = []
|
|
all_replayed = True
|
|
for kind in ("artifacts", "documents"):
|
|
values = pack.get(kind)
|
|
if not isinstance(values, list):
|
|
raise SystemExit(f"legacy pack receipt lacks {kind}")
|
|
for value in values:
|
|
path = verified_file(value, kind[:-1])
|
|
body = path.read_bytes()
|
|
content_type = "application/json; charset=utf-8" if kind == "documents" else value.get("mediaType", "application/octet-stream")
|
|
url = f"{prefix}/{version}/{path.name}"
|
|
etag, replayed = put_immutable(url, body, content_type)
|
|
all_replayed = all_replayed and replayed
|
|
if kind == "documents":
|
|
readback = http(url)
|
|
if readback.status != 200 or readback.read() != body:
|
|
raise SystemExit(f"exact document readback failed: {url}")
|
|
uploaded.append({"kind": kind[:-1], "url": url, "etag": etag, "sha256": value["sha256"]})
|
|
|
|
head_path = Path(str(pack.get("channelHeadFile", ""))).resolve()
|
|
head_body = head_path.read_bytes()
|
|
latest_url = f"{prefix}/latest/channel-head.json"
|
|
current = http(latest_url)
|
|
headers = {"Content-Type": "application/json; charset=utf-8", "Cache-Control": "public, max-age=60"}
|
|
replayed = False
|
|
if current.status == 404:
|
|
headers["If-None-Match"] = "*"
|
|
elif current.status == 200:
|
|
current_body = current.read()
|
|
if current_body == head_body:
|
|
replayed = True
|
|
else:
|
|
current_head = json.loads(current_body)["head"]
|
|
incoming_head = json.loads(head_body)["head"]
|
|
validate_lane_transition(current_head.get("lanes", {}), incoming_head.get("lanes", {}), channel)
|
|
etag = current.headers.get("ETag", "")
|
|
if not etag:
|
|
raise SystemExit("latest channel head lacks an ETag for CAS")
|
|
headers["If-Match"] = etag
|
|
else:
|
|
raise SystemExit(f"latest inspection failed ({current.status})")
|
|
if replayed:
|
|
latest_etag = current.headers.get("ETag", "")
|
|
else:
|
|
promoted = http(latest_url, "PUT", head_body, headers)
|
|
if promoted.status not in {200, 201}:
|
|
raise SystemExit(f"latest CAS failed ({promoted.status})")
|
|
latest_etag = promoted.headers.get("ETag", "")
|
|
write_json(receipt_path, {
|
|
"schemaVersion": 1, "operation": "exact.release", "channel": channel, "releaseVersion": version,
|
|
"latestChannelHeadUrl": latest_url, "latestChannelHeadEtag": latest_etag,
|
|
"documents": [item for item in uploaded if item["kind"] == "document"],
|
|
"artifacts": [item for item in uploaded if item["kind"] == "artifact"], "replayed": replayed and all_replayed,
|
|
})
|
|
|
|
|
|
def self_check() -> None:
|
|
version = lambda number: {"releaseVersion": f"0.1.0-somechan.{number}"}
|
|
validate_lane_transition({"content": version(1), "terminal": version(1)},
|
|
{"content": version(2), "terminal": version(2), "electron": version(2)}, "somechan")
|
|
rejected = 0
|
|
for current, incoming in (
|
|
({"content": version(2), "terminal": version(2)}, {"content": version(3)}),
|
|
({"content": version(2)}, {"content": version(1)}),
|
|
({"content": version(2)}, {"content": version(2)}),
|
|
):
|
|
try:
|
|
validate_lane_transition(current, incoming, "somechan")
|
|
except SystemExit:
|
|
rejected += 1
|
|
if rejected != 3:
|
|
raise SystemExit("exact release lane self-check failed")
|
|
print("exact release lane transition self-check passed")
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--request", type=Path)
|
|
parser.add_argument("--receipt", type=Path)
|
|
parser.add_argument("--self-check", action="store_true")
|
|
args = parser.parse_args()
|
|
if args.self_check:
|
|
if args.request is not None or args.receipt is not None:
|
|
raise SystemExit("--self-check does not accept request or receipt")
|
|
self_check()
|
|
return
|
|
if args.request is None or args.receipt is None:
|
|
raise SystemExit("--request and --receipt are required")
|
|
request = read_json(args.request.resolve())
|
|
if request.get("schemaVersion") != 1:
|
|
raise SystemExit("unsupported exact release request schema")
|
|
if request.get("operation") == "exact.publish":
|
|
publish(request, args.receipt.resolve())
|
|
elif request.get("operation") == "exact.activate":
|
|
activate(request, args.receipt.resolve())
|
|
elif request.get("operation") == "exact.release":
|
|
legacy_release(request, args.receipt.resolve())
|
|
else:
|
|
raise SystemExit("unsupported exact release operation")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|