tera-spatial: an NDJSON replay bridge to the TypeScript spatial environments

Tera's four (now five) spatial environments already implement a Gym-style
contract with checksums, train/dev splits and a replay gate — in TypeScript,
unreachable from `uv run eval`. This bridges them rather than porting them: a
resident NDJSON worker over stdio drives the vendored TS closure, and no reward
arithmetic exists in Python anywhere in the package, including the denominator.

Correctness is replay, not assertion: every scenario x seed must round-trip
through Python and replay to an identical FNV-1a-64 checksum. 32/32 do, and 52
tamper attempts are rejected, 24 of them re-sealed with Tera's own checksum so
it is replay() catching divergence rather than the seal.

Lives in arena rather than tera because tera has no Python toolchain. That
overturns the earlier plan's claim that this workstream shares no files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-21 15:55:12 -07:00
co-authored by Claude Opus 5
parent 00d21025ff
commit 162d67a83c
33 changed files with 9030 additions and 0 deletions
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
"""Vendor the Tera arena TypeScript closure into this package.
Tera is a TypeScript repository with no Python toolchain, and this package is a
Python wheel. The bridge's rule is that a number the model is graded on is
computed *once*, in TypeScript, and only ever transported into Python — so the
TypeScript has to travel with the wheel rather than be resolved at runtime from
a checkout that may not exist on the machine doing the eval.
What travels is the transitive import closure of `src/arena/index.ts` and
nothing else: 23 files, no bare specifiers, no Three.js, no DOM. That closure is
walked here rather than declared, so a new import in `tera` is picked up the
next time somebody runs this instead of silently going missing.
uv run python scripts/sync_tera.py --tera ~/repos/gitea/tera
Writes `tera_spatial/vendor/tera/<path>` for every file in the closure and
regenerates `tera_spatial/hashes.py`. Both are committed. `hashes.py` is what
`test_replay.py` checks the vendored tree against, so an edit to a vendored
file that does not come back through this script fails the gate.
"""
from __future__ import annotations
import argparse
import hashlib
import shutil
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from tera_spatial.closure import ENTRY, walk # noqa: E402
def sha256(path: Path) -> str:
return "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest()
def main(argv: list[str] | None = None) -> int:
package = Path(__file__).resolve().parent.parent
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--tera", type=Path, default=Path.home() / "repos/gitea/tera")
parser.add_argument("--check", action="store_true", help="verify only; write nothing")
args = parser.parse_args(argv)
root = args.tera.expanduser().resolve()
if not (root / ENTRY).is_file():
print(f"not a tera checkout: {root}", file=sys.stderr)
return 2
files, bare = walk(root)
if bare:
# A bare specifier means the closure needs `node_modules`, and the wheel
# would ship a bridge that only runs next to a `npm install`.
print("closure is not self-contained:", file=sys.stderr)
for entry in bare:
print(f" {entry}", file=sys.stderr)
return 1
vendor = package / "tera_spatial" / "vendor" / "tera"
if args.check:
stale = [rel for rel in files if not (vendor / rel).is_file()]
if stale:
print("missing from vendor:", *stale, sep="\n ", file=sys.stderr)
return 1
else:
if vendor.exists():
shutil.rmtree(vendor)
for rel in files:
destination = vendor / rel
destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(root / rel, destination)
digests = {rel: sha256(vendor / rel) for rel in files}
total = sum((vendor / rel).stat().st_size for rel in files)
aggregate = hashlib.sha256()
for rel in files:
aggregate.update(rel.encode())
aggregate.update(b"\0")
aggregate.update((vendor / rel).read_bytes())
aggregate.update(b"\0")
body = _render(digests, total, "sha256:" + aggregate.hexdigest())
target = package / "tera_spatial" / "hashes.py"
if args.check:
if target.read_text(encoding="utf-8") != body:
print("hashes.py is stale; re-run scripts/sync_tera.py", file=sys.stderr)
return 1
print(f"vendored closure ok: {len(files)} files, {total} bytes")
return 0
target.write_text(body, encoding="utf-8")
print(f"vendored {len(files)} files ({total} bytes) from {root}")
return 0
def _render(digests: dict[str, str], total: int, aggregate: str) -> str:
lines = [
'"""SHA-256 of every vendored Tera source file. Generated — do not edit.',
"",
"Regenerate with `scripts/sync_tera.py`. `verify()` is called by the replay",
"gate: the checksums a trace carries are only worth something if the code that",
"produced them is the code on disk.",
'"""',
"",
"from __future__ import annotations",
"",
"import hashlib",
"from pathlib import Path",
"",
f"CLOSURE_ENTRY = {ENTRY!r}",
f"CLOSURE_BYTES = {total}",
f"CLOSURE_SHA256 = {aggregate!r}",
"",
"VENDORED_FILES: dict[str, str] = {",
]
lines += [f" {rel!r}: {digest!r}," for rel, digest in digests.items()]
lines += [
"}",
"",
"VENDOR_ROOT = Path(__file__).resolve().parent / \"vendor\" / \"tera\"",
"",
"",
"def verify() -> list[str]:",
' """Return a list of complaints about the vendored tree. Empty means clean."""',
" problems: list[str] = []",
" for relative, expected in VENDORED_FILES.items():",
" path = VENDOR_ROOT / relative",
" if not path.is_file():",
" problems.append(f\"missing: {relative}\")",
" continue",
' actual = "sha256:" + hashlib.sha256(path.read_bytes()).hexdigest()',
" if actual != expected:",
' problems.append(f"modified: {relative} ({actual} != {expected})")',
" for path in sorted(VENDOR_ROOT.rglob(\"*\")):",
" if path.is_file():",
" relative = path.relative_to(VENDOR_ROOT).as_posix()",
" if relative not in VENDORED_FILES:",
' problems.append(f"unrecorded: {relative}")',
" return problems",
"",
]
return "\n".join(lines)
if __name__ == "__main__":
raise SystemExit(main())