TOMK / src /python /tomagi /materialize.py
c0mbatduckzz's picture
Publish WQK 0.6 formal specification, use cases and verified release (part 2)
767a051 verified
Raw History Blame Contribute Delete
5.01 kB
"""Generic byte materialization from ordered TOMAGI EMIT execution records."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Mapping, Sequence
from .core import (
FLAG_EMIT_BIG_ENDIAN,
FLAG_EMIT_COUNT_MASK,
FLAG_EMIT_COUNT_SHIFT,
Opcode,
Program,
State,
PROGRAM_FLAG_EMIT_BYTES,
PROGRAM_FLAG_SEEDED_PROFILE,
run,
u32,
)
from .format import load
TRACE_FIELDS = (
"step", "cell_before", "opcode", "branch", "cell_after", "key_hi", "key_lo",
"rho", "theta", "tick", "phi", "orientation", "sheet", "residual", "output",
"lineage", "status",
)
@dataclass(frozen=True, slots=True)
class EmitRecord:
sequence: int
step: int
cell_index: int
flags: int
payload: int
byte_count: int
byte_order: str
data: bytes
lineage: int
def as_record(self) -> dict[str, Any]:
return {
"sequence": self.sequence,
"step": self.step,
"cell_index": self.cell_index,
"flags": self.flags,
"payload": self.payload,
"byte_count": self.byte_count,
"byte_order": self.byte_order,
"hex": self.data.hex(),
"lineage": self.lineage,
}
def decode_emit_payload(flags: int, payload: int) -> tuple[bytes, int, str]:
flags = u32(flags)
payload = u32(payload)
count = (flags & FLAG_EMIT_COUNT_MASK) >> FLAG_EMIT_COUNT_SHIFT
if not 1 <= count <= 4:
raise ValueError(f"EMIT byte count must be in 1..4, found {count}")
if flags & FLAG_EMIT_BIG_ENDIAN:
return payload.to_bytes(4, "big")[-count:], count, "big"
return payload.to_bytes(4, "little")[:count], count, "little"
def _validate_trace(
program: Program,
trace: Sequence[Mapping[str, Any]],
) -> list[Mapping[str, Any]]:
"""Authenticate a canonical-initial-state trace prefix by deterministic replay."""
rows = list(trace)
_, expected = run(program, ticks=len(rows), trace=True)
if len(expected) != len(rows):
raise ValueError("trace continues after the program halted")
for index, (row, reference) in enumerate(zip(rows, expected)):
if not isinstance(row, Mapping):
raise ValueError(f"trace row {index} must be an object")
unknown = sorted(
(key for key in row if key not in TRACE_FIELDS), key=repr
)
if unknown:
raise ValueError(
f"trace row {index} has unknown fields: "
+ ", ".join(repr(key) for key in unknown)
)
for field in TRACE_FIELDS:
if field not in row:
raise ValueError(f"trace row {index} is missing field {field}")
value = row[field]
if isinstance(value, bool) or not isinstance(value, int):
raise ValueError(f"trace row {index} field {field} must be an integer")
if value != reference[field]:
raise ValueError(
f"trace row {index} field {field} does not match deterministic replay"
)
return rows
def materialize_trace(
program: Program,
trace: Sequence[Mapping[str, Any]],
) -> tuple[bytes, list[EmitRecord]]:
if not (program.flags & PROGRAM_FLAG_SEEDED_PROFILE):
raise ValueError("byte materialization requires a seeded-profile program")
if not (program.flags & PROGRAM_FLAG_EMIT_BYTES):
raise ValueError("program does not declare emitted-byte materialization")
validated_trace = _validate_trace(program, trace)
output = bytearray()
records: list[EmitRecord] = []
for row in validated_trace:
index = int(row["cell_before"])
if not 0 <= index < len(program.cells):
raise ValueError(f"trace cell index outside program: {index}")
cell = program.cells[index]
if cell.opcode != int(Opcode.EMIT):
continue
data, count, byte_order = decode_emit_payload(cell.flags, cell.payload)
records.append(EmitRecord(
sequence=len(records),
step=int(row["step"]),
cell_index=index,
flags=cell.flags,
payload=cell.payload,
byte_count=count,
byte_order=byte_order,
data=data,
lineage=int(row.get("lineage", 0)),
))
output.extend(data)
if not records:
raise ValueError("execution trace contains no EMIT records")
return bytes(output), records
def materialize_file(
program_path: str | Path,
destination: str | Path,
*,
ticks: int | None = None,
) -> tuple[bytes, State, list[dict[str, int]], list[EmitRecord]]:
program = load(program_path)
state, trace = run(program, ticks=ticks, trace=True)
data, records = materialize_trace(program, trace)
out = Path(destination)
out.parent.mkdir(parents=True, exist_ok=True)
out.write_bytes(data)
return data, state, trace, records