feat(perception): add scoped stream control and bounded clock observations

This commit is contained in:
DCCONSTRUCTIONS
2026-09-02 19:41:43 +03:00
parent 0cc6b96306
commit d7b8989e43
6 changed files with 1160 additions and 2 deletions
@@ -0,0 +1,312 @@
"""CPU-only clock/grant route evidence; NOT a model/freshness qualification.
One bootstrap ticket/certificate copied via authenticated SSH, subsequent data
grants delivered only by TLS Poll. Source events/resume proof remain synthetic;
real monotonic clock observations use explicit CONDITIONAL error/rate budgets.
"""
import argparse
import asyncio
import json
import os
import resource
import secrets
import subprocess
import sys
import threading
import time
from dataclasses import asdict
from datetime import UTC, datetime
from hashlib import sha256
from pathlib import Path
import grpc
from grpc_transport_probe import document, identity, until
from k1link.compute.live_perception import LiveIngressEvent
from k1link.perception.realtime_contract import StreamStart
from k1link.perception.streaming_clock import ClockMappingError, ClockWindow
from k1link.perception.streaming_continuity import ResumeEvidence
from k1link.perception.streaming_control_grpc import (
ControlTicket,
StreamControlClient,
StreamControlEndpoint,
)
from k1link.perception.streaming_grpc import GrpcStreamClient, GrpcStreamEndpoint
from k1link.perception.streaming_lifecycle import StreamingLifecycle
from k1link.perception.streaming_queue import StreamMailbox
async def server(root):
private = root / "private"
private.mkdir(mode=0o700, exist_ok=True)
cert, key, bootstrap = [private / x for x in ("cert.pem", "key.pem", "bootstrap.json")]
subprocess.run(
[
"openssl",
"req",
"-x509",
"-newkey",
"rsa:2048",
"-nodes",
"-days",
"1",
"-subj",
"/CN=localhost",
"-keyout",
str(key),
"-out",
str(cert),
],
check=True,
capture_output=True,
timeout=10,
)
run = StreamingLifecycle(
identity(),
root / "lease",
StreamMailbox(),
threading.Event(),
recover_input=True,
source_clock_ns=lambda: 1_000_000_000,
)
resident = run.spawn(
lambda: subprocess.Popen(
[sys.executable, "-c", "import time; time.sleep(180)"],
start_new_session=True,
)
)
run.ready()
pulse_stop = threading.Event()
def pulse():
while not pulse_stop.wait(0.1):
run.renew(identity())
pulse_thread = threading.Thread(target=pulse, daemon=True)
pulse_thread.start()
received = []
def consume(event):
item = {
"sequence": event.ingress_sequence,
"sha256": sha256(event.payload).hexdigest(),
"bytes": len(event.payload),
"resident_pid": resident.pid,
}
received.append(item)
if len(received) > 8:
raise ValueError("bounded count exceeded")
endpoint.publish(
run.continuity.epoch, event.ingress_sequence, json.dumps(item, sort_keys=True).encode()
)
endpoint = GrpcStreamEndpoint(run, consume, lambda _: None)
pending = [endpoint.issue(run.continuity.epoch, "synthetic-capture", 1)]
ticket = ControlTicket(identity(), secrets.token_hex(32))
clock_id = "worker-process-" + secrets.token_hex(12)
control = StreamControlEndpoint(
ticket,
lambda: pending[0] if endpoint.grant is not None else None,
clock_id=clock_id,
)
report = {
"utc": datetime.now(UTC).isoformat(),
"started_monotonic_ns": str(time.monotonic_ns()),
"model_count": 0,
"synthetic_source_and_resume": True,
"real_time_qualified": False,
"actuation_allowed": False,
"received": received,
"clock_id": clock_id,
"grpc_version": grpc.__version__,
}
rpc = None
try:
rpc, _ = await endpoint.serve(
"0.0.0.0:50061",
certificate=cert.read_bytes(),
private_key=key.read_bytes(),
control_handlers=(control.handler(),),
)
document(
bootstrap,
{
"activation": identity().to_dict(),
"token": ticket.token,
"remote_clock_id": clock_id,
},
)
bootstrap.chmod(0o600)
await until(lambda: len(received) == 4 and endpoint.active is None, seconds=90)
report["first_transport"] = endpoint.last
report["before_gap"] = run.snapshot()
began = time.monotonic_ns()
await asyncio.sleep(2.2)
report["gap_ns"] = str(time.monotonic_ns() - began)
assert resident.poll() is None and run.continuity.phase == "waiting"
report["after_gap"] = run.snapshot()
epoch = run.begin_input(identity())
run.resume_input(epoch, ResumeEvidence(*([1_000_000_000] * 4), True), lambda: None)
pending[0] = endpoint.issue(epoch, "synthetic-capture", 1)
await until(lambda: len(received) == 8 and run.mailbox.done, seconds=30)
endpoint.finish_results(epoch)
await until(lambda: endpoint.active is None)
report["second_transport"] = endpoint.last
report["passed"] = resident.poll() is None
report["peak_mailbox_bytes"] = run.mailbox.peak_bytes
finally:
if rpc:
await rpc.stop(0)
pulse_stop.set()
pulse_thread.join(1)
report["closed"] = run.close()
report["resident_reaped"] = resident.poll() is not None
report["final_mailbox_bytes"] = run.mailbox.bytes
report["control_accepted"] = control.accepted
report["control_rejected"] = control.rejected
report["rss_max_kib"] = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
report["finished_monotonic_ns"] = str(time.monotonic_ns())
document(root / "server-report.json", report)
for path in (key, bootstrap):
path.unlink(missing_ok=True)
async def client(root, target):
bootstrap = root / "bootstrap.json"
value = json.loads(bootstrap.read_text())
ticket = ControlTicket(StreamStart.from_dict(value["activation"]), value["token"])
local_clock_id = "mac-process-" + secrets.token_hex(12)
control = StreamControlClient(
target, (root / "cert.pem").read_bytes(), ticket, clock_id=local_clock_id
)
mapping = ClockWindow(
local_clock_id,
value["remote_clock_id"],
rate_ppm=500,
timestamp_error_ns=50_000,
maximum_age_ns=2_000_000_000,
)
rows, grants, replies, errors = [], [], [], []
report = {
"utc": datetime.now(UTC).isoformat(),
"started_monotonic_ns": str(time.monotonic_ns()),
"schema_version": "missioncore.grpc-control-clock-probe/v1",
"observations": rows,
"grants": grants,
"replies": replies,
"errors": errors,
"model_count": 0,
"synthetic_source_and_resume": True,
"real_time_qualified": False,
"one_way_frame_age_measured": False,
"actuation_allowed": False,
"conditional_relative_rate_ppm": 500,
"timestamp_error_budget_ns": "50000",
"maximum_mapping_age_ns": "2000000000",
"admission_uncertainty_ns": "5000000",
"path": "TLS gRPC over existing Mac-Worker authenticated SSH/Tailscale route",
}
async def poll(phase):
for _ in range(4):
try:
probe, access = await control.poll()
break
except grpc.aio.AioRpcError as exc:
errors.append({"phase": phase, "code": exc.code().name})
await asyncio.sleep(0.1)
else:
raise RuntimeError("bounded control polling failed")
bounds = mapping.add(probe)
now = time.monotonic_ns()
uncertainty = bounds.uncertainty_ns(now)
raw = {k: str(v) if type(v) is int else v for k, v in asdict(probe).items()}
rows.append(
{
"phase": phase,
"probe": raw,
"bounds": bounds.to_dict(),
"evaluated_at_ns": str(now),
"uncertainty_ns": str(uncertainty),
"admitted_5ms": uncertainty <= 5_000_000,
}
)
return access
try:
previous = None
for phase in (1, 2):
if phase == 2:
await asyncio.sleep(2.3)
try:
mapping.current(time.monotonic_ns())
except ClockMappingError:
report["mapping_expired_during_gap"] = True
else:
raise AssertionError("old clock mapping survived expiry")
access = None
for _ in range(32):
candidate = await poll(phase)
if candidate is not None:
access = candidate
await asyncio.sleep(0.05)
assert access is not None and (previous is None or access.epoch != previous.epoch)
assert previous is None or access.token != previous.token
grants.append(
{
"phase": phase,
"epoch": access.epoch.to_dict(),
"token_changed": previous is not None,
"delivery": "authenticated-control-poll",
}
)
stream = GrpcStreamClient(target, (root / "cert.pem").read_bytes(), access)
try:
await stream.open()
for sequence in range((phase - 1) * 4 + 1, phase * 4 + 1):
payload = bytes([sequence]) * 32768
event = LiveIngressEvent(
sequence,
"synthetic-capture",
1,
"lidar",
"lidar",
sequence,
1_799_999_999_123_456_789,
1_000_000_000,
payload,
)
started = time.monotonic_ns()
await stream.send(event)
result = await stream.receive()
elapsed = time.monotonic_ns() - started
returned = json.loads(result[1])
assert (
result[0] == sequence and returned["sha256"] == sha256(payload).hexdigest()
)
replies.append({**returned, "round_trip_ns": str(elapsed)})
assert await poll(phase) is None # Control still works during Exchange.
await asyncio.sleep(0.05)
if phase == 2:
await stream.end()
assert await stream.receive() is None
finally:
await stream.close()
previous = access
report["passed"] = True
finally:
await control.close()
report["finished_monotonic_ns"] = str(time.monotonic_ns())
document(root / "client-report.json", report)
bootstrap.unlink(missing_ok=True)
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("mode", choices=("server", "client"))
parser.add_argument("root", type=Path)
parser.add_argument("--target", default="localhost:18561")
args = parser.parse_args()
os.umask(0o077)
asyncio.run(server(args.root) if args.mode == "server" else client(args.root, args.target))