feat(observatory): add portable calculation profiles

This commit is contained in:
DCCONSTRUCTIONS
2026-08-31 15:42:56 +03:00
parent d1b75efcea
commit 9beb534108
75 changed files with 24419 additions and 348 deletions
@@ -0,0 +1,588 @@
#!/usr/bin/env python3
"""Build and verify a deterministic blocked M4.9 executor release candidate.
This builder deliberately cannot mark the executor ready. It seals the exact
portable source materializer, generic TRAVEL/TGS runner, result-v2 assembler
and validator into a reproducible candidate archive. A later installation
step must additionally provide an exact compiled runner, an executor image and
an installation receipt before the runtime registry can become ready.
"""
from __future__ import annotations
import argparse
import gzip
import hashlib
import io
import json
import os
import re
import stat
import subprocess
import tarfile
import tempfile
from collections.abc import Sequence
from dataclasses import dataclass
from pathlib import Path, PurePosixPath
from typing import Final, cast
REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
M49_EXECUTOR_RELEASE_CANDIDATE_SCHEMA: Final = (
"missioncore.m49-tgs-portable-executor-release-candidate/v1"
)
M49_COMPILED_RUNNER_BUILD_SCHEMA: Final = "missioncore.m49-tgs-portable-compiled-runner-build/v1"
M49_EXECUTOR_RELEASE_ID: Final = "m49-tgs-portable-executor-v1"
M49_TRAVEL_IMAGE_SHA256: Final = "7b412020f4d8392d1d1ed1b33beadc44140f0ea8f781e62dd69796042334300f"
M49_PROFILE_SHA256: Final = "6128d6af7e6137f9a9473db045e3b155e2105319159f17c32f344b4aedf823a9"
M49_RESULT_CONTRACT_SHA256: Final = (
"9dd80c8e2504559d2156fca933de6eb27901e35305e6853aeb84707e1cb13892"
)
M49_RUNNER_SOURCE_SHA256: Final = "52813392aabd02efc5c2b8f7c22ed88e3ef4cc8ad3aafeba2792efe503e29fe9"
M49_RUNNER_WRAPPER_SHA256: Final = (
"2d6c32560682647f868e4ce4c2605749f17c60482a609f8c03ff951411f48ffb"
)
M49_COMPILER_CONTRACT: Final = {
"compiler": "g++",
"language_standard": "c++17",
"flags": ["-O3", "-DNDEBUG", "-pthread"],
"travel_include": "/opt/travel/src/TRAVEL/cpp/travel/core",
"eigen_include": "/usr/include/eigen3",
}
M49_RELEASE_BLOCKERS: Final = (
"compiled-runner-artifact-missing",
"exact-executor-image-missing",
"worker-installation-receipt-missing",
)
M49_RELEASE_SOURCES: Final = (
Path("config/perception/m49-tgs-portable-v2.json"),
Path("experiments/perception/worker/observatory_portable/Dockerfile.m49-portable-executor"),
Path(
"experiments/perception/worker/observatory_portable/"
"Invoke-M49PortableExecutorCandidateInstall.ps1"
),
Path("experiments/perception/worker/observatory_portable/m49-tgs-portable-runner-source.json"),
Path("experiments/perception/worker/observatory_portable/run_m49_tgs_portable.cpp"),
Path("experiments/perception/worker/observatory_portable/run_m49_tgs_portable.sh"),
Path("experiments/perception/worker/observatory_portable/smoke_m49_tgs_portable.sh"),
Path("experiments/perception/worker/m49_t3_travel/build_tgs_fail_closed_evidence.py"),
Path("experiments/perception/worker/m49_t3_travel/build_tgs_full_shadow_binary.sh"),
Path("experiments/perception/worker/m49_t3_travel/build_tgs_full_shadow_evidence.py"),
Path("src/k1link/compute/lidar_replay.py"),
Path("src/k1link/observatory/m49_portable_executor.py"),
Path("src/k1link/observatory/m49_portable_result.py"),
Path("src/k1link/observatory/m49_portable_source.py"),
Path("src/k1link/observatory/portable_result_contract.py"),
)
_AUTHORITY: Final = {
"commands_enabled": False,
"actuation_allowed": False,
"navigation_or_safety_accepted": False,
"production_accepted": False,
}
_REVISION: Final = re.compile(r"^[a-f0-9]{40}$")
_SHA256: Final = re.compile(r"^[a-f0-9]{64}$")
_HASH_CHUNK_BYTES: Final = 1024 * 1024
class M49ExecutorReleaseBuildError(RuntimeError):
"""The exact portable executor candidate cannot be built or verified."""
@dataclass(frozen=True, slots=True)
class BuiltM49ExecutorReleaseCandidate:
archive: Path
archive_sha256: str
candidate_sha256: str
manifest: dict[str, object]
@dataclass(frozen=True, slots=True)
class BuiltM49CompiledRunnerSeal:
binary: Path
manifest_path: Path
manifest_sha256: str
manifest: dict[str, object]
def seal_m49_compiled_runner_build(
*,
source_root: Path,
source_revision: str,
binary_path: Path,
manifest_path: Path,
) -> BuiltM49CompiledRunnerSeal:
"""Seal, but never execute, a binary built in the exact TRAVEL image."""
if _REVISION.fullmatch(source_revision) is None:
raise M49ExecutorReleaseBuildError("M4.9 compiled-runner revision is invalid")
root = source_root.expanduser().resolve(strict=True)
if root.is_symlink() or not root.is_dir():
raise M49ExecutorReleaseBuildError("M4.9 compiled-runner source root is unsafe")
source = root / "experiments/perception/worker/observatory_portable/run_m49_tgs_portable.cpp"
wrapper = root / "experiments/perception/worker/observatory_portable/run_m49_tgs_portable.sh"
profile = root / "config/perception/m49-tgs-portable-v2.json"
if (
_sha256_file(source) != M49_RUNNER_SOURCE_SHA256
or _sha256_file(wrapper) != M49_RUNNER_WRAPPER_SHA256
or _sha256_file(profile) != M49_PROFILE_SHA256
):
raise M49ExecutorReleaseBuildError(
"M4.9 compiled-runner sources differ from the exact release"
)
binary = binary_path.expanduser().absolute()
try:
metadata = binary.lstat()
resolved_binary = binary.resolve(strict=True)
except OSError as exc:
raise M49ExecutorReleaseBuildError("M4.9 compiled runner is unavailable") from exc
if (
stat.S_ISLNK(metadata.st_mode)
or not stat.S_ISREG(metadata.st_mode)
or not os.path.samefile(binary, resolved_binary)
or not os.access(resolved_binary, os.X_OK)
or not _is_elf(resolved_binary)
):
raise M49ExecutorReleaseBuildError("M4.9 compiled runner is not an executable ELF artifact")
manifest: dict[str, object] = {
"schema_version": M49_COMPILED_RUNNER_BUILD_SCHEMA,
"source_revision": source_revision,
"source_state": "committed-snapshot",
"build_image_sha256": M49_TRAVEL_IMAGE_SHA256,
"profile_sha256": M49_PROFILE_SHA256,
"runner_source_sha256": M49_RUNNER_SOURCE_SHA256,
"runner_wrapper_sha256": M49_RUNNER_WRAPPER_SHA256,
"compiler_contract": dict(M49_COMPILER_CONTRACT),
"binary": {
"file_name": "run_m49_tgs_portable",
"format": "elf",
"byte_length": resolved_binary.stat().st_size,
"sha256": _sha256_file(resolved_binary),
},
"authority": dict(_AUTHORITY),
}
payload = _canonical_json(manifest)
target = manifest_path.expanduser().absolute()
if target.exists():
raise M49ExecutorReleaseBuildError("M4.9 compiled-runner seal already exists")
target.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
if target.parent.is_symlink() or not target.parent.is_dir():
raise M49ExecutorReleaseBuildError("M4.9 compiled-runner seal root is unsafe")
target.write_bytes(payload)
return BuiltM49CompiledRunnerSeal(
binary=resolved_binary,
manifest_path=target,
manifest_sha256=hashlib.sha256(payload).hexdigest(),
manifest=manifest,
)
def git_revision(repository_root: Path = REPOSITORY_ROOT) -> str:
completed = subprocess.run(
["git", "rev-parse", "HEAD"],
cwd=repository_root,
check=False,
capture_output=True,
text=True,
)
revision = completed.stdout.strip()
if completed.returncode != 0 or _REVISION.fullmatch(revision) is None:
raise M49ExecutorReleaseBuildError("M4.9 release revision is unavailable")
return revision
def materialize_revision(
*, revision: str, destination: Path, repository_root: Path = REPOSITORY_ROOT
) -> None:
"""Extract only the explicit release source set from one exact commit."""
if _REVISION.fullmatch(revision) is None or destination.exists():
raise M49ExecutorReleaseBuildError("M4.9 release revision request is invalid")
verified = subprocess.run(
["git", "rev-parse", "--verify", f"{revision}^{{commit}}"],
cwd=repository_root,
check=False,
capture_output=True,
text=True,
)
if verified.returncode != 0 or verified.stdout.strip() != revision:
raise M49ExecutorReleaseBuildError("M4.9 release revision is not a commit")
archive_path = destination.parent / "source.tar"
archived = subprocess.run(
[
"git",
"archive",
"--format=tar",
"--output",
str(archive_path),
revision,
"--",
*(path.as_posix() for path in M49_RELEASE_SOURCES),
],
cwd=repository_root,
check=False,
capture_output=True,
text=True,
)
if archived.returncode != 0:
raise M49ExecutorReleaseBuildError(
"M4.9 release sources are not all present in the selected commit"
)
destination.mkdir()
resolved_root = destination.resolve()
with tarfile.open(archive_path, "r:") as archive:
members = archive.getmembers()
for member in members:
target = (destination / member.name).resolve()
if (
target != resolved_root
and resolved_root not in target.parents
or not (member.isdir() or member.isreg())
):
raise M49ExecutorReleaseBuildError("M4.9 Git archive contains an unsafe member")
for member in members:
target = destination / member.name
if member.isdir():
target.mkdir(parents=True, exist_ok=True)
continue
source = archive.extractfile(member)
if source is None:
raise M49ExecutorReleaseBuildError("M4.9 Git archive member is unreadable")
target.parent.mkdir(parents=True, exist_ok=True)
with source, target.open("wb") as output:
while chunk := source.read(_HASH_CHUNK_BYTES):
output.write(chunk)
def build_m49_executor_release_candidate(
*,
source_root: Path,
output_directory: Path,
source_revision: str,
source_state: str,
) -> BuiltM49ExecutorReleaseCandidate:
"""Build a deterministic candidate; never a ready installation artifact."""
if _REVISION.fullmatch(source_revision) is None:
raise M49ExecutorReleaseBuildError("M4.9 source revision is invalid")
if source_state not in {"committed-snapshot", "uncommitted-candidate"}:
raise M49ExecutorReleaseBuildError("M4.9 source state is invalid")
root = source_root.expanduser().resolve(strict=True)
if root.is_symlink() or not root.is_dir():
raise M49ExecutorReleaseBuildError("M4.9 source root is unsafe")
files = _source_inventory(root)
identity: dict[str, object] = {
"schema_version": M49_EXECUTOR_RELEASE_CANDIDATE_SCHEMA,
"release_id": M49_EXECUTOR_RELEASE_ID,
"state": "blocked",
"source_revision": source_revision,
"source_state": source_state,
"worker_contour_id": "worker-006",
"travel_build_image_sha256": M49_TRAVEL_IMAGE_SHA256,
"executor_image_sha256": None,
"compiled_runner": None,
"profile_sha256": M49_PROFILE_SHA256,
"result_contract_sha256": M49_RESULT_CONTRACT_SHA256,
"source_contract": {
"camera": "exact-admitted-fmp4-members",
"spatial_replay": "exact-admitted-k1mqtt-member",
"host_time_metadata": "separate-exact-admitted-member-required",
"server_paths_or_commands_allowed": False,
},
"phases": [
{"phase_id": "source-materializer", "state": "implemented"},
{"phase_id": "travel-tgs-runner", "state": "implemented"},
{"phase_id": "result-v2-assembler", "state": "implemented"},
{"phase_id": "exact-result-validator", "state": "implemented"},
{"phase_id": "package-sealer", "state": "implemented"},
],
"files": files,
"blockers": list(M49_RELEASE_BLOCKERS),
"authority": dict(_AUTHORITY),
}
candidate_sha256 = hashlib.sha256(_canonical_json(identity)).hexdigest()
manifest: dict[str, object] = {
**identity,
"candidate_sha256": candidate_sha256,
}
output = output_directory.expanduser().absolute()
output.mkdir(parents=True, exist_ok=True)
if output.is_symlink() or not output.is_dir():
raise M49ExecutorReleaseBuildError("M4.9 release output is unsafe")
target = output / f"m49-tgs-portable-executor-{candidate_sha256}.tgz"
if target.exists():
verified = verify_m49_executor_release_candidate(target)
if verified.candidate_sha256 != candidate_sha256:
raise M49ExecutorReleaseBuildError(
"existing M4.9 release candidate has another identity"
)
return verified
with tempfile.TemporaryDirectory(prefix="m49-executor-candidate-") as temporary:
stage = Path(temporary)
payload = stage / "payload"
for source in M49_RELEASE_SOURCES:
destination = payload / source
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes((root / source).read_bytes())
(stage / "release-manifest.json").write_bytes(_canonical_json(manifest))
_write_archive(stage, target)
verified = verify_m49_executor_release_candidate(target)
if verified.candidate_sha256 != candidate_sha256:
raise M49ExecutorReleaseBuildError("built M4.9 release candidate changed identity")
return verified
def verify_m49_executor_release_candidate(
archive_path: Path,
) -> BuiltM49ExecutorReleaseCandidate:
candidate = archive_path.expanduser().resolve(strict=True)
if candidate.is_symlink() or not candidate.is_file():
raise M49ExecutorReleaseBuildError("M4.9 release archive is unsafe")
with tarfile.open(candidate, "r:gz") as archive:
members = archive.getmembers()
names = [member.name for member in members]
payload_names: set[str] = set()
for source in M49_RELEASE_SOURCES:
parts = PurePosixPath("payload", *source.parts)
for parent in reversed(parts.parents):
name = parent.as_posix()
if name not in {".", "payload"}:
payload_names.add(name)
payload_names.add(parts.as_posix())
expected_names = [
"release-manifest.json",
"payload",
*sorted(payload_names),
]
if names != expected_names:
raise M49ExecutorReleaseBuildError("M4.9 release archive member set changed")
by_name = {member.name: member for member in members}
for member in members:
path = PurePosixPath(member.name)
if (
path.is_absolute()
or any(part in {"", ".", ".."} for part in path.parts)
or not (member.isdir() or member.isreg())
or member.uid != 0
or member.gid != 0
or member.mtime != 0
):
raise M49ExecutorReleaseBuildError("M4.9 release archive metadata is unsafe")
manifest_stream = archive.extractfile(by_name["release-manifest.json"])
if manifest_stream is None:
raise M49ExecutorReleaseBuildError("M4.9 release manifest is unavailable")
manifest_payload = manifest_stream.read()
try:
manifest = _object(json.loads(manifest_payload), "M4.9 release manifest")
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise M49ExecutorReleaseBuildError("M4.9 release manifest is invalid JSON") from exc
if manifest_payload != _canonical_json(manifest):
raise M49ExecutorReleaseBuildError("M4.9 release manifest is not canonical JSON")
candidate_sha256 = cast(str, manifest.pop("candidate_sha256", None))
if (
_SHA256.fullmatch(candidate_sha256 or "") is None
or manifest.get("schema_version") != M49_EXECUTOR_RELEASE_CANDIDATE_SCHEMA
or manifest.get("state") != "blocked"
or tuple(cast(list[object], manifest.get("blockers"))) != M49_RELEASE_BLOCKERS
or manifest.get("authority") != _AUTHORITY
or hashlib.sha256(_canonical_json(manifest)).hexdigest() != candidate_sha256
):
raise M49ExecutorReleaseBuildError("M4.9 release candidate identity changed")
files = cast(list[object], manifest.get("files"))
expected_files = {path.as_posix() for path in M49_RELEASE_SOURCES}
if {cast(dict[str, object], row).get("relative_path") for row in files} != expected_files:
raise M49ExecutorReleaseBuildError("M4.9 release file set changed")
for value in files:
row = _object(value, "M4.9 release file")
relative = cast(str, row["relative_path"])
member = by_name[f"payload/{relative}"]
stream = archive.extractfile(member)
if stream is None:
raise M49ExecutorReleaseBuildError("M4.9 release file is unavailable")
payload = stream.read()
if (
row.get("byte_length") != len(payload)
or row.get("sha256") != hashlib.sha256(payload).hexdigest()
):
raise M49ExecutorReleaseBuildError("M4.9 release file changed")
restored_manifest = {**manifest, "candidate_sha256": candidate_sha256}
return BuiltM49ExecutorReleaseCandidate(
archive=candidate,
archive_sha256=_sha256_file(candidate),
candidate_sha256=candidate_sha256,
manifest=restored_manifest,
)
def write_worktree_candidate_manifest(
*, source_root: Path, target: Path, source_revision: str
) -> dict[str, object]:
"""Write a reviewable manifest without pretending it is a Git release."""
files = _source_inventory(source_root.expanduser().resolve(strict=True))
identity: dict[str, object] = {
"schema_version": M49_EXECUTOR_RELEASE_CANDIDATE_SCHEMA,
"release_id": M49_EXECUTOR_RELEASE_ID,
"state": "blocked",
"source_revision": source_revision,
"source_state": "uncommitted-candidate",
"worker_contour_id": "worker-006",
"travel_build_image_sha256": M49_TRAVEL_IMAGE_SHA256,
"executor_image_sha256": None,
"compiled_runner": None,
"profile_sha256": M49_PROFILE_SHA256,
"result_contract_sha256": M49_RESULT_CONTRACT_SHA256,
"source_contract": {
"camera": "exact-admitted-fmp4-members",
"spatial_replay": "exact-admitted-k1mqtt-member",
"host_time_metadata": "separate-exact-admitted-member-required",
"server_paths_or_commands_allowed": False,
},
"phases": [
{"phase_id": "source-materializer", "state": "implemented"},
{"phase_id": "travel-tgs-runner", "state": "implemented"},
{"phase_id": "result-v2-assembler", "state": "implemented"},
{"phase_id": "exact-result-validator", "state": "implemented"},
{"phase_id": "package-sealer", "state": "implemented"},
],
"files": files,
"blockers": [
*M49_RELEASE_BLOCKERS,
"committed-source-snapshot-missing",
],
"authority": dict(_AUTHORITY),
}
manifest: dict[str, object] = {
**identity,
"candidate_sha256": hashlib.sha256(_canonical_json(identity)).hexdigest(),
}
destination = target.expanduser().absolute()
if destination.exists():
raise M49ExecutorReleaseBuildError("worktree candidate manifest already exists")
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(_canonical_json(manifest))
return manifest
def _source_inventory(root: Path) -> list[dict[str, object]]:
rows: list[dict[str, object]] = []
for relative in M49_RELEASE_SOURCES:
path = root / relative
try:
resolved = path.resolve(strict=True)
except OSError as exc:
raise M49ExecutorReleaseBuildError(
f"M4.9 release source is unavailable: {relative}"
) from exc
if path.is_symlink() or not resolved.is_file() or not resolved.is_relative_to(root):
raise M49ExecutorReleaseBuildError(f"M4.9 release source is unsafe: {relative}")
rows.append(
{
"relative_path": relative.as_posix(),
"byte_length": resolved.stat().st_size,
"sha256": _sha256_file(resolved),
}
)
return rows
def _write_archive(stage: Path, target: Path) -> None:
members = [stage / "release-manifest.json", stage / "payload"]
members.extend(sorted((stage / "payload").rglob("*")))
target.parent.mkdir(parents=True, exist_ok=True)
with (
target.open("wb") as raw,
gzip.GzipFile(filename="", mode="wb", fileobj=raw, mtime=0) as compressed,
tarfile.open(fileobj=compressed, mode="w", format=tarfile.PAX_FORMAT) as archive,
):
for path in members:
relative = path.relative_to(stage).as_posix()
info = tarfile.TarInfo(relative)
info.uid = 0
info.gid = 0
info.uname = "root"
info.gname = "root"
info.mtime = 0
if path.is_dir():
info.type = tarfile.DIRTYPE
info.mode = 0o755
archive.addfile(info, io.BytesIO())
else:
info.type = tarfile.REGTYPE
info.mode = 0o755 if path.suffix in {".sh", ".py"} else 0o644
info.size = path.stat().st_size
with path.open("rb") as stream:
archive.addfile(info, stream)
def _canonical_json(value: object) -> bytes:
try:
return json.dumps(
value,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
).encode("utf-8")
except (TypeError, ValueError) as exc:
raise M49ExecutorReleaseBuildError("M4.9 release manifest is not JSON-compatible") from exc
def _sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(_HASH_CHUNK_BYTES), b""):
digest.update(chunk)
return digest.hexdigest()
def _is_elf(path: Path) -> bool:
try:
with path.open("rb") as stream:
return stream.read(4) == b"\x7fELF"
except OSError:
return False
def _object(value: object, label: str) -> dict[str, object]:
if not isinstance(value, dict) or any(not isinstance(key, str) for key in value):
raise M49ExecutorReleaseBuildError(f"{label} must be an object")
return cast(dict[str, object], value)
def _parse_arguments(arguments: Sequence[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--output-directory", type=Path, required=True)
parser.add_argument("--revision")
return parser.parse_args(arguments)
def main(arguments: Sequence[str] | None = None) -> int:
options = _parse_arguments(arguments)
revision = options.revision or git_revision()
with tempfile.TemporaryDirectory(prefix="m49-revision-") as temporary:
snapshot = Path(temporary) / "source"
materialize_revision(revision=revision, destination=snapshot)
built = build_m49_executor_release_candidate(
source_root=snapshot,
output_directory=options.output_directory,
source_revision=revision,
source_state="committed-snapshot",
)
print(
json.dumps(
{
"ok": True,
"state": "blocked",
"artifact": str(built.archive),
"sha256": built.archive_sha256,
"candidate_sha256": built.candidate_sha256,
"blockers": list(M49_RELEASE_BLOCKERS),
},
sort_keys=True,
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env python3
"""Print the immutable Mac launchd plan for the Worker 006 reverse tunnel."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
from k1link.observatory.worker_tunnel_launchd import (
plan_observatory_worker_tunnel_launch_agent,
)
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--data-directory", type=Path, required=True)
parser.add_argument(
"--agent-path",
type=Path,
default=(
Path.home()
/ "Library/LaunchAgents/com.nodedc.observatory-worker-tunnel.local.plist"
),
)
parser.add_argument("--ssh-path", type=Path, default=Path("/usr/bin/ssh"))
arguments = parser.parse_args()
plan = plan_observatory_worker_tunnel_launch_agent(
data_directory=arguments.data_directory,
agent_path=arguments.agent_path,
ssh_path=arguments.ssh_path,
)
print(json.dumps(plan.to_dict(), indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())